From 666ab706a66f7c39c8bb758c0abc2c08c15d4967 Mon Sep 17 00:00:00 2001 From: Dinesht04 Date: Thu, 13 Nov 2025 02:22:58 +0530 Subject: [PATCH 01/92] feat(ui): add min values for inputs and context-based keyboards for inputs --- ui/src/components/SchemaForm/components/Input.tsx | 15 +++++++++++++++ ui/src/components/SchemaForm/index.tsx | 3 +++ ui/src/components/SchemaForm/types.ts | 10 ++++++++++ ui/src/pages/Admin/Privileges/index.tsx | 2 ++ ui/src/pages/Admin/Write/index.tsx | 10 ++++++++++ 5 files changed, 40 insertions(+) diff --git a/ui/src/components/SchemaForm/components/Input.tsx b/ui/src/components/SchemaForm/components/Input.tsx index 1a3fe319b..c0fd084ca 100644 --- a/ui/src/components/SchemaForm/components/Input.tsx +++ b/ui/src/components/SchemaForm/components/Input.tsx @@ -29,6 +29,17 @@ interface Props { onChange?: (fd: Type.FormDataType) => void; formData: Type.FormDataType; readOnly: boolean; + minValue?: number; + inputMode?: + | 'text' + | 'search' + | 'none' + | 'tel' + | 'url' + | 'email' + | 'numeric' + | 'decimal' + | undefined; } const Index: FC = ({ type = 'text', @@ -37,6 +48,8 @@ const Index: FC = ({ onChange, formData, readOnly = false, + minValue = 0, + inputMode = 'text', }) => { const fieldObject = formData[fieldName]; const handleChange = (evt: React.ChangeEvent) => { @@ -60,6 +73,8 @@ const Index: FC = ({ placeholder={placeholder} type={type} value={fieldObject?.value || ''} + min={minValue} + inputMode={inputMode} onChange={handleChange} disabled={readOnly} isInvalid={fieldObject?.isInvalid} diff --git a/ui/src/components/SchemaForm/index.tsx b/ui/src/components/SchemaForm/index.tsx index 421e0b1e1..23b193b48 100644 --- a/ui/src/components/SchemaForm/index.tsx +++ b/ui/src/components/SchemaForm/index.tsx @@ -368,6 +368,9 @@ const SchemaForm: ForwardRefRenderFunction = ( {widget === 'input' ? ( { } return true; }, + inputType: 'number', + inputMode: 'numeric', }, }; }); diff --git a/ui/src/pages/Admin/Write/index.tsx b/ui/src/pages/Admin/Write/index.tsx index 86d44d6d9..fee2d28cc 100644 --- a/ui/src/pages/Admin/Write/index.tsx +++ b/ui/src/pages/Admin/Write/index.tsx @@ -261,6 +261,8 @@ const Index: FC = () => { {t('min_tags.label')} { @@ -302,6 +304,8 @@ const Index: FC = () => { {t('min_content.label')} { @@ -344,6 +348,8 @@ const Index: FC = () => { {t('image_size.label')} { @@ -366,6 +372,8 @@ const Index: FC = () => { {t('attachment_size.label')} { @@ -388,6 +396,8 @@ const Index: FC = () => { {t('image_megapixels.label')} { From 157dbfd08a1474534fe3548ef02243bf421ba020 Mon Sep 17 00:00:00 2001 From: Dinesht04 Date: Fri, 14 Nov 2025 02:28:46 +0530 Subject: [PATCH 02/92] feat(ui): add types, logic and defaults for min, max value of input component of form --- ui/src/components/SchemaForm/components/Input.tsx | 9 ++++++--- ui/src/components/SchemaForm/index.tsx | 9 +++++++++ ui/src/components/SchemaForm/types.ts | 2 ++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ui/src/components/SchemaForm/components/Input.tsx b/ui/src/components/SchemaForm/components/Input.tsx index c0fd084ca..3a2c0397d 100644 --- a/ui/src/components/SchemaForm/components/Input.tsx +++ b/ui/src/components/SchemaForm/components/Input.tsx @@ -29,7 +29,8 @@ interface Props { onChange?: (fd: Type.FormDataType) => void; formData: Type.FormDataType; readOnly: boolean; - minValue?: number; + min?: number; + max?: number; inputMode?: | 'text' | 'search' @@ -48,7 +49,8 @@ const Index: FC = ({ onChange, formData, readOnly = false, - minValue = 0, + min = 0, + max = 65355, inputMode = 'text', }) => { const fieldObject = formData[fieldName]; @@ -73,7 +75,8 @@ const Index: FC = ({ placeholder={placeholder} type={type} value={fieldObject?.value || ''} - min={minValue} + min={min} + max={max} inputMode={inputMode} onChange={handleChange} disabled={readOnly} diff --git a/ui/src/components/SchemaForm/index.tsx b/ui/src/components/SchemaForm/index.tsx index 23b193b48..5bde2fdc8 100644 --- a/ui/src/components/SchemaForm/index.tsx +++ b/ui/src/components/SchemaForm/index.tsx @@ -260,6 +260,8 @@ const SchemaForm: ForwardRefRenderFunction = ( enum: enumValues = [], enumNames = [], max_length = 0, + max = 65355, + min = 0, } = properties[key]; const { 'ui:widget': widget = 'input', 'ui:options': uiOpt } = uiSchema?.[key] || {}; @@ -374,6 +376,8 @@ const SchemaForm: ForwardRefRenderFunction = ( placeholder={ uiOpt && 'placeholder' in uiOpt ? uiOpt.placeholder : '' } + min={min} + max={max} fieldName={key} onChange={onChange} formData={formData} @@ -408,9 +412,14 @@ const SchemaForm: ForwardRefRenderFunction = ( type={ uiOpt && 'inputType' in uiOpt ? uiOpt.inputType : 'text' } + inputMode={ + uiOpt && 'inputMode' in uiOpt ? uiOpt.inputMode : 'text' + } placeholder={ uiOpt && 'placeholder' in uiOpt ? uiOpt.placeholder : '' } + min={min} + max={max} fieldName={key} onChange={onChange} formData={formData} diff --git a/ui/src/components/SchemaForm/types.ts b/ui/src/components/SchemaForm/types.ts index eaedf902a..55cf8e99d 100644 --- a/ui/src/components/SchemaForm/types.ts +++ b/ui/src/components/SchemaForm/types.ts @@ -49,6 +49,8 @@ export interface JSONSchema { description?: string; enum?: Array; enumNames?: string[]; + min?: number; + max?: number; default?: string | boolean | number | any[]; max_length?: number; }; From 54e602c5e6ad9a8c49187eadc4d480fbd7892a97 Mon Sep 17 00:00:00 2001 From: Dinesht04 Date: Wed, 19 Nov 2025 15:28:58 +0530 Subject: [PATCH 03/92] fix(ui): refactor number input props (min,max) --- ui/src/components/SchemaForm/components/Input.tsx | 9 ++++++--- ui/src/components/SchemaForm/index.tsx | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ui/src/components/SchemaForm/components/Input.tsx b/ui/src/components/SchemaForm/components/Input.tsx index 3a2c0397d..d84d7d55a 100644 --- a/ui/src/components/SchemaForm/components/Input.tsx +++ b/ui/src/components/SchemaForm/components/Input.tsx @@ -50,10 +50,14 @@ const Index: FC = ({ formData, readOnly = false, min = 0, - max = 65355, + max, inputMode = 'text', }) => { const fieldObject = formData[fieldName]; + const numberInputProps = + type === 'number' + ? { min, ...(max != null && max > 0 ? { max } : {}) } + : {}; const handleChange = (evt: React.ChangeEvent) => { const { name, value } = evt.currentTarget; const state = { @@ -75,8 +79,7 @@ const Index: FC = ({ placeholder={placeholder} type={type} value={fieldObject?.value || ''} - min={min} - max={max} + {...numberInputProps} inputMode={inputMode} onChange={handleChange} disabled={readOnly} diff --git a/ui/src/components/SchemaForm/index.tsx b/ui/src/components/SchemaForm/index.tsx index 5bde2fdc8..171b5f675 100644 --- a/ui/src/components/SchemaForm/index.tsx +++ b/ui/src/components/SchemaForm/index.tsx @@ -260,7 +260,7 @@ const SchemaForm: ForwardRefRenderFunction = ( enum: enumValues = [], enumNames = [], max_length = 0, - max = 65355, + max, min = 0, } = properties[key]; const { 'ui:widget': widget = 'input', 'ui:options': uiOpt } = From 9a7eb0f450d31042c8badf080354754a8704e429 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Thu, 20 Nov 2025 17:42:35 +0800 Subject: [PATCH 04/92] fix(service): set default language to "en_US" if invalid language is provided --- internal/service/siteinfo/siteinfo_service.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index a0f4891c4..92b3e0c71 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -40,7 +40,6 @@ import ( tagcommon "github.com/apache/answer/internal/service/tag_common" "github.com/apache/answer/plugin" "github.com/jinzhu/copier" - "github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/log" ) @@ -159,10 +158,9 @@ func (s *SiteInfoService) SaveSiteGeneral(ctx context.Context, req schema.SiteGe } func (s *SiteInfoService) SaveSiteInterface(ctx context.Context, req schema.SiteInterfaceReq) (err error) { - // check language + // If the language is invalid, set it to the default language "en_US" if !translator.CheckLanguageIsValid(req.Language) { - err = errors.BadRequest(reason.LangNotFound) - return + req.Language = "en_US" } content, _ := json.Marshal(req) From 09b6b34b0540b1aa6f344b20df8507f56e6fb406 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Thu, 20 Nov 2025 17:50:57 +0800 Subject: [PATCH 05/92] fix(comment): decode CommentID using DeShortID for consistency --- internal/controller/comment_controller.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/controller/comment_controller.go b/internal/controller/comment_controller.go index 5b807d935..65fbedf04 100644 --- a/internal/controller/comment_controller.go +++ b/internal/controller/comment_controller.go @@ -246,6 +246,7 @@ func (cc *CommentController) GetCommentWithPage(ctx *gin.Context) { return } req.ObjectID = uid.DeShortID(req.ObjectID) + req.CommentID = uid.DeShortID(req.CommentID) req.UserID = middleware.GetLoginUserIDFromContext(ctx) canList, err := cc.rankService.CheckOperationPermissions(ctx, req.UserID, []string{ permission.CommentEdit, From a15dd41550c282a4de44259c69a57dd52eeb0e9c Mon Sep 17 00:00:00 2001 From: ferhat elmas Date: Sat, 22 Nov 2025 12:43:55 +0100 Subject: [PATCH 06/92] refactor(internal): compile regex once while clearing text Regex and Replacer can be reused. No need to recreate for each invocation. Signed-off-by: ferhat elmas --- pkg/htmltext/htmltext.go | 48 ++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/pkg/htmltext/htmltext.go b/pkg/htmltext/htmltext.go index 49049109d..0b84cda49 100644 --- a/pkg/htmltext/htmltext.go +++ b/pkg/htmltext/htmltext.go @@ -34,38 +34,34 @@ import ( "github.com/mozillazg/go-pinyin" ) +var ( + reCode = regexp.MustCompile(`(?ism)<(pre)>.*<\/pre>`) + reCodeReplace = "{code...}" + reLink = regexp.MustCompile(`(?ism)(.*)?<\/a>`) + reLinkReplace = " [$1] " + reSpace = regexp.MustCompile(` +`) + reSpaceReplace = " " + + spaceReplacer = strings.NewReplacer( + "\n", " ", + "\r", " ", + "\t", " ", + ) +) + // ClearText clear HTML, get the clear text -func ClearText(html string) (text string) { - if len(html) == 0 { - text = html - return +func ClearText(html string) string { + if html == "" { + return html } - var ( - re *regexp.Regexp - codeReg = `(?ism)<(pre)>.*<\/pre>` - codeRepl = "{code...}" - linkReg = `(?ism)(.*)?<\/a>` - linkRepl = " [$1] " - spaceReg = ` +` - spaceRepl = " " - ) - re = regexp.MustCompile(codeReg) - html = re.ReplaceAllString(html, codeRepl) + html = reCode.ReplaceAllString(html, reCodeReplace) + html = reLink.ReplaceAllString(html, reLinkReplace) - re = regexp.MustCompile(linkReg) - html = re.ReplaceAllString(html, linkRepl) - - text = strings.NewReplacer( - "\n", " ", - "\r", " ", - "\t", " ", - ).Replace(strip.StripTags(html)) + text := spaceReplacer.Replace(strip.StripTags(html)) // replace multiple spaces to one space - re = regexp.MustCompile(spaceReg) - text = strings.TrimSpace(re.ReplaceAllString(text, spaceRepl)) - return + return strings.TrimSpace(reSpace.ReplaceAllString(text, reSpaceReplace)) } func UrlTitle(title string) (text string) { From ce053ccfa6620cc4c8263ba3b54dfcd988a1e6e9 Mon Sep 17 00:00:00 2001 From: ferhat elmas Date: Tue, 25 Nov 2025 00:34:24 +0100 Subject: [PATCH 07/92] fix: multi byte run boundary for cut long title Signed-off-by: ferhat elmas --- pkg/htmltext/htmltext.go | 12 +++++++++--- pkg/htmltext/htmltext_test.go | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/pkg/htmltext/htmltext.go b/pkg/htmltext/htmltext.go index 0b84cda49..707c20a80 100644 --- a/pkg/htmltext/htmltext.go +++ b/pkg/htmltext/htmltext.go @@ -96,10 +96,16 @@ func convertChinese(content string) string { } func cutLongTitle(title string) string { - if len(title) > 150 { - return title[0:150] + maxBytes := 150 + if len(title) <= maxBytes { + return title } - return title + + truncated := title[:maxBytes] + for len(truncated) > 0 && !utf8.ValidString(truncated) { + truncated = truncated[:len(truncated)-1] + } + return truncated } // FetchExcerpt return the excerpt from the HTML string diff --git a/pkg/htmltext/htmltext_test.go b/pkg/htmltext/htmltext_test.go index d549d8874..63866eb28 100644 --- a/pkg/htmltext/htmltext_test.go +++ b/pkg/htmltext/htmltext_test.go @@ -21,6 +21,7 @@ package htmltext import ( "fmt" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -178,6 +179,27 @@ func TestFetchRangedExcerpt(t *testing.T) { assert.Equal(t, expected, actual) } +func TestCutLongTitle(t *testing.T) { + // Short title, no cutting needed + short := "hello" + assert.Equal(t, short, cutLongTitle(short)) + + // Exactly max bytes, no cutting needed + exact150 := strings.Repeat("a", 150) + assert.Equal(t, 150, len(cutLongTitle(exact150))) + + // Just over max bytes, should be cut + exact151 := strings.Repeat("a", 151) + assert.Equal(t, 150, len(cutLongTitle(exact151))) + + // Multi-byte rune at boundary gets removed properly + asciiPart := strings.Repeat("a", 149) // 149 bytes + multiByteChar := "中" // 3 bytes - will span bytes 149-151 + title := asciiPart + multiByteChar // 152 bytes total + + assert.Equal(t, asciiPart, cutLongTitle(title)) +} + func TestFetchMatchedExcerpt(t *testing.T) { var ( expected, From 0777291e80c804cb836b5059d7e0fad5f2b7fe79 Mon Sep 17 00:00:00 2001 From: ferhat elmas Date: Wed, 26 Nov 2025 01:00:42 +0100 Subject: [PATCH 08/92] fix(ui): null pointer access if get branding fails Signed-off-by: ferhat elmas --- internal/router/ui.go | 6 ++-- internal/router/ui_test.go | 59 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 internal/router/ui_test.go diff --git a/internal/router/ui.go b/internal/router/ui.go index 0b5ee3f96..14f71f5fc 100644 --- a/internal/router/ui.go +++ b/internal/router/ui.go @@ -22,7 +22,6 @@ package router import ( "embed" "fmt" - "github.com/apache/answer/plugin" "io/fs" "net/http" "os" @@ -31,6 +30,7 @@ import ( "github.com/apache/answer/internal/controller" "github.com/apache/answer/internal/service/siteinfo_common" "github.com/apache/answer/pkg/htmltext" + "github.com/apache/answer/plugin" "github.com/apache/answer/ui" "github.com/gin-gonic/gin" "github.com/segmentfault/pacman/log" @@ -111,10 +111,10 @@ func (a *UIRouter) Register(r *gin.Engine, baseURLPath string) { if err != nil { log.Error(err) } - if branding.Favicon != "" { + if branding != nil && branding.Favicon != "" { c.String(http.StatusOK, htmltext.GetPicByUrl(branding.Favicon)) return - } else if branding.SquareIcon != "" { + } else if branding != nil && branding.SquareIcon != "" { c.String(http.StatusOK, htmltext.GetPicByUrl(branding.SquareIcon)) return } else { diff --git a/internal/router/ui_test.go b/internal/router/ui_test.go new file mode 100644 index 000000000..645529338 --- /dev/null +++ b/internal/router/ui_test.go @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package router + +import ( + "errors" + "net/http" + "net/http/httptest" + "testing" + + "github.com/apache/answer/internal/service/mock" + "github.com/gin-gonic/gin" + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" +) + +func TestUIRouter_FaviconWithNilBranding(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockSiteInfoService := mock.NewMockSiteInfoCommonService(ctrl) + + // Simulate a database error + mockSiteInfoService.EXPECT(). + GetSiteBranding(gomock.Any()). + Return(nil, errors.New("database connection failed")) + + router := &UIRouter{ + siteInfoService: mockSiteInfoService, + } + + gin.SetMode(gin.TestMode) + r := gin.New() + router.Register(r, "") + + req := httptest.NewRequest(http.MethodGet, "/favicon.ico", nil) + w := httptest.NewRecorder() + + r.ServeHTTP(w, req) + + assert.Equal(t, http.StatusOK, w.Code) +} From bc629db13266dfcd9560da38b39d71a615a1664f Mon Sep 17 00:00:00 2001 From: ferhat elmas Date: Thu, 27 Nov 2025 22:05:14 +0100 Subject: [PATCH 09/92] chore(deps): bump mockgen to 0.6.0 for go1.25 support Signed-off-by: ferhat elmas --- Makefile | 4 ++-- README.md | 2 +- cmd/wire_gen.go | 8 ++++---- docs/docs.go | 32 +++++++++++++++++++++++--------- docs/swagger.json | 32 +++++++++++++++++++++++--------- docs/swagger.yaml | 28 +++++++++++++++++++--------- go.mod | 14 +++++++------- go.sum | 36 ++++++++++++++++++------------------ 8 files changed, 97 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index 6e9679a89..8ab23cce3 100644 --- a/Makefile +++ b/Makefile @@ -23,10 +23,10 @@ universal: generate generate: @$(GO) get github.com/swaggo/swag/cmd/swag@v1.16.3 @$(GO) get github.com/google/wire/cmd/wire@v0.5.0 - @$(GO) get go.uber.org/mock/mockgen@v0.5.0 + @$(GO) get go.uber.org/mock/mockgen@v0.6.0 @$(GO) install github.com/swaggo/swag/cmd/swag@v1.16.3 @$(GO) install github.com/google/wire/cmd/wire@v0.5.0 - @$(GO) install go.uber.org/mock/mockgen@v0.5.0 + @$(GO) install go.uber.org/mock/mockgen@v0.6.0 @$(GO) generate ./... @$(GO) mod tidy diff --git a/README.md b/README.md index 8d201500e..362365496 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ You can also check out the [plugins here](https://answer.apache.org/plugins). - Golang >= 1.23 - Node.js >= 20 - pnpm >= 9 -- [mockgen](https://github.com/uber-go/mock?tab=readme-ov-file#installation) >= 1.6.0 +- [mockgen](https://github.com/uber-go/mock?tab=readme-ov-file#installation) >= 0.6.0 - [wire](https://github.com/google/wire/) >= 0.5.0 ### Build diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index bda555bca..aae1c6af6 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -192,22 +192,22 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, objService := object_info.NewObjService(answerRepo, questionRepo, commentCommonRepo, tagCommonRepo, tagCommonService) notificationQueueService := notice_queue.NewNotificationQueueService() externalNotificationQueueService := notice_queue.NewNewQuestionNotificationQueueService() + reviewRepo := review.NewReviewRepo(dataData) + reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, externalNotificationQueueService, tagCommonService, questionCommon, notificationQueueService, siteInfoCommonService, commentCommonRepo) + commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, notificationQueueService, externalNotificationQueueService, activityQueueService, eventQueueService, reviewService) rolePowerRelRepo := role.NewRolePowerRelRepo(dataData) rolePowerRelService := role2.NewRolePowerRelService(rolePowerRelRepo, userRoleRelService) rankService := rank2.NewRankService(userCommon, userRankRepo, objService, userRoleRelService, rolePowerRelService, configService) limitRepo := limit.NewRateLimitRepo(dataData) rateLimitMiddleware := middleware.NewRateLimitMiddleware(limitRepo) + commentController := controller.NewCommentController(commentService, rankService, captchaService, rateLimitMiddleware) reportRepo := report.NewReportRepo(dataData, uniqueIDRepo) tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, activityQueueService) answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, notificationQueueService) answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, configService) externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, externalNotificationQueueService, userExternalLoginRepo, siteInfoCommonService) - reviewRepo := review.NewReviewRepo(dataData) - reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, externalNotificationQueueService, tagCommonService, questionCommon, notificationQueueService, siteInfoCommonService, commentCommonRepo) questionService := content.NewQuestionService(activityRepo, questionRepo, answerRepo, tagCommonService, tagService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, notificationQueueService, externalNotificationQueueService, activityQueueService, siteInfoCommonService, externalNotificationService, reviewService, configService, eventQueueService, reviewRepo) answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, notificationQueueService, externalNotificationQueueService, activityQueueService, reviewService, eventQueueService) - commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, notificationQueueService, externalNotificationQueueService, activityQueueService, eventQueueService, reviewService) - commentController := controller.NewCommentController(commentService, rankService, captchaService, rateLimitMiddleware) reportHandle := report_handle.NewReportHandle(questionService, answerService, commentService) reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, eventQueueService) reportController := controller.NewReportController(reportService, rankService, captchaService) diff --git a/docs/docs.go b/docs/docs.go index 263e6775e..c87313917 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -9780,8 +9780,6 @@ const docTemplate = `{ "schema.QuestionAdd": { "type": "object", "required": [ - "content", - "tags", "title" ], "properties": { @@ -9796,7 +9794,7 @@ const docTemplate = `{ "description": "content", "type": "string", "maxLength": 65535, - "minLength": 6 + "minLength": 0 }, "tags": { "description": "tags", @@ -9817,8 +9815,6 @@ const docTemplate = `{ "type": "object", "required": [ "answer_content", - "content", - "tags", "title" ], "properties": { @@ -9838,7 +9834,7 @@ const docTemplate = `{ "description": "content", "type": "string", "maxLength": 65535, - "minLength": 6 + "minLength": 0 }, "mention_username_list": { "type": "array", @@ -10119,9 +10115,7 @@ const docTemplate = `{ "schema.QuestionUpdate": { "type": "object", "required": [ - "content", "id", - "tags", "title" ], "properties": { @@ -10136,7 +10130,7 @@ const docTemplate = `{ "description": "content", "type": "string", "maxLength": 65535, - "minLength": 6 + "minLength": 0 }, "edit_summary": { "description": "edit summary", @@ -11047,6 +11041,16 @@ const docTemplate = `{ "max_image_size": { "type": "integer" }, + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "recommend_tags": { "type": "array", "items": { @@ -11091,6 +11095,16 @@ const docTemplate = `{ "max_image_size": { "type": "integer" }, + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "recommend_tags": { "type": "array", "items": { diff --git a/docs/swagger.json b/docs/swagger.json index 8cc85e263..9f89cb157 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -9753,8 +9753,6 @@ "schema.QuestionAdd": { "type": "object", "required": [ - "content", - "tags", "title" ], "properties": { @@ -9769,7 +9767,7 @@ "description": "content", "type": "string", "maxLength": 65535, - "minLength": 6 + "minLength": 0 }, "tags": { "description": "tags", @@ -9790,8 +9788,6 @@ "type": "object", "required": [ "answer_content", - "content", - "tags", "title" ], "properties": { @@ -9811,7 +9807,7 @@ "description": "content", "type": "string", "maxLength": 65535, - "minLength": 6 + "minLength": 0 }, "mention_username_list": { "type": "array", @@ -10092,9 +10088,7 @@ "schema.QuestionUpdate": { "type": "object", "required": [ - "content", "id", - "tags", "title" ], "properties": { @@ -10109,7 +10103,7 @@ "description": "content", "type": "string", "maxLength": 65535, - "minLength": 6 + "minLength": 0 }, "edit_summary": { "description": "edit summary", @@ -11020,6 +11014,16 @@ "max_image_size": { "type": "integer" }, + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "recommend_tags": { "type": "array", "items": { @@ -11064,6 +11068,16 @@ "max_image_size": { "type": "integer" }, + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "recommend_tags": { "type": "array", "items": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 9cdf248e1..d2dd076cf 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1589,7 +1589,7 @@ definitions: content: description: content maxLength: 65535 - minLength: 6 + minLength: 0 type: string tags: description: tags @@ -1602,8 +1602,6 @@ definitions: minLength: 6 type: string required: - - content - - tags - title type: object schema.QuestionAddByAnswer: @@ -1620,7 +1618,7 @@ definitions: content: description: content maxLength: 65535 - minLength: 6 + minLength: 0 type: string mention_username_list: items: @@ -1638,8 +1636,6 @@ definitions: type: string required: - answer_content - - content - - tags - title type: object schema.QuestionInfoResp: @@ -1826,7 +1822,7 @@ definitions: content: description: content maxLength: 65535 - minLength: 6 + minLength: 0 type: string edit_summary: description: edit summary @@ -1849,9 +1845,7 @@ definitions: minLength: 6 type: string required: - - content - id - - tags - title type: object schema.QuestionUpdateInviteUser: @@ -2453,6 +2447,14 @@ definitions: type: integer max_image_size: type: integer + min_content: + maximum: 65535 + minimum: 0 + type: integer + min_tags: + maximum: 5 + minimum: 0 + type: integer recommend_tags: items: $ref: '#/definitions/schema.SiteWriteTag' @@ -2482,6 +2484,14 @@ definitions: type: integer max_image_size: type: integer + min_content: + maximum: 65535 + minimum: 0 + type: integer + min_tags: + maximum: 5 + minimum: 0 + type: integer recommend_tags: items: $ref: '#/definitions/schema.SiteWriteTag' diff --git a/go.mod b/go.mod index 417688120..969d9ebbc 100644 --- a/go.mod +++ b/go.mod @@ -56,12 +56,12 @@ require ( github.com/swaggo/swag v1.16.3 github.com/tidwall/gjson v1.17.3 github.com/yuin/goldmark v1.7.4 - go.uber.org/mock v0.5.0 - golang.org/x/crypto v0.36.0 + go.uber.org/mock v0.6.0 + golang.org/x/crypto v0.41.0 golang.org/x/image v0.20.0 - golang.org/x/net v0.38.0 - golang.org/x/term v0.30.0 - golang.org/x/text v0.23.0 + golang.org/x/net v0.43.0 + golang.org/x/term v0.34.0 + golang.org/x/text v0.28.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/yaml.v3 v3.0.1 modernc.org/sqlite v1.33.0 @@ -161,8 +161,8 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/arch v0.10.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/tools v0.25.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/tools v0.36.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index b45d881fe..35db004db 100644 --- a/go.sum +++ b/go.sum @@ -654,8 +654,8 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= -go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -685,8 +685,8 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/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.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= @@ -703,8 +703,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= +golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -731,8 +731,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 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.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -743,8 +743,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -779,14 +779,14 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc 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.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 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= -golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= -golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= +golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= +golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -795,8 +795,8 @@ 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.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -820,8 +820,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= +golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= +golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From fc2a1d8afeb86602215d831c2767c2a1a56f30a2 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Fri, 28 Nov 2025 10:49:10 +0800 Subject: [PATCH 10/92] fix(answer): update QuestionID handling in answer update process --- internal/controller/answer_controller.go | 1 - internal/schema/answer_schema.go | 1 - internal/service/content/answer_service.go | 19 +++++++++---------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/internal/controller/answer_controller.go b/internal/controller/answer_controller.go index 7c5aca1db..0e43121c5 100644 --- a/internal/controller/answer_controller.go +++ b/internal/controller/answer_controller.go @@ -318,7 +318,6 @@ func (ac *AnswerController) UpdateAnswer(ctx *gin.Context) { handler.HandleResponse(ctx, err, nil) return } - req.QuestionID = uid.DeShortID(req.QuestionID) linkUrlLimitUser := canList[2] isAdmin := middleware.GetUserIsAdminModerator(ctx) if !isAdmin || !linkUrlLimitUser { diff --git a/internal/schema/answer_schema.go b/internal/schema/answer_schema.go index 015e26ac5..9ac4bcad7 100644 --- a/internal/schema/answer_schema.go +++ b/internal/schema/answer_schema.go @@ -78,7 +78,6 @@ type GetAnswerInfoResp struct { type AnswerUpdateReq struct { ID string `json:"id"` - QuestionID string `json:"question_id"` Title string `json:"title"` Content string `validate:"required,notblank,gte=6,lte=65535" json:"content"` EditSummary string `validate:"omitempty" json:"edit_summary"` diff --git a/internal/service/content/answer_service.go b/internal/service/content/answer_service.go index b9d45b522..982bbf88a 100644 --- a/internal/service/content/answer_service.go +++ b/internal/service/content/answer_service.go @@ -346,24 +346,23 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq return "", errors.BadRequest(reason.AnswerCannotUpdate) } - questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionID) + answerInfo, exist, err := as.answerRepo.GetByID(ctx, req.ID) if err != nil { return "", err } if !exist { - return "", errors.BadRequest(reason.QuestionNotFound) + return "", errors.BadRequest(reason.AnswerNotFound) + } + if answerInfo.Status == entity.AnswerStatusDeleted { + return "", errors.BadRequest(reason.AnswerCannotUpdate) } - answerInfo, exist, err := as.answerRepo.GetByID(ctx, req.ID) + questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, answerInfo.QuestionID) if err != nil { return "", err } if !exist { - return "", errors.BadRequest(reason.AnswerNotFound) - } - - if answerInfo.Status == entity.AnswerStatusDeleted { - return "", errors.BadRequest(reason.AnswerCannotUpdate) + return "", errors.BadRequest(reason.QuestionNotFound) } //If the content is the same, ignore it @@ -374,7 +373,7 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq insertData := &entity.Answer{} insertData.ID = req.ID insertData.UserID = answerInfo.UserID - insertData.QuestionID = req.QuestionID + insertData.QuestionID = questionInfo.ID insertData.OriginalText = req.Content insertData.ParsedText = req.HTML insertData.UpdatedAt = time.Now() @@ -403,7 +402,7 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq if err = as.answerRepo.UpdateAnswer(ctx, insertData, []string{"original_text", "parsed_text", "updated_at", "last_edit_user_id"}); err != nil { return "", err } - err = as.questionCommon.UpdatePostTime(ctx, req.QuestionID) + err = as.questionCommon.UpdatePostTime(ctx, questionInfo.ID) if err != nil { return insertData.ID, err } From f723d120d924dcf7e65b969ce18f8111cac40343 Mon Sep 17 00:00:00 2001 From: ferhat elmas Date: Fri, 28 Nov 2025 23:11:57 +0100 Subject: [PATCH 11/92] feat: add golangci-lint into lint target * replace empty interface with any * run fmt via golangci-lint related to #1432 Signed-off-by: ferhat elmas --- .gitignore | 2 +- .golangci.yaml | 30 +++++++++++++++++++ Makefile | 17 +++++++++-- docs/docs.go | 7 ++--- docs/swagger.json | 7 ++--- docs/swagger.yaml | 6 ++-- internal/base/handler/handler.go | 6 ++-- internal/base/handler/response.go | 4 +-- internal/base/pager/pager.go | 2 +- internal/base/pager/pagination.go | 6 ++-- internal/base/server/http_funcmap.go | 6 ++-- internal/base/translator/provider.go | 8 ++--- internal/base/validator/validator.go | 4 +-- internal/install/install_from_env.go | 2 +- internal/migrations/init.go | 10 +++---- internal/migrations/init_data.go | 2 +- internal/migrations/v25.go | 2 +- internal/migrations/v6.go | 2 +- internal/repo/meta/meta_repo.go | 2 +- .../plugin_config/plugin_user_config_repo.go | 2 +- internal/repo/revision/revision_repo.go | 2 +- internal/repo/role/user_role_rel_repo.go | 2 +- internal/repo/search_common/search_repo.go | 26 ++++++++-------- internal/repo/user/user_repo.go | 2 +- internal/schema/question_schema.go | 28 ++++++++--------- internal/schema/revision_schema.go | 2 +- internal/schema/siteinfo_schema.go | 14 ++++----- internal/schema/user_schema.go | 2 +- internal/service/question_common/question.go | 2 +- internal/service/siteinfo/siteinfo_service.go | 2 +- .../siteinfo_common/siteinfo_service.go | 4 +-- pkg/converter/str.go | 2 +- 32 files changed, 125 insertions(+), 90 deletions(-) create mode 100644 .golangci.yaml diff --git a/.gitignore b/.gitignore index 1fc116a74..257ef31d6 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,7 @@ vendor/ /answer-data/ /answer /new_answer - +build/tools/ dist/ # Lint setup generated file diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 000000000..af00efc3b --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,30 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +version: "2" +linters: + default: none + +formatters: + enable: + - gofmt + settings: + gofmt: + simplify: true + rewrite-rules: + - pattern: 'interface{}' + replacement: 'any' diff --git a/Makefile b/Makefile index 8ab23cce3..fd3f044fa 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,15 @@ Revision=$(shell git rev-parse --short HEAD 2>/dev/null || echo "") GO_FLAGS=-ldflags="-X github.com/apache/answer/cmd.Version=$(VERSION) -X 'github.com/apache/answer/cmd.Revision=$(Revision)' -X 'github.com/apache/answer/cmd.Time=`date +%s`' -extldflags -static" GO=$(GO_ENV) "$(shell which go)" +GOLANGCI_VERSION ?= v2.6.2 +TOOLS_BIN := $(shell mkdir -p build/tools && realpath build/tools) + +GOLANGCI = $(TOOLS_BIN)/golangci-lint-$(GOLANGCI_VERSION) +$(GOLANGCI): + rm -f $(TOOLS_BIN)/golangci-lint* + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_VERSION)/install.sh | sh -s -- -b $(TOOLS_BIN) $(GOLANGCI_VERSION) + mv $(TOOLS_BIN)/golangci-lint $(TOOLS_BIN)/golangci-lint-$(GOLANGCI_VERSION) + build: generate @$(GO) build $(GO_FLAGS) -o $(BIN) $(DIR_SRC) @@ -50,8 +59,12 @@ install-ui-packages: ui: @cd ui && pnpm pre-install && pnpm build && cd - -lint: generate +lint: generate $(GOLANGCI) + @bash ./script/check-asf-header.sh + $(GOLANGCI) run + +lint-fix: generate $(GOLANGCI) @bash ./script/check-asf-header.sh - @gofmt -w -l . + $(GOLANGCI) run --fix all: clean build diff --git a/docs/docs.go b/docs/docs.go index c87313917..5e9d5b39d 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -8080,9 +8080,6 @@ const docTemplate = `{ "id": { "type": "string" }, - "question_id": { - "type": "string" - }, "title": { "type": "string" } @@ -10920,7 +10917,7 @@ const docTemplate = `{ }, "theme_config": { "type": "object", - "additionalProperties": true + "additionalProperties": {} } } }, @@ -10935,7 +10932,7 @@ const docTemplate = `{ }, "theme_config": { "type": "object", - "additionalProperties": true + "additionalProperties": {} }, "theme_options": { "type": "array", diff --git a/docs/swagger.json b/docs/swagger.json index 9f89cb157..e0f6378e4 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -8053,9 +8053,6 @@ "id": { "type": "string" }, - "question_id": { - "type": "string" - }, "title": { "type": "string" } @@ -10893,7 +10890,7 @@ }, "theme_config": { "type": "object", - "additionalProperties": true + "additionalProperties": {} } } }, @@ -10908,7 +10905,7 @@ }, "theme_config": { "type": "object", - "additionalProperties": true + "additionalProperties": {} }, "theme_options": { "type": "array", diff --git a/docs/swagger.yaml b/docs/swagger.yaml index d2dd076cf..e0244083b 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -399,8 +399,6 @@ definitions: type: string id: type: string - question_id: - type: string title: type: string required: @@ -2364,7 +2362,7 @@ definitions: maxLength: 255 type: string theme_config: - additionalProperties: true + additionalProperties: {} type: object required: - theme @@ -2376,7 +2374,7 @@ definitions: theme: type: string theme_config: - additionalProperties: true + additionalProperties: {} type: object theme_options: items: diff --git a/internal/base/handler/handler.go b/internal/base/handler/handler.go index 7670feea7..5a4961a3e 100644 --- a/internal/base/handler/handler.go +++ b/internal/base/handler/handler.go @@ -31,7 +31,7 @@ import ( ) // HandleResponse Handle response body -func HandleResponse(ctx *gin.Context, err error, data interface{}) { +func HandleResponse(ctx *gin.Context, err error, data any) { lang := GetLang(ctx) // no error if err == nil { @@ -61,7 +61,7 @@ func HandleResponse(ctx *gin.Context, err error, data interface{}) { } // BindAndCheck bind request and check -func BindAndCheck(ctx *gin.Context, data interface{}) bool { +func BindAndCheck(ctx *gin.Context, data any) bool { lang := GetLang(ctx) ctx.Set(constant.AcceptLanguageFlag, lang) if err := ctx.ShouldBind(data); err != nil { @@ -79,7 +79,7 @@ func BindAndCheck(ctx *gin.Context, data interface{}) bool { } // BindAndCheckReturnErr bind request and check -func BindAndCheckReturnErr(ctx *gin.Context, data interface{}) (errFields []*validator.FormErrorField) { +func BindAndCheckReturnErr(ctx *gin.Context, data any) (errFields []*validator.FormErrorField) { lang := GetLang(ctx) if err := ctx.ShouldBind(data); err != nil { log.Errorf("http_handle BindAndCheck fail, %s", err.Error()) diff --git a/internal/base/handler/response.go b/internal/base/handler/response.go index 827e0b362..51be8a8a1 100644 --- a/internal/base/handler/response.go +++ b/internal/base/handler/response.go @@ -34,7 +34,7 @@ type RespBody struct { // response message Message string `json:"msg"` // response data - Data interface{} `json:"data"` + Data any `json:"data"` } // TrMsg translate the reason cause as a message @@ -63,7 +63,7 @@ func NewRespBodyFromError(e *errors.Error) *RespBody { } // NewRespBodyData new response body with data -func NewRespBodyData(code int, reason string, data interface{}) *RespBody { +func NewRespBodyData(code int, reason string, data any) *RespBody { return &RespBody{ Code: code, Reason: reason, diff --git a/internal/base/pager/pager.go b/internal/base/pager/pager.go index d7a4caa14..b14d99bfa 100644 --- a/internal/base/pager/pager.go +++ b/internal/base/pager/pager.go @@ -27,7 +27,7 @@ import ( ) // Help xorm page helper -func Help(page, pageSize int, rowsSlicePtr interface{}, rowElement interface{}, session *xorm.Session) (total int64, err error) { +func Help(page, pageSize int, rowsSlicePtr any, rowElement any, session *xorm.Session) (total int64, err error) { page, pageSize = ValPageAndPageSize(page, pageSize) sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) diff --git a/internal/base/pager/pagination.go b/internal/base/pager/pagination.go index 36849fed5..1b09e1f21 100644 --- a/internal/base/pager/pagination.go +++ b/internal/base/pager/pagination.go @@ -25,8 +25,8 @@ import ( // PageModel page model type PageModel struct { - Count int64 `json:"count"` - List interface{} `json:"list"` + Count int64 `json:"count"` + List any `json:"list"` } // PageCond page condition @@ -36,7 +36,7 @@ type PageCond struct { } // NewPageModel new page model -func NewPageModel(totalRecords int64, records interface{}) *PageModel { +func NewPageModel(totalRecords int64, records any) *PageModel { sliceValue := reflect.Indirect(reflect.ValueOf(records)) if sliceValue.Kind() != reflect.Slice { panic("not a slice") diff --git a/internal/base/server/http_funcmap.go b/internal/base/server/http_funcmap.go index 9d8e98f96..8f6cac5fc 100644 --- a/internal/base/server/http_funcmap.go +++ b/internal/base/server/http_funcmap.go @@ -64,7 +64,7 @@ var funcMap = template.FuncMap{ "formatLinkNofollow": func(data string) template.HTML { return template.HTML(FormatLinkNofollow(data)) }, - "translator": func(la i18n.Language, data string, params ...interface{}) string { + "translator": func(la i18n.Language, data string, params ...any) string { trans := translator.GlobalTrans.Tr(la, data) if len(params) > 0 && len(params)%2 == 0 { @@ -128,8 +128,8 @@ var funcMap = template.FuncMap{ trans = translator.GlobalTrans.Tr(la, "ui.dates.long_date_with_year") return day.Format(timestamp, trans, tz) }, - "wrapComments": func(comments []*schema.GetCommentResp, la i18n.Language, tz string) map[string]interface{} { - return map[string]interface{}{ + "wrapComments": func(comments []*schema.GetCommentResp, la i18n.Language, tz string) map[string]any { + return map[string]any{ "comments": comments, "language": la, "timezone": tz, diff --git a/internal/base/translator/provider.go b/internal/base/translator/provider.go index 9838d185d..47212e84f 100644 --- a/internal/base/translator/provider.go +++ b/internal/base/translator/provider.go @@ -76,14 +76,14 @@ func NewTranslator(c *I18n) (tr i18n.Translator, err error) { // parse the backend translation originalTr := struct { - Backend map[string]map[string]interface{} `yaml:"backend"` - UI map[string]interface{} `yaml:"ui"` - Plugin map[string]interface{} `yaml:"plugin"` + Backend map[string]map[string]any `yaml:"backend"` + UI map[string]any `yaml:"ui"` + Plugin map[string]any `yaml:"plugin"` }{} if err = yaml.Unmarshal(buf, &originalTr); err != nil { return nil, err } - translation := make(map[string]interface{}, 0) + translation := make(map[string]any, 0) for k, v := range originalTr.Backend { translation[k] = v } diff --git a/internal/base/validator/validator.go b/internal/base/validator/validator.go index 70c7be2e9..22761c521 100644 --- a/internal/base/validator/validator.go +++ b/internal/base/validator/validator.go @@ -187,7 +187,7 @@ func GetValidatorByLang(lang i18n.Language) *MyValidator { } // Check / -func (m *MyValidator) Check(value interface{}) (errFields []*FormErrorField, err error) { +func (m *MyValidator) Check(value any) (errFields []*FormErrorField, err error) { defer func() { if len(errFields) == 0 { return @@ -261,7 +261,7 @@ type Checker interface { Check() (errField []*FormErrorField, err error) } -func getObjectTagByFieldName(obj interface{}, fieldName string) (tag string) { +func getObjectTagByFieldName(obj any, fieldName string) (tag string) { defer func() { if err := recover(); err != nil { log.Error(err) diff --git a/internal/install/install_from_env.go b/internal/install/install_from_env.go index a6b668bab..c05d2aaba 100644 --- a/internal/install/install_from_env.go +++ b/internal/install/install_from_env.go @@ -133,7 +133,7 @@ func initBaseInfo(env *Env) (err error) { return requestAPI(req, "POST", "/installation/base-info", InitBaseInfo) } -func requestAPI(req interface{}, method, url string, handlerFunc gin.HandlerFunc) error { +func requestAPI(req any, method, url string, handlerFunc gin.HandlerFunc) error { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) body, _ := json.Marshal(req) diff --git a/internal/migrations/init.go b/internal/migrations/init.go index 392ecb2c6..184c986b9 100644 --- a/internal/migrations/init.go +++ b/internal/migrations/init.go @@ -208,7 +208,7 @@ func (m *Mentor) initSiteInfoGeneralData() { } func (m *Mentor) initSiteInfoLoginConfig() { - loginConfig := map[string]interface{}{ + loginConfig := map[string]any{ "allow_new_registrations": true, "allow_email_registrations": true, "allow_password_login": true, @@ -223,7 +223,7 @@ func (m *Mentor) initSiteInfoLoginConfig() { } func (m *Mentor) initSiteInfoLegalConfig() { - legalConfig := map[string]interface{}{ + legalConfig := map[string]any{ "external_content_display": m.userData.ExternalContentDisplay, } legalConfigDataBytes, _ := json.Marshal(legalConfig) @@ -244,7 +244,7 @@ func (m *Mentor) initSiteInfoThemeConfig() { } func (m *Mentor) initSiteInfoSEOConfig() { - seoData := map[string]interface{}{ + seoData := map[string]any{ "permalink": constant.PermalinkQuestionID, "robots": defaultSEORobotTxt + m.userData.SiteURL + "/sitemap.xml", } @@ -276,7 +276,7 @@ func (m *Mentor) initSiteInfoUsersConfig() { } func (m *Mentor) initSiteInfoPrivilegeRank() { - privilegeRankData := map[string]interface{}{ + privilegeRankData := map[string]any{ "level": schema.PrivilegeLevel2, } privilegeRankDataBytes, _ := json.Marshal(privilegeRankData) @@ -288,7 +288,7 @@ func (m *Mentor) initSiteInfoPrivilegeRank() { } func (m *Mentor) initSiteInfoWrite() { - writeData := map[string]interface{}{ + writeData := map[string]any{ "min_content": 6, "restrict_answer": true, "min_tags": 1, diff --git a/internal/migrations/init_data.go b/internal/migrations/init_data.go index 96151625d..356a915a7 100644 --- a/internal/migrations/init_data.go +++ b/internal/migrations/init_data.go @@ -43,7 +43,7 @@ Sitemap: ` ) var ( - tables = []interface{}{ + tables = []any{ &entity.Activity{}, &entity.Answer{}, &entity.Collection{}, diff --git a/internal/migrations/v25.go b/internal/migrations/v25.go index 560a852ac..228c2ef26 100644 --- a/internal/migrations/v25.go +++ b/internal/migrations/v25.go @@ -39,7 +39,7 @@ func addFileRecord(ctx context.Context, x *xorm.Engine) error { if err != nil { return fmt.Errorf("get legal config failed: %w", err) } - legalConfig := make(map[string]interface{}) + legalConfig := make(map[string]any) if exist { if err := json.Unmarshal([]byte(legalInfo.Content), &legalConfig); err != nil { return fmt.Errorf("unmarshal legal config failed: %w", err) diff --git a/internal/migrations/v6.go b/internal/migrations/v6.go index 9171ad47a..88fb58497 100644 --- a/internal/migrations/v6.go +++ b/internal/migrations/v6.go @@ -45,7 +45,7 @@ func addNewAnswerNotification(ctx context.Context, x *xorm.Engine) error { } } - m := make(map[string]interface{}) + m := make(map[string]any) _ = json.Unmarshal([]byte(cond.Value), &m) m["new_answer_title"] = "[{{.SiteName}}] {{.DisplayName}} answered your question" m["new_answer_body"] = "{{.QuestionTitle}}

\n\n{{.DisplayName}}:
\n
{{.AnswerSummary}}

\nView it on {{.SiteName}}

\n\nYou are receiving this because you authored the thread. Unsubscribe" diff --git a/internal/repo/meta/meta_repo.go b/internal/repo/meta/meta_repo.go index 767bd04c7..9680fb419 100644 --- a/internal/repo/meta/meta_repo.go +++ b/internal/repo/meta/meta_repo.go @@ -72,7 +72,7 @@ func (mr *metaRepo) UpdateMeta(ctx context.Context, meta *entity.Meta) (err erro // AddOrUpdateMetaByObjectIdAndKey if exist record with same objectID and key, update it. Or create a new one func (mr *metaRepo) AddOrUpdateMetaByObjectIdAndKey(ctx context.Context, objectId, key string, f func(*entity.Meta, bool) (*entity.Meta, error)) error { - _, err := mr.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) { + _, err := mr.data.DB.Transaction(func(session *xorm.Session) (any, error) { session = session.Context(ctx) // 1. acquire meta entity with target object id and key diff --git a/internal/repo/plugin_config/plugin_user_config_repo.go b/internal/repo/plugin_config/plugin_user_config_repo.go index 19d6af5f9..83da8e758 100644 --- a/internal/repo/plugin_config/plugin_user_config_repo.go +++ b/internal/repo/plugin_config/plugin_user_config_repo.go @@ -44,7 +44,7 @@ func NewPluginUserConfigRepo(data *data.Data) plugin_common.PluginUserConfigRepo func (ur *pluginUserConfigRepo) SaveUserPluginConfig(ctx context.Context, userID string, pluginSlugName, configValue string) (err error) { - _, err = ur.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) { + _, err = ur.data.DB.Transaction(func(session *xorm.Session) (any, error) { session = session.Context(ctx) old := &entity.PluginUserConfig{ UserID: userID, diff --git a/internal/repo/revision/revision_repo.go b/internal/repo/revision/revision_repo.go index 09ba1aacd..8b9e08400 100644 --- a/internal/repo/revision/revision_repo.go +++ b/internal/repo/revision/revision_repo.go @@ -64,7 +64,7 @@ func (rr *revisionRepo) AddRevision(ctx context.Context, revision *entity.Revisi if !rr.allowRecord(revision.ObjectType) { return nil } - _, err = rr.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) { + _, err = rr.data.DB.Transaction(func(session *xorm.Session) (any, error) { session = session.Context(ctx) _, err = session.Insert(revision) if err != nil { diff --git a/internal/repo/role/user_role_rel_repo.go b/internal/repo/role/user_role_rel_repo.go index 7bd14ecea..1925339c0 100644 --- a/internal/repo/role/user_role_rel_repo.go +++ b/internal/repo/role/user_role_rel_repo.go @@ -45,7 +45,7 @@ func NewUserRoleRelRepo(data *data.Data) role.UserRoleRelRepo { // SaveUserRoleRel save user role rel func (ur *userRoleRelRepo) SaveUserRoleRel(ctx context.Context, userID string, roleID int) (err error) { - _, err = ur.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) { + _, err = ur.data.DB.Transaction(func(session *xorm.Session) (any, error) { session = session.Context(ctx) item := &entity.UserRoleRel{UserID: userID} exist, err := session.Get(item) diff --git a/internal/repo/search_common/search_repo.go b/internal/repo/search_common/search_repo.go index 314c51878..806517234 100644 --- a/internal/repo/search_common/search_repo.go +++ b/internal/repo/search_common/search_repo.go @@ -107,8 +107,8 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs ub *builder.Builder qfs = qFields afs = aFields - argsQ = []interface{}{} - argsA = []interface{}{} + argsQ = []any{} + argsA = []any{} ) if order == "relevance" { @@ -212,8 +212,8 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs return } - queryArgs := []interface{}{} - countArgs := []interface{}{} + queryArgs := []any{} + countArgs := []any{} queryArgs = append(queryArgs, querySQL) queryArgs = append(queryArgs, argsQ...) @@ -246,7 +246,7 @@ func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagID words = filterWords(words) var ( qfs = qFields - args = []interface{}{} + args = []any{} ) if order == "relevance" { if len(words) > 0 { @@ -313,8 +313,8 @@ func (sr *searchRepo) SearchQuestions(ctx context.Context, words []string, tagID args = append(args, answers) } - queryArgs := []interface{}{} - countArgs := []interface{}{} + queryArgs := []any{} + countArgs := []any{} countSQL, _, err := builder.MySQL().Select("count(*) total").From(b, "c").ToSQL() if err != nil { @@ -358,7 +358,7 @@ func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs var ( afs = aFields - args = []interface{}{} + args = []any{} ) if order == "relevance" { if len(words) > 0 { @@ -409,8 +409,8 @@ func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs args = append(args, questionID) } - queryArgs := []interface{}{} - countArgs := []interface{}{} + queryArgs := []any{} + countArgs := []any{} countSQL, _, err := builder.MySQL().Select("count(*) total").From(b, "c").ToSQL() if err != nil { @@ -575,9 +575,9 @@ func (sr *searchRepo) parseResult(ctx context.Context, res []map[string][]byte, return resultList, nil } -func addRelevanceField(searchFields, words, fields []string) (res []string, args []interface{}) { +func addRelevanceField(searchFields, words, fields []string) (res []string, args []any) { relevanceRes := []string{} - args = []interface{}{} + args = []any{} for _, searchField := range searchFields { var ( @@ -585,7 +585,7 @@ func addRelevanceField(searchFields, words, fields []string) (res []string, args replacement = "REPLACE(%s, ?, '')" replaceField = searchField replaced string - argsField = []interface{}{} + argsField = []any{} ) res = fields diff --git a/internal/repo/user/user_repo.go b/internal/repo/user/user_repo.go index a85cd79a1..1533cc5e8 100644 --- a/internal/repo/user/user_repo.go +++ b/internal/repo/user/user_repo.go @@ -51,7 +51,7 @@ func NewUserRepo(data *data.Data) usercommon.UserRepo { // AddUser add user func (ur *userRepo) AddUser(ctx context.Context, user *entity.User) (err error) { - _, err = ur.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) { + _, err = ur.data.DB.Transaction(func(session *xorm.Session) (any, error) { session = session.Context(ctx) userInfo := &entity.User{} exist, err := session.Where("username = ?", user.Username).Get(userInfo) diff --git a/internal/schema/question_schema.go b/internal/schema/question_schema.go index 84b97b830..133208286 100644 --- a/internal/schema/question_schema.go +++ b/internal/schema/question_schema.go @@ -330,24 +330,24 @@ type UserAnswerInfo struct { CreateTime int `json:"create_time"` UpdateTime int `json:"update_time"` QuestionInfo struct { - Title string `json:"title"` - UrlTitle string `json:"url_title"` - Tags []interface{} `json:"tags"` + Title string `json:"title"` + UrlTitle string `json:"url_title"` + Tags []any `json:"tags"` } `json:"question_info"` } type UserQuestionInfo struct { - ID string `json:"question_id"` - Title string `json:"title"` - UrlTitle string `json:"url_title"` - VoteCount int `json:"vote_count"` - Tags []interface{} `json:"tags"` - ViewCount int `json:"view_count"` - AnswerCount int `json:"answer_count"` - CollectionCount int `json:"collection_count"` - CreatedAt int64 `json:"created_at"` - AcceptedAnswerID string `json:"accepted_answer_id"` - Status string `json:"status"` + ID string `json:"question_id"` + Title string `json:"title"` + UrlTitle string `json:"url_title"` + VoteCount int `json:"vote_count"` + Tags []any `json:"tags"` + ViewCount int `json:"view_count"` + AnswerCount int `json:"answer_count"` + CollectionCount int `json:"collection_count"` + CreatedAt int64 `json:"created_at"` + AcceptedAnswerID string `json:"accepted_answer_id"` + Status string `json:"status"` } const ( diff --git a/internal/schema/revision_schema.go b/internal/schema/revision_schema.go index 946d11653..b3ac0aadd 100644 --- a/internal/schema/revision_schema.go +++ b/internal/schema/revision_schema.go @@ -97,7 +97,7 @@ type GetRevisionResp struct { Title string `json:"title"` UrlTitle string `json:"url_title"` Content string `json:"-"` - ContentParsed interface{} `json:"content"` + ContentParsed any `json:"content"` Status int `json:"status"` CreatedAt time.Time `json:"-"` CreatedAtParsed int64 `json:"create_at"` diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index 76f66cb07..0e43bb420 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -178,9 +178,9 @@ type SiteCustomCssHTMLReq struct { // SiteThemeReq site theme config type SiteThemeReq struct { - Theme string `validate:"required,gt=0,lte=255" json:"theme"` - ThemeConfig map[string]interface{} `validate:"omitempty" json:"theme_config"` - ColorScheme string `validate:"omitempty,gt=0,lte=100" json:"color_scheme"` + Theme string `validate:"required,gt=0,lte=255" json:"theme"` + ThemeConfig map[string]any `validate:"omitempty" json:"theme_config"` + ColorScheme string `validate:"omitempty,gt=0,lte=100" json:"color_scheme"` } type SiteSeoReq struct { @@ -213,10 +213,10 @@ type SiteUsersResp SiteUsersReq // SiteThemeResp site theme response type SiteThemeResp struct { - ThemeOptions []*ThemeOption `json:"theme_options"` - Theme string `json:"theme"` - ThemeConfig map[string]interface{} `json:"theme_config"` - ColorScheme string `json:"color_scheme"` + ThemeOptions []*ThemeOption `json:"theme_options"` + Theme string `json:"theme"` + ThemeConfig map[string]any `json:"theme_config"` + ColorScheme string `json:"color_scheme"` } func (s *SiteThemeResp) TrTheme(ctx context.Context) { diff --git a/internal/schema/user_schema.go b/internal/schema/user_schema.go index 7ba8817a8..d209c8f58 100644 --- a/internal/schema/user_schema.go +++ b/internal/schema/user_schema.go @@ -200,7 +200,7 @@ func (r *GetOtherUserInfoByUsernameResp) ConvertFromUserEntityWithLang(ctx conte r.SuspendedUntil = userInfo.SuspendedUntil.Unix() trans := translator.GlobalTrans.Tr(lang, "ui.dates.long_date_with_time") suspendedUntilFormatted := day.Format(userInfo.SuspendedUntil.Unix(), trans, "UTC") - r.StatusMsg = translator.TrWithData(lang, reason.UserStatusSuspendedUntil, map[string]interface{}{ + r.StatusMsg = translator.TrWithData(lang, reason.UserStatusSuspendedUntil, map[string]any{ "SuspendedUntil": suspendedUntilFormatted, }) } diff --git a/internal/service/question_common/question.go b/internal/service/question_common/question.go index feb5626ed..333806445 100644 --- a/internal/service/question_common/question.go +++ b/internal/service/question_common/question.go @@ -622,7 +622,7 @@ func (qs *QuestionCommon) SitemapCron(ctx context.Context) { } } -func (qs *QuestionCommon) SetCache(ctx context.Context, cachekey string, info interface{}) error { +func (qs *QuestionCommon) SetCache(ctx context.Context, cachekey string, info any) error { infoStr, err := json.Marshal(info) if err != nil { return errors.InternalServer(reason.UnknownError).WithError(err).WithStack() diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index 92b3e0c71..cf43d68d5 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -183,7 +183,7 @@ func (s *SiteInfoService) SaveSiteBranding(ctx context.Context, req *schema.Site } // SaveSiteWrite save site configuration about write -func (s *SiteInfoService) SaveSiteWrite(ctx context.Context, req *schema.SiteWriteReq) (resp interface{}, err error) { +func (s *SiteInfoService) SaveSiteWrite(ctx context.Context, req *schema.SiteWriteReq) (resp any, err error) { recommendTags, reservedTags := make([]string, 0), make([]string, 0) recommendTagMapping, reservedTagMapping := make(map[string]bool), make(map[string]bool) for _, tag := range req.ReservedTags { diff --git a/internal/service/siteinfo_common/siteinfo_service.go b/internal/service/siteinfo_common/siteinfo_service.go index ef4869cc4..fda117229 100644 --- a/internal/service/siteinfo_common/siteinfo_service.go +++ b/internal/service/siteinfo_common/siteinfo_service.go @@ -56,7 +56,7 @@ type SiteInfoCommonService interface { GetSiteCustomCssHTML(ctx context.Context) (resp *schema.SiteCustomCssHTMLResp, err error) GetSiteTheme(ctx context.Context) (resp *schema.SiteThemeResp, err error) GetSiteSeo(ctx context.Context) (resp *schema.SiteSeoResp, err error) - GetSiteInfoByType(ctx context.Context, siteType string, resp interface{}) (err error) + GetSiteInfoByType(ctx context.Context, siteType string, resp any) (err error) IsBrandingFileUsed(ctx context.Context, filePath string) bool } @@ -224,7 +224,7 @@ func (s *siteInfoCommonService) EnableShortID(ctx context.Context) (enabled bool return siteSeo.IsShortLink() } -func (s *siteInfoCommonService) GetSiteInfoByType(ctx context.Context, siteType string, resp interface{}) (err error) { +func (s *siteInfoCommonService) GetSiteInfoByType(ctx context.Context, siteType string, resp any) (err error) { siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, siteType) if err != nil { return err diff --git a/pkg/converter/str.go b/pkg/converter/str.go index 40c147fdc..5164609ca 100644 --- a/pkg/converter/str.go +++ b/pkg/converter/str.go @@ -47,7 +47,7 @@ func IntToString(data int64) string { // InterfaceToString converts data to string // It will be used in template render -func InterfaceToString(data interface{}) string { +func InterfaceToString(data any) string { switch t := data.(type) { case int: i := data.(int) From 9540ef60050fb6e2598d8d72ab23514f6e6d4f93 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Mon, 1 Dec 2025 11:30:42 +0800 Subject: [PATCH 12/92] refactor(goimports): add goimports to golangci-lint configuration #1432 --- .golangci.yaml | 1 + internal/base/handler/handler.go | 3 ++- internal/base/middleware/accept_language.go | 3 ++- internal/base/middleware/rate_limit.go | 1 + internal/cli/config.go | 1 + internal/cli/i18n.go | 7 ++++--- internal/controller/template_render/comment.go | 1 + internal/controller/user_plugin_controller.go | 3 ++- internal/entity/badge_entity.go | 3 ++- internal/entity/config_entity.go | 1 + internal/migrations/v1.go | 1 + internal/migrations/v13.go | 1 + internal/migrations/v14.go | 1 + internal/migrations/v15.go | 1 + internal/migrations/v16.go | 1 + internal/migrations/v17.go | 1 + internal/migrations/v18.go | 1 + internal/migrations/v19.go | 1 + internal/migrations/v2.go | 1 + internal/migrations/v21.go | 1 + internal/migrations/v22.go | 1 + internal/migrations/v24.go | 1 + internal/repo/activity/answer_repo.go | 3 ++- internal/repo/activity/user_active_repo.go | 1 + internal/repo/activity_common/vote.go | 1 + internal/repo/auth/auth.go | 1 + internal/repo/badge/badge_event_rule.go | 3 ++- internal/repo/badge/badge_repo.go | 1 + internal/repo/badge_award/badge_award_repo.go | 1 + internal/repo/badge_group/badge_group_repo.go | 1 + internal/repo/collection/collection_repo.go | 1 + internal/repo/export/email_repo.go | 3 ++- internal/repo/limit/limit.go | 3 ++- internal/repo/meta/meta_repo.go | 2 +- internal/repo/plugin_config/plugin_user_config_repo.go | 1 + internal/repo/search_sync/search_sync.go | 1 + .../user_notification_config_repo.go | 1 + internal/schema/email_template.go | 1 + internal/schema/notification_schema.go | 3 ++- internal/schema/user_notification_schema.go | 1 + internal/service/activity/activity.go | 2 +- internal/service/activity/answer_activity_service.go | 1 + internal/service/badge/badge_award_service.go | 1 + internal/service/badge/badge_event_handler.go | 1 + internal/service/badge/badge_group_service.go | 1 + internal/service/badge/badge_service.go | 3 ++- internal/service/content/question_hottest_service.go | 5 +++-- internal/service/content/vote_service.go | 3 ++- internal/service/export/email_service.go | 3 ++- internal/service/meta/meta_service.go | 3 ++- internal/service/notification/notification_service.go | 1 + internal/service/permission/answer_permission.go | 1 + internal/service/permission/question_permission.go | 1 + internal/service/provider.go | 2 +- internal/service/report/report_service.go | 1 + internal/service/search_parser/search_parser.go | 3 ++- .../user_notification_config_service.go | 1 + pkg/converter/str.go | 3 ++- pkg/day/day_test.go | 3 ++- pkg/gravatar/gravatar_test.go | 3 ++- 60 files changed, 82 insertions(+), 25 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index af00efc3b..263f63f70 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -22,6 +22,7 @@ linters: formatters: enable: - gofmt + - goimports settings: gofmt: simplify: true diff --git a/internal/base/handler/handler.go b/internal/base/handler/handler.go index 5a4961a3e..b545b5e01 100644 --- a/internal/base/handler/handler.go +++ b/internal/base/handler/handler.go @@ -21,13 +21,14 @@ package handler import ( "errors" + "net/http" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/reason" "github.com/apache/answer/internal/base/validator" "github.com/gin-gonic/gin" myErrors "github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/log" - "net/http" ) // HandleResponse Handle response body diff --git a/internal/base/middleware/accept_language.go b/internal/base/middleware/accept_language.go index 7a8ee391a..ca8a1f903 100644 --- a/internal/base/middleware/accept_language.go +++ b/internal/base/middleware/accept_language.go @@ -20,13 +20,14 @@ package middleware import ( + "strings" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/translator" "github.com/gin-gonic/gin" "github.com/segmentfault/pacman/i18n" "golang.org/x/text/language" - "strings" ) // ExtractAndSetAcceptLanguage extract accept language from header and set to context diff --git a/internal/base/middleware/rate_limit.go b/internal/base/middleware/rate_limit.go index 29b961757..d376a6d50 100644 --- a/internal/base/middleware/rate_limit.go +++ b/internal/base/middleware/rate_limit.go @@ -22,6 +22,7 @@ package middleware import ( "encoding/json" "fmt" + "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/reason" "github.com/apache/answer/internal/repo/limit" diff --git a/internal/cli/config.go b/internal/cli/config.go index 93cb8eab2..ecb62a13c 100644 --- a/internal/cli/config.go +++ b/internal/cli/config.go @@ -23,6 +23,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/entity" diff --git a/internal/cli/i18n.go b/internal/cli/i18n.go index faef0f28a..819ebd753 100644 --- a/internal/cli/i18n.go +++ b/internal/cli/i18n.go @@ -21,13 +21,14 @@ package cli import ( "fmt" + "os" + "path/filepath" + "strings" + "github.com/apache/answer/i18n" "github.com/apache/answer/pkg/dir" "github.com/apache/answer/pkg/writer" "gopkg.in/yaml.v3" - "os" - "path/filepath" - "strings" ) type YamlPluginContent struct { diff --git a/internal/controller/template_render/comment.go b/internal/controller/template_render/comment.go index 67efd2129..2862ad8dd 100644 --- a/internal/controller/template_render/comment.go +++ b/internal/controller/template_render/comment.go @@ -21,6 +21,7 @@ package templaterender import ( "context" + "github.com/apache/answer/internal/base/pager" "github.com/apache/answer/internal/schema" ) diff --git a/internal/controller/user_plugin_controller.go b/internal/controller/user_plugin_controller.go index 310215253..1c4c041c5 100644 --- a/internal/controller/user_plugin_controller.go +++ b/internal/controller/user_plugin_controller.go @@ -21,10 +21,11 @@ package controller import ( "encoding/json" + "net/http" + "github.com/apache/answer/internal/base/middleware" "github.com/apache/answer/internal/base/reason" "github.com/segmentfault/pacman/errors" - "net/http" "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/schema" diff --git a/internal/entity/badge_entity.go b/internal/entity/badge_entity.go index a370e2750..367bb7456 100644 --- a/internal/entity/badge_entity.go +++ b/internal/entity/badge_entity.go @@ -20,8 +20,9 @@ package entity import ( - "github.com/tidwall/gjson" "time" + + "github.com/tidwall/gjson" ) type BadgeLevel int diff --git a/internal/entity/config_entity.go b/internal/entity/config_entity.go index 95a02be48..d39af7b2d 100644 --- a/internal/entity/config_entity.go +++ b/internal/entity/config_entity.go @@ -21,6 +21,7 @@ package entity import ( "encoding/json" + "github.com/segmentfault/pacman/log" "github.com/apache/answer/pkg/converter" diff --git a/internal/migrations/v1.go b/internal/migrations/v1.go index c5e731a0e..688732fa7 100644 --- a/internal/migrations/v1.go +++ b/internal/migrations/v1.go @@ -21,6 +21,7 @@ package migrations import ( "context" + "xorm.io/xorm" ) diff --git a/internal/migrations/v13.go b/internal/migrations/v13.go index 30bfbb542..57d248482 100644 --- a/internal/migrations/v13.go +++ b/internal/migrations/v13.go @@ -24,6 +24,7 @@ import ( "encoding/json" "fmt" "time" + "xorm.io/builder" "github.com/apache/answer/internal/base/constant" diff --git a/internal/migrations/v14.go b/internal/migrations/v14.go index ee3a3d0d6..5e125c98e 100644 --- a/internal/migrations/v14.go +++ b/internal/migrations/v14.go @@ -22,6 +22,7 @@ package migrations import ( "context" "time" + "xorm.io/xorm/schemas" "xorm.io/xorm" diff --git a/internal/migrations/v15.go b/internal/migrations/v15.go index 5195c105a..5858d0097 100644 --- a/internal/migrations/v15.go +++ b/internal/migrations/v15.go @@ -21,6 +21,7 @@ package migrations import ( "context" + "github.com/apache/answer/internal/entity" "xorm.io/xorm" ) diff --git a/internal/migrations/v16.go b/internal/migrations/v16.go index 11643600c..11ae36843 100644 --- a/internal/migrations/v16.go +++ b/internal/migrations/v16.go @@ -21,6 +21,7 @@ package migrations import ( "context" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/entity" "github.com/segmentfault/pacman/log" diff --git a/internal/migrations/v17.go b/internal/migrations/v17.go index 655e547a2..3fa2c7b31 100644 --- a/internal/migrations/v17.go +++ b/internal/migrations/v17.go @@ -22,6 +22,7 @@ package migrations import ( "context" "fmt" + "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/service/permission" "github.com/segmentfault/pacman/log" diff --git a/internal/migrations/v18.go b/internal/migrations/v18.go index 89db524f5..7178c704e 100644 --- a/internal/migrations/v18.go +++ b/internal/migrations/v18.go @@ -23,6 +23,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" diff --git a/internal/migrations/v19.go b/internal/migrations/v19.go index b45d374bb..b50c89f14 100644 --- a/internal/migrations/v19.go +++ b/internal/migrations/v19.go @@ -21,6 +21,7 @@ package migrations import ( "context" + "github.com/apache/answer/internal/entity" "xorm.io/xorm" ) diff --git a/internal/migrations/v2.go b/internal/migrations/v2.go index 4e17597dc..601ff98b2 100644 --- a/internal/migrations/v2.go +++ b/internal/migrations/v2.go @@ -21,6 +21,7 @@ package migrations import ( "context" + "xorm.io/xorm" ) diff --git a/internal/migrations/v21.go b/internal/migrations/v21.go index 880852f8e..de38bffbd 100644 --- a/internal/migrations/v21.go +++ b/internal/migrations/v21.go @@ -21,6 +21,7 @@ package migrations import ( "context" + "xorm.io/xorm" ) diff --git a/internal/migrations/v22.go b/internal/migrations/v22.go index 14292a1e7..e7177deae 100644 --- a/internal/migrations/v22.go +++ b/internal/migrations/v22.go @@ -22,6 +22,7 @@ package migrations import ( "context" "fmt" + "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/repo/unique" diff --git a/internal/migrations/v24.go b/internal/migrations/v24.go index 19358af45..a488679f6 100644 --- a/internal/migrations/v24.go +++ b/internal/migrations/v24.go @@ -23,6 +23,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" diff --git a/internal/repo/activity/answer_repo.go b/internal/repo/activity/answer_repo.go index db6e3bde4..4aca874a7 100644 --- a/internal/repo/activity/answer_repo.go +++ b/internal/repo/activity/answer_repo.go @@ -22,8 +22,9 @@ package activity import ( "context" "fmt" - "github.com/segmentfault/pacman/log" "time" + + "github.com/segmentfault/pacman/log" "xorm.io/builder" "github.com/apache/answer/internal/base/constant" diff --git a/internal/repo/activity/user_active_repo.go b/internal/repo/activity/user_active_repo.go index 2452bcf83..68dfec7d7 100644 --- a/internal/repo/activity/user_active_repo.go +++ b/internal/repo/activity/user_active_repo.go @@ -22,6 +22,7 @@ package activity import ( "context" "fmt" + "xorm.io/builder" "github.com/apache/answer/internal/base/data" diff --git a/internal/repo/activity_common/vote.go b/internal/repo/activity_common/vote.go index cb7d23d00..506578424 100644 --- a/internal/repo/activity_common/vote.go +++ b/internal/repo/activity_common/vote.go @@ -21,6 +21,7 @@ package activity_common import ( "context" + "github.com/apache/answer/pkg/uid" "github.com/apache/answer/internal/base/data" diff --git a/internal/repo/auth/auth.go b/internal/repo/auth/auth.go index a1e358f9a..597352b23 100644 --- a/internal/repo/auth/auth.go +++ b/internal/repo/auth/auth.go @@ -22,6 +22,7 @@ package auth import ( "context" "encoding/json" + "github.com/apache/answer/internal/service/auth" "github.com/apache/answer/internal/base/constant" diff --git a/internal/repo/badge/badge_event_rule.go b/internal/repo/badge/badge_event_rule.go index 8c4656db3..786d988ac 100644 --- a/internal/repo/badge/badge_event_rule.go +++ b/internal/repo/badge/badge_event_rule.go @@ -21,6 +21,8 @@ package badge import ( "context" + "strconv" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/reason" @@ -29,7 +31,6 @@ import ( "github.com/apache/answer/internal/service/badge" "github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/log" - "strconv" ) // eventRuleRepo event rule repo diff --git a/internal/repo/badge/badge_repo.go b/internal/repo/badge/badge_repo.go index 257caef81..baff45d8a 100644 --- a/internal/repo/badge/badge_repo.go +++ b/internal/repo/badge/badge_repo.go @@ -21,6 +21,7 @@ package badge import ( "context" + "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/pager" "github.com/apache/answer/internal/base/reason" diff --git a/internal/repo/badge_award/badge_award_repo.go b/internal/repo/badge_award/badge_award_repo.go index eda5d80c2..11429e570 100644 --- a/internal/repo/badge_award/badge_award_repo.go +++ b/internal/repo/badge_award/badge_award_repo.go @@ -22,6 +22,7 @@ package badge_award import ( "context" "fmt" + "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/pager" "github.com/apache/answer/internal/base/reason" diff --git a/internal/repo/badge_group/badge_group_repo.go b/internal/repo/badge_group/badge_group_repo.go index 839ba4691..8f1111a48 100644 --- a/internal/repo/badge_group/badge_group_repo.go +++ b/internal/repo/badge_group/badge_group_repo.go @@ -21,6 +21,7 @@ package badge_group import ( "context" + "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/service/badge" diff --git a/internal/repo/collection/collection_repo.go b/internal/repo/collection/collection_repo.go index a3faacdb5..f30692c97 100644 --- a/internal/repo/collection/collection_repo.go +++ b/internal/repo/collection/collection_repo.go @@ -21,6 +21,7 @@ package collection import ( "context" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/handler" diff --git a/internal/repo/export/email_repo.go b/internal/repo/export/email_repo.go index 1f8e1ce83..a3e619712 100644 --- a/internal/repo/export/email_repo.go +++ b/internal/repo/export/email_repo.go @@ -21,9 +21,10 @@ package export import ( "context" + "time" + "github.com/apache/answer/internal/base/constant" "github.com/tidwall/gjson" - "time" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/reason" diff --git a/internal/repo/limit/limit.go b/internal/repo/limit/limit.go index 4868accd5..524ad12bc 100644 --- a/internal/repo/limit/limit.go +++ b/internal/repo/limit/limit.go @@ -22,11 +22,12 @@ package limit import ( "context" "fmt" + "time" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/reason" "github.com/segmentfault/pacman/errors" - "time" ) // LimitRepo auth repository diff --git a/internal/repo/meta/meta_repo.go b/internal/repo/meta/meta_repo.go index 9680fb419..fecd7bd5d 100644 --- a/internal/repo/meta/meta_repo.go +++ b/internal/repo/meta/meta_repo.go @@ -25,7 +25,7 @@ import ( "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/reason" "github.com/apache/answer/internal/entity" - "github.com/apache/answer/internal/service/meta_common" + metacommon "github.com/apache/answer/internal/service/meta_common" "github.com/segmentfault/pacman/errors" "xorm.io/builder" "xorm.io/xorm" diff --git a/internal/repo/plugin_config/plugin_user_config_repo.go b/internal/repo/plugin_config/plugin_user_config_repo.go index 83da8e758..d14442a56 100644 --- a/internal/repo/plugin_config/plugin_user_config_repo.go +++ b/internal/repo/plugin_config/plugin_user_config_repo.go @@ -21,6 +21,7 @@ package plugin_config import ( "context" + "github.com/apache/answer/internal/base/pager" "xorm.io/xorm" diff --git a/internal/repo/search_sync/search_sync.go b/internal/repo/search_sync/search_sync.go index 5c0adc0f9..889ffe5be 100644 --- a/internal/repo/search_sync/search_sync.go +++ b/internal/repo/search_sync/search_sync.go @@ -21,6 +21,7 @@ package search_sync import ( "context" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/entity" diff --git a/internal/repo/user_notification_config/user_notification_config_repo.go b/internal/repo/user_notification_config/user_notification_config_repo.go index 8ea2b065b..0e761514b 100644 --- a/internal/repo/user_notification_config/user_notification_config_repo.go +++ b/internal/repo/user_notification_config/user_notification_config_repo.go @@ -21,6 +21,7 @@ package user_notification_config import ( "context" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/reason" diff --git a/internal/schema/email_template.go b/internal/schema/email_template.go index 1fcdfbce3..d7e4b929a 100644 --- a/internal/schema/email_template.go +++ b/internal/schema/email_template.go @@ -21,6 +21,7 @@ package schema import ( "encoding/json" + "github.com/apache/answer/internal/base/constant" ) diff --git a/internal/schema/notification_schema.go b/internal/schema/notification_schema.go index a68328ace..e5d60615e 100644 --- a/internal/schema/notification_schema.go +++ b/internal/schema/notification_schema.go @@ -21,8 +21,9 @@ package schema import ( "encoding/json" - "github.com/apache/answer/internal/entity" "sort" + + "github.com/apache/answer/internal/entity" ) const ( diff --git a/internal/schema/user_notification_schema.go b/internal/schema/user_notification_schema.go index eca97e81c..60cc4a27b 100644 --- a/internal/schema/user_notification_schema.go +++ b/internal/schema/user_notification_schema.go @@ -21,6 +21,7 @@ package schema import ( "encoding/json" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/entity" ) diff --git a/internal/service/activity/activity.go b/internal/service/activity/activity.go index 2d384f34c..061d84493 100644 --- a/internal/service/activity/activity.go +++ b/internal/service/activity/activity.go @@ -26,7 +26,7 @@ import ( "strings" "github.com/apache/answer/internal/service/activity_common" - "github.com/apache/answer/internal/service/meta_common" + metacommon "github.com/apache/answer/internal/service/meta_common" "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" diff --git a/internal/service/activity/answer_activity_service.go b/internal/service/activity/answer_activity_service.go index 169e7eb39..48b5f3ef9 100644 --- a/internal/service/activity/answer_activity_service.go +++ b/internal/service/activity/answer_activity_service.go @@ -21,6 +21,7 @@ package activity import ( "context" + "github.com/apache/answer/internal/schema" "github.com/apache/answer/internal/service/activity_type" "github.com/apache/answer/internal/service/config" diff --git a/internal/service/badge/badge_award_service.go b/internal/service/badge/badge_award_service.go index 397a7471a..982c1d1a4 100644 --- a/internal/service/badge/badge_award_service.go +++ b/internal/service/badge/badge_award_service.go @@ -21,6 +21,7 @@ package badge import ( "context" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/reason" diff --git a/internal/service/badge/badge_event_handler.go b/internal/service/badge/badge_event_handler.go index 219822947..cc161f6ad 100644 --- a/internal/service/badge/badge_event_handler.go +++ b/internal/service/badge/badge_event_handler.go @@ -21,6 +21,7 @@ package badge import ( "context" + "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" diff --git a/internal/service/badge/badge_group_service.go b/internal/service/badge/badge_group_service.go index e0dab6e89..7c220a0be 100644 --- a/internal/service/badge/badge_group_service.go +++ b/internal/service/badge/badge_group_service.go @@ -21,6 +21,7 @@ package badge import ( "context" + "github.com/apache/answer/internal/entity" ) diff --git a/internal/service/badge/badge_service.go b/internal/service/badge/badge_service.go index 7bc9ffe21..03b8a8774 100644 --- a/internal/service/badge/badge_service.go +++ b/internal/service/badge/badge_service.go @@ -21,6 +21,8 @@ package badge import ( "context" + "strings" + "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/reason" "github.com/apache/answer/internal/base/translator" @@ -32,7 +34,6 @@ import ( "github.com/gin-gonic/gin" "github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/log" - "strings" ) type BadgeRepo interface { diff --git a/internal/service/content/question_hottest_service.go b/internal/service/content/question_hottest_service.go index a33b155fb..085b36709 100644 --- a/internal/service/content/question_hottest_service.go +++ b/internal/service/content/question_hottest_service.go @@ -21,11 +21,12 @@ package content import ( "context" + "math" + "time" + "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" "github.com/segmentfault/pacman/log" - "math" - "time" ) func (q *QuestionService) RefreshHottestCron(ctx context.Context) { diff --git a/internal/service/content/vote_service.go b/internal/service/content/vote_service.go index ff3ee5974..92f0c9962 100644 --- a/internal/service/content/vote_service.go +++ b/internal/service/content/vote_service.go @@ -22,9 +22,10 @@ package content import ( "context" "fmt" - "github.com/apache/answer/internal/service/event_queue" "strings" + "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/service/activity_common" "github.com/apache/answer/internal/base/constant" diff --git a/internal/service/export/email_service.go b/internal/service/export/email_service.go index b00ee093b..ddf31b348 100644 --- a/internal/service/export/email_service.go +++ b/internal/service/export/email_service.go @@ -23,12 +23,13 @@ import ( "crypto/tls" "encoding/json" "fmt" - "github.com/apache/answer/pkg/display" "mime" "os" "strings" "time" + "github.com/apache/answer/pkg/display" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/reason" diff --git a/internal/service/meta/meta_service.go b/internal/service/meta/meta_service.go index 9e4f07410..4b3104197 100644 --- a/internal/service/meta/meta_service.go +++ b/internal/service/meta/meta_service.go @@ -23,10 +23,11 @@ import ( "context" "encoding/json" "errors" - "github.com/apache/answer/internal/service/event_queue" "strconv" "strings" + "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/reason" diff --git a/internal/service/notification/notification_service.go b/internal/service/notification/notification_service.go index 598212aa1..09d871351 100644 --- a/internal/service/notification/notification_service.go +++ b/internal/service/notification/notification_service.go @@ -23,6 +23,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/base/handler" diff --git a/internal/service/permission/answer_permission.go b/internal/service/permission/answer_permission.go index 4eb563a5a..340fca8db 100644 --- a/internal/service/permission/answer_permission.go +++ b/internal/service/permission/answer_permission.go @@ -21,6 +21,7 @@ package permission import ( "context" + "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/base/handler" diff --git a/internal/service/permission/question_permission.go b/internal/service/permission/question_permission.go index b6750beae..eca0a58f2 100644 --- a/internal/service/permission/question_permission.go +++ b/internal/service/permission/question_permission.go @@ -21,6 +21,7 @@ package permission import ( "context" + "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/base/handler" diff --git a/internal/service/provider.go b/internal/service/provider.go index 4b1b64276..65535f41b 100644 --- a/internal/service/provider.go +++ b/internal/service/provider.go @@ -40,7 +40,7 @@ import ( "github.com/apache/answer/internal/service/follow" "github.com/apache/answer/internal/service/importer" "github.com/apache/answer/internal/service/meta" - "github.com/apache/answer/internal/service/meta_common" + metacommon "github.com/apache/answer/internal/service/meta_common" "github.com/apache/answer/internal/service/notice_queue" "github.com/apache/answer/internal/service/notification" notficationcommon "github.com/apache/answer/internal/service/notification_common" diff --git a/internal/service/report/report_service.go b/internal/service/report/report_service.go index 7dcc1d689..d32ccdabf 100644 --- a/internal/service/report/report_service.go +++ b/internal/service/report/report_service.go @@ -21,6 +21,7 @@ package report import ( "encoding/json" + "github.com/apache/answer/internal/service/event_queue" "github.com/apache/answer/internal/base/constant" diff --git a/internal/service/search_parser/search_parser.go b/internal/service/search_parser/search_parser.go index e87efaf6f..3e6182e15 100644 --- a/internal/service/search_parser/search_parser.go +++ b/internal/service/search_parser/search_parser.go @@ -22,10 +22,11 @@ package search_parser import ( "context" "fmt" - "github.com/apache/answer/internal/base/constant" "regexp" "strings" + "github.com/apache/answer/internal/base/constant" + "github.com/apache/answer/internal/schema" "github.com/apache/answer/internal/service/tag_common" usercommon "github.com/apache/answer/internal/service/user_common" diff --git a/internal/service/user_notification_config/user_notification_config_service.go b/internal/service/user_notification_config/user_notification_config_service.go index 7c54df0aa..01da3ee2f 100644 --- a/internal/service/user_notification_config/user_notification_config_service.go +++ b/internal/service/user_notification_config/user_notification_config_service.go @@ -21,6 +21,7 @@ package user_notification_config import ( "context" + "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" diff --git a/pkg/converter/str.go b/pkg/converter/str.go index 5164609ca..8553975be 100644 --- a/pkg/converter/str.go +++ b/pkg/converter/str.go @@ -21,8 +21,9 @@ package converter import ( "fmt" - "github.com/segmentfault/pacman/log" "strconv" + + "github.com/segmentfault/pacman/log" ) func StringToInt64(str string) int64 { diff --git a/pkg/day/day_test.go b/pkg/day/day_test.go index 73e49aca3..4f945d88f 100644 --- a/pkg/day/day_test.go +++ b/pkg/day/day_test.go @@ -20,9 +20,10 @@ package day import ( - "github.com/stretchr/testify/assert" "testing" "time" + + "github.com/stretchr/testify/assert" ) func TestFormat(t *testing.T) { diff --git a/pkg/gravatar/gravatar_test.go b/pkg/gravatar/gravatar_test.go index bf504e68f..b88a69649 100644 --- a/pkg/gravatar/gravatar_test.go +++ b/pkg/gravatar/gravatar_test.go @@ -20,9 +20,10 @@ package gravatar import ( - "github.com/apache/answer/internal/base/constant" "testing" + "github.com/apache/answer/internal/base/constant" + "github.com/stretchr/testify/assert" ) From 5e705a124b3ae2d927f8084e545c3809ae70f4a8 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Mon, 1 Dec 2025 12:23:50 +0800 Subject: [PATCH 13/92] refactor(lint): improve error handling and code consistency across multiple files --- .golangci.yaml | 13 ++++- cmd/wire.go | 3 +- internal/base/conf/conf.go | 4 +- internal/base/constant/ctx_flag.go | 7 +++ internal/base/data/data.go | 2 +- internal/base/handler/lang.go | 2 +- internal/base/handler/short_id.go | 2 +- internal/base/server/http_funcmap.go | 9 ++-- internal/base/validator/validator.go | 2 +- internal/cli/build.go | 52 ------------------- internal/cli/config.go | 6 ++- internal/cli/dump.go | 4 +- internal/cli/install_check.go | 8 ++- internal/cli/reset_password.go | 4 +- internal/controller/template_controller.go | 43 ++++++--------- .../controller/template_render/controller.go | 1 - internal/controller/user_controller.go | 7 +-- internal/install/install_from_env.go | 3 +- internal/migrations/migrations.go | 4 +- internal/migrations/v22.go | 3 ++ internal/migrations/v24.go | 3 -- internal/repo/answer/answer_repo.go | 1 + .../plugin_config/plugin_user_config_repo.go | 2 +- internal/repo/repo_test/repo_main_test.go | 2 +- internal/repo/tag/tag_rel_repo.go | 1 + internal/service/action/captcha_service.go | 7 ++- internal/service/action/captcha_strategy.go | 27 +++++----- internal/service/badge/badge_event_handler.go | 1 - internal/service/badge/badge_service.go | 26 +++------- internal/service/content/question_service.go | 22 ++++---- internal/service/content/revision_service.go | 5 +- internal/service/content/search_service.go | 3 ++ internal/service/content/vote_service.go | 3 -- .../service/dashboard/dashboard_service.go | 8 +-- .../file_record/file_record_service.go | 1 - internal/service/importer/importer_service.go | 5 +- internal/service/meta/meta_service.go | 12 +++-- .../invite_answer_notification.go | 2 +- .../notification/new_answer_notification.go | 2 +- .../notification/new_comment_notification.go | 2 +- .../notification/new_question_notification.go | 2 +- .../notification/notification_service.go | 4 +- .../notification_common/notification.go | 3 ++ .../service/report_handle/report_handle.go | 6 +++ internal/service/review/review_service.go | 1 - internal/service/siteinfo/siteinfo_service.go | 4 +- internal/service/uploader/upload.go | 28 +++++++--- internal/service/user_admin/user_backyard.go | 11 ++-- .../user_notification_config_service.go | 8 +-- pkg/checker/file_type.go | 4 +- pkg/checker/password.go | 3 +- pkg/converter/markdown.go | 7 ++- pkg/htmltext/htmltext.go | 4 +- plugin/kv_storage.go | 6 +-- plugin/plugin_test/plugin_main_test.go | 2 +- ui/static.go | 1 - 56 files changed, 194 insertions(+), 214 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 263f63f70..611b49bc2 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -17,7 +17,18 @@ version: "2" linters: - default: none + exclusions: + paths: + - answer-data + - ui + - i18n + enable: + - asasalint # checks for pass []any as any in variadic func(...any) + - asciicheck # checks that your code does not contain non-ASCII identifiers + - bidichk # checks for dangerous unicode character sequences + - bodyclose # checks whether HTTP response body is closed successfully + - canonicalheader # checks whether net/http.Header uses canonical header + - copyloopvar # detects places where loop variables are copied (Go 1.22+) formatters: enable: diff --git a/cmd/wire.go b/cmd/wire.go index b25026e5b..3979ecbf5 100644 --- a/cmd/wire.go +++ b/cmd/wire.go @@ -1,5 +1,4 @@ //go:build wireinject -// +build wireinject /* * Licensed to the Apache Software Foundation (ASF) under one @@ -32,7 +31,7 @@ import ( "github.com/apache/answer/internal/base/server" "github.com/apache/answer/internal/base/translator" "github.com/apache/answer/internal/controller" - "github.com/apache/answer/internal/controller/template_render" + templaterender "github.com/apache/answer/internal/controller/template_render" "github.com/apache/answer/internal/controller_admin" "github.com/apache/answer/internal/repo" "github.com/apache/answer/internal/router" diff --git a/internal/base/conf/conf.go b/internal/base/conf/conf.go index db83862b0..04e3a19ba 100644 --- a/internal/base/conf/conf.go +++ b/internal/base/conf/conf.go @@ -117,7 +117,9 @@ func ReadConfig(configFilePath string) (c *AllConfig, err error) { func RewriteConfig(configFilePath string, allConfig *AllConfig) error { buf := bytes.Buffer{} enc := yaml.NewEncoder(&buf) - defer enc.Close() + defer func() { + _ = enc.Close() + }() enc.SetIndent(2) if err := enc.Encode(allConfig); err != nil { return err diff --git a/internal/base/constant/ctx_flag.go b/internal/base/constant/ctx_flag.go index 2a757fa87..450491bb3 100644 --- a/internal/base/constant/ctx_flag.go +++ b/internal/base/constant/ctx_flag.go @@ -23,3 +23,10 @@ const ( AcceptLanguageFlag = "Accept-Language" ShortIDFlag = "Short-ID-Enabled" ) + +type ContextKey string + +const ( + AcceptLanguageContextKey ContextKey = ContextKey(AcceptLanguageFlag) + ShortIDContextKey ContextKey = ContextKey(ShortIDFlag) +) diff --git a/internal/base/data/data.go b/internal/base/data/data.go index 1d24d7184..7696d8f56 100644 --- a/internal/base/data/data.go +++ b/internal/base/data/data.go @@ -47,7 +47,7 @@ type Data struct { func NewData(db *xorm.Engine, cache cache.Cache) (*Data, func(), error) { cleanup := func() { log.Info("closing the data resources") - db.Close() + _ = db.Close() } return &Data{DB: db, Cache: cache}, cleanup, nil } diff --git a/internal/base/handler/lang.go b/internal/base/handler/lang.go index a676e5bc2..4ff1ac7f1 100644 --- a/internal/base/handler/lang.go +++ b/internal/base/handler/lang.go @@ -38,7 +38,7 @@ func GetLang(ctx *gin.Context) i18n.Language { // GetLangByCtx get language from header func GetLangByCtx(ctx context.Context) i18n.Language { - acceptLanguage, ok := ctx.Value(constant.AcceptLanguageFlag).(i18n.Language) + acceptLanguage, ok := ctx.Value(constant.AcceptLanguageContextKey).(i18n.Language) if ok { return acceptLanguage } diff --git a/internal/base/handler/short_id.go b/internal/base/handler/short_id.go index c763bf944..8f9a2a7e5 100644 --- a/internal/base/handler/short_id.go +++ b/internal/base/handler/short_id.go @@ -27,7 +27,7 @@ import ( // GetEnableShortID get language from header func GetEnableShortID(ctx context.Context) bool { - flag, ok := ctx.Value(constant.ShortIDFlag).(bool) + flag, ok := ctx.Value(constant.ShortIDContextKey).(bool) if ok { return flag } diff --git a/internal/base/server/http_funcmap.go b/internal/base/server/http_funcmap.go index 8f6cac5fc..db4604572 100644 --- a/internal/base/server/http_funcmap.go +++ b/internal/base/server/http_funcmap.go @@ -21,7 +21,6 @@ package server import ( "html/template" - "math" "regexp" "strconv" "strings" @@ -107,15 +106,15 @@ var funcMap = template.FuncMap{ } if between >= 60 && between < 3600 { - min := math.Floor(float64(between / 60)) + min := between / 60 trans = translator.GlobalTrans.Tr(la, "ui.dates.x_minutes_ago") - return strings.ReplaceAll(trans, "{{count}}", strconv.FormatFloat(min, 'f', 0, 64)) + return strings.ReplaceAll(trans, "{{count}}", strconv.FormatInt(min, 10)) } if between >= 3600 && between < 3600*24 { - h := math.Floor(float64(between / 3600)) + h := between / 3600 trans = translator.GlobalTrans.Tr(la, "ui.dates.x_hours_ago") - return strings.ReplaceAll(trans, "{{count}}", strconv.FormatFloat(h, 'f', 0, 64)) + return strings.ReplaceAll(trans, "{{count}}", strconv.FormatInt(h, 10)) } if between >= 3600*24 && diff --git a/internal/base/validator/validator.go b/internal/base/validator/validator.go index 22761c521..9c7f6ec41 100644 --- a/internal/base/validator/validator.go +++ b/internal/base/validator/validator.go @@ -142,7 +142,7 @@ func Sanitizer(fl validator.FieldLevel) (res bool) { switch field.Kind() { case reflect.String: filter := bluemonday.UGCPolicy() - content := strings.Replace(filter.Sanitize(field.String()), "&", "&", -1) + content := strings.ReplaceAll(filter.Sanitize(field.String()), "&", "&") field.SetString(content) return true case reflect.Chan, reflect.Map, reflect.Slice, reflect.Array: diff --git a/internal/cli/build.go b/internal/cli/build.go index a5a4d938e..efc876e31 100644 --- a/internal/cli/build.go +++ b/internal/cli/build.go @@ -34,7 +34,6 @@ import ( "github.com/Masterminds/semver/v3" "github.com/apache/answer/pkg/dir" "github.com/apache/answer/pkg/writer" - "github.com/apache/answer/ui" "github.com/segmentfault/pacman/log" "gopkg.in/yaml.v3" ) @@ -300,50 +299,6 @@ func copyUIFiles(b *buildingMaterial) (err error) { return nil } -// overwriteIndexTs overwrites index.ts file in ui/src/plugins/ dir -func overwriteIndexTs(b *buildingMaterial) (err error) { - localUIPluginDir := filepath.Join(b.tmpDir, "vendor/github.com/apache/answer/ui/src/plugins/") - - folders, err := getFolders(localUIPluginDir) - if err != nil { - return fmt.Errorf("failed to get folders: %w", err) - } - - content := generateIndexTsContent(folders) - err = os.WriteFile(filepath.Join(localUIPluginDir, "index.ts"), []byte(content), 0644) - if err != nil { - return fmt.Errorf("failed to write index.ts: %w", err) - } - return nil -} - -func getFolders(dir string) ([]string, error) { - var folders []string - files, err := os.ReadDir(dir) - if err != nil { - return nil, err - } - for _, file := range files { - if file.IsDir() && file.Name() != "builtin" { - folders = append(folders, file.Name()) - } - } - return folders, nil -} - -func generateIndexTsContent(folders []string) string { - builder := &strings.Builder{} - builder.WriteString("export default null;\n") - // Line 2:1: Delete `⏎` prettier/prettier - if len(folders) > 0 { - builder.WriteString("\n") - } - for _, folder := range folders { - builder.WriteString(fmt.Sprintf("export { default as %s } from '%s';\n", folder, folder)) - } - return builder.String() -} - // buildUI run pnpm install and pnpm build commands to build ui func buildUI(b *buildingMaterial) (err error) { localUIBuildDir := filepath.Join(b.tmpDir, "vendor/github.com/apache/answer/ui") @@ -362,13 +317,6 @@ func buildUI(b *buildingMaterial) (err error) { return nil } -func replaceNecessaryFile(b *buildingMaterial) (err error) { - fmt.Printf("try to replace ui build directory\n") - uiBuildDir := filepath.Join(b.tmpDir, "vendor/github.com/apache/answer/ui") - err = copyDirEntries(ui.Build, ".", uiBuildDir) - return err -} - // mergeI18nFiles merge i18n files func mergeI18nFiles(b *buildingMaterial) (err error) { fmt.Printf("try to merge i18n files\n") diff --git a/internal/cli/config.go b/internal/cli/config.go index ecb62a13c..e2445c590 100644 --- a/internal/cli/config.go +++ b/internal/cli/config.go @@ -42,7 +42,9 @@ func SetDefaultConfig(dbConf *data.Database, cacheConf *data.CacheConf, field *C if err != nil { return err } - defer db.Close() + defer func() { + _ = db.Close() + }() cache, cacheCleanup, err := data.NewCache(cacheConf) if err != nil { @@ -50,7 +52,7 @@ func SetDefaultConfig(dbConf *data.Database, cacheConf *data.CacheConf, field *C } defer func() { if cache != nil { - cache.Flush(context.Background()) + _ = cache.Flush(context.Background()) cacheCleanup() } }() diff --git a/internal/cli/dump.go b/internal/cli/dump.go index e5d528212..e63ef1a93 100644 --- a/internal/cli/dump.go +++ b/internal/cli/dump.go @@ -34,7 +34,9 @@ func DumpAllData(dataConf *data.Database, dumpDataPath string) error { if err != nil { return err } - defer db.Close() + defer func() { + _ = db.Close() + }() if err = db.Ping(); err != nil { return err } diff --git a/internal/cli/install_check.go b/internal/cli/install_check.go index 9326e069f..c3fadcaba 100644 --- a/internal/cli/install_check.go +++ b/internal/cli/install_check.go @@ -43,7 +43,9 @@ func CheckDBConnection(dataConf *data.Database) bool { fmt.Printf("connection database failed: %s\n", err) return false } - defer db.Close() + defer func() { + _ = db.Close() + }() if err = db.Ping(); err != nil { fmt.Printf("connection ping database failed: %s\n", err) return false @@ -59,7 +61,9 @@ func CheckDBTableExist(dataConf *data.Database) bool { fmt.Printf("connection database failed: %s\n", err) return false } - defer db.Close() + defer func() { + _ = db.Close() + }() if err = db.Ping(); err != nil { fmt.Printf("connection ping database failed: %s\n", err) return false diff --git a/internal/cli/reset_password.go b/internal/cli/reset_password.go index 2a7d1af4c..dbb3422af 100644 --- a/internal/cli/reset_password.go +++ b/internal/cli/reset_password.go @@ -77,7 +77,9 @@ func ResetPassword(ctx context.Context, dataDirPath string, opts *ResetPasswordO if err != nil { return fmt.Errorf("connect database failed: %w", err) } - defer db.Close() + defer func() { + _ = db.Close() + }() cache, cacheCleanup, err := data.NewCache(config.Data.Cache) if err != nil { diff --git a/internal/controller/template_controller.go b/internal/controller/template_controller.go index 83cd58c32..801e129c2 100644 --- a/internal/controller/template_controller.go +++ b/internal/controller/template_controller.go @@ -162,11 +162,9 @@ func (tc *TemplateController) Index(ctx *gin.Context) { siteInfo := tc.SiteInfo(ctx) siteInfo.Canonical = siteInfo.General.SiteUrl - UrlUseTitle := false - if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle || - siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID { - UrlUseTitle = true - } + UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle || + siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID + siteInfo.Title = "" tc.html(ctx, http.StatusOK, "question.html", siteInfo, gin.H{ "data": data, @@ -205,11 +203,9 @@ func (tc *TemplateController) QuestionList(ctx *gin.Context) { siteInfo.Canonical = fmt.Sprintf("%s/questions?page=%d", siteInfo.General.SiteUrl, page) } - UrlUseTitle := false - if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle || - siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID { - UrlUseTitle = true - } + UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle || + siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID + siteInfo.Title = fmt.Sprintf("%s - %s", translator.Tr(handler.GetLang(ctx), constant.QuestionsTitleTrKey), siteInfo.General.Name) tc.html(ctx, http.StatusOK, "question.html", siteInfo, gin.H{ "data": data, @@ -371,11 +367,8 @@ func (tc *TemplateController) QuestionInfo(ctx *gin.Context) { return } - UrlUseTitle := false - if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle || - siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID { - UrlUseTitle = true - } + UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle || + siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID //related question userID := middleware.GetLoginUserIDFromContext(ctx) @@ -434,7 +427,7 @@ func (tc *TemplateController) QuestionInfo(ctx *gin.Context) { for _, tag := range detail.Tags { tags = append(tags, tag.DisplayName) } - siteInfo.Keywords = strings.Replace(strings.Trim(fmt.Sprint(tags), "[]"), " ", ",", -1) + siteInfo.Keywords = strings.ReplaceAll(strings.Trim(fmt.Sprint(tags), "[]"), " ", ",") siteInfo.Title = fmt.Sprintf("%s - %s", detail.Title, siteInfo.General.Name) tc.html(ctx, http.StatusOK, "question-detail.html", siteInfo, gin.H{ "id": id, @@ -504,11 +497,9 @@ func (tc *TemplateController) TagInfo(ctx *gin.Context) { } siteInfo.Keywords = tagInfo.DisplayName - UrlUseTitle := false - if siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle || - siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID { - UrlUseTitle = true - } + UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle || + siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID + siteInfo.Title = fmt.Sprintf("'%s' %s - %s", tagInfo.DisplayName, translator.Tr(handler.GetLang(ctx), constant.QuestionsTitleTrKey), siteInfo.General.Name) tc.html(ctx, http.StatusOK, "tag-detail.html", siteInfo, gin.H{ "tag": tagInfo, @@ -570,11 +561,9 @@ func (tc *TemplateController) Page404(ctx *gin.Context) { } func (tc *TemplateController) html(ctx *gin.Context, code int, tpl string, siteInfo *schema.TemplateSiteInfoResp, data gin.H) { - var ( - prefix = "" - cssPath = "" - scriptPath = make([]string, len(tc.scriptPath)) - ) + prefix := "" + cssPath := "" + scriptPath := make([]string, len(tc.scriptPath)) _ = plugin.CallCDN(func(fn plugin.CDN) error { prefix = fn.GetStaticPrefix() @@ -612,7 +601,7 @@ func (tc *TemplateController) html(ctx *gin.Context, code int, tpl string, siteI data["description"] = siteInfo.Description data["language"] = handler.GetLang(ctx) data["timezone"] = siteInfo.Interface.TimeZone - language := strings.Replace(siteInfo.Interface.Language, "_", "-", -1) + language := strings.ReplaceAll(siteInfo.Interface.Language, "_", "-") data["lang"] = language data["HeadCode"] = siteInfo.CustomCssHtml.CustomHead data["HeaderCode"] = siteInfo.CustomCssHtml.CustomHeader diff --git a/internal/controller/template_render/controller.go b/internal/controller/template_render/controller.go index 5f802fa76..3412010db 100644 --- a/internal/controller/template_render/controller.go +++ b/internal/controller/template_render/controller.go @@ -101,7 +101,6 @@ func Paginator(page, pageSize int, nums int64) *schema.Paginator { case page >= 3 && totalpages > 5: start := page - 3 + 1 pages = make([]int, 5) - prevpage = page - 3 for i := range pages { pages[i] = start + i } diff --git a/internal/controller/user_controller.go b/internal/controller/user_controller.go index 49b9b23c6..e4a3b3d3b 100644 --- a/internal/controller/user_controller.go +++ b/internal/controller/user_controller.go @@ -151,7 +151,7 @@ func (uc *UserController) UserEmailLogin(ctx *gin.Context) { resp, err := uc.userService.EmailLogin(ctx, req) if err != nil { - _, _ = uc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionPassword, ctx.ClientIP()) + uc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionPassword, ctx.ClientIP()) errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "e_mail", ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.EmailOrPasswordWrong), @@ -404,10 +404,7 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) { handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return } - _, err := uc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionEditUserinfo, req.UserID) - if err != nil { - log.Error(err) - } + uc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionEditUserinfo, req.UserID) } oldPassVerification, err := uc.userService.UserModifyPassWordVerification(ctx, req) diff --git a/internal/install/install_from_env.go b/internal/install/install_from_env.go index c05d2aaba..02bc76381 100644 --- a/internal/install/install_from_env.go +++ b/internal/install/install_from_env.go @@ -22,6 +22,7 @@ package install import ( "bytes" "encoding/json" + "errors" "fmt" "net/http" "net/http/httptest" @@ -143,7 +144,7 @@ func requestAPI(req any, method, url string, handlerFunc gin.HandlerFunc) error } handlerFunc(c) if w.Code != http.StatusOK { - return fmt.Errorf(gjson.Get(w.Body.String(), "msg").String()) + return errors.New(gjson.Get(w.Body.String(), "msg").String()) } return nil } diff --git a/internal/migrations/migrations.go b/internal/migrations/migrations.go index 9caa28ed1..2fbfbb7fd 100644 --- a/internal/migrations/migrations.go +++ b/internal/migrations/migrations.go @@ -147,7 +147,9 @@ func Migrate(debug bool, dbConf *data.Database, cacheConf *data.CacheConf, upgra fmt.Println("new database failed: ", err.Error()) return err } - defer engine.Close() + defer func() { + _ = engine.Close() + }() currentDBVersion, err := GetCurrentDBVersion(engine) if err != nil { diff --git a/internal/migrations/v22.go b/internal/migrations/v22.go index e7177deae..5367f5d46 100644 --- a/internal/migrations/v22.go +++ b/internal/migrations/v22.go @@ -61,6 +61,9 @@ func addBadges(ctx context.Context, x *xorm.Engine) (err error) { if exist { badge.ID = beans.ID _, err = x.Context(ctx).ID(beans.ID).Update(badge) + if err != nil { + return fmt.Errorf("update badge failed: %w", err) + } continue } badge.ID, err = uniqueIDRepo.GenUniqueIDStr(ctx, new(entity.Badge).TableName()) diff --git a/internal/migrations/v24.go b/internal/migrations/v24.go index a488679f6..86d624254 100644 --- a/internal/migrations/v24.go +++ b/internal/migrations/v24.go @@ -66,8 +66,5 @@ func addQuestionLinkedCount(ctx context.Context, x *xorm.Engine) error { } } - type Question struct { - LinkedCount int `xorm:"not null default 0 INT(11) linked_count"` - } return x.Context(ctx).Sync(new(entity.Question)) } diff --git a/internal/repo/answer/answer_repo.go b/internal/repo/answer/answer_repo.go index c5447befc..0f1ae8146 100644 --- a/internal/repo/answer/answer_repo.go +++ b/internal/repo/answer/answer_repo.go @@ -503,6 +503,7 @@ func (ar *answerRepo) updateSearch(ctx context.Context, answerID string) (err er err = st.Find(&tagListList) if err != nil { err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + return } for _, tag := range tagListList { tags = append(tags, tag.TagID) diff --git a/internal/repo/plugin_config/plugin_user_config_repo.go b/internal/repo/plugin_config/plugin_user_config_repo.go index d14442a56..df5ae29b8 100644 --- a/internal/repo/plugin_config/plugin_user_config_repo.go +++ b/internal/repo/plugin_config/plugin_user_config_repo.go @@ -71,7 +71,7 @@ func (ur *pluginUserConfigRepo) SaveUserPluginConfig(ctx context.Context, userID return nil, nil }) if err != nil { - err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() } return nil } diff --git a/internal/repo/repo_test/repo_main_test.go b/internal/repo/repo_test/repo_main_test.go index a59ae6269..919ca94e8 100644 --- a/internal/repo/repo_test/repo_main_test.go +++ b/internal/repo/repo_test/repo_main_test.go @@ -77,7 +77,7 @@ func TestMain(t *testing.M) { dbSetting = dbSettingMapping[string(schemas.SQLITE)] } if dbSetting.Driver == string(schemas.SQLITE) { - os.RemoveAll(dbSetting.Connection) + _ = os.RemoveAll(dbSetting.Connection) } defer func() { diff --git a/internal/repo/tag/tag_rel_repo.go b/internal/repo/tag/tag_rel_repo.go index 3634c97a7..a52b1bf54 100644 --- a/internal/repo/tag/tag_rel_repo.go +++ b/internal/repo/tag/tag_rel_repo.go @@ -198,6 +198,7 @@ func (tr *tagRelRepo) GetTagRelDefaultStatusByObjectID(ctx context.Context, obje exist, err := tr.data.DB.Context(ctx).ID(objectID).Cols("show", "status").Get(&question) if err != nil { err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + return } if exist && (question.Show == entity.QuestionHide || question.Status == entity.QuestionStatusDeleted) { return entity.TagRelStatusHide, nil diff --git a/internal/service/action/captcha_service.go b/internal/service/action/captcha_service.go index 04f8b16ac..aefb70519 100644 --- a/internal/service/action/captcha_service.go +++ b/internal/service/action/captcha_service.go @@ -106,11 +106,11 @@ func (cs *CaptchaService) ActionRecordVerifyCaptcha( return pass } -func (cs *CaptchaService) ActionRecordAdd(ctx context.Context, actionType string, unit string) (int, error) { +func (cs *CaptchaService) ActionRecordAdd(ctx context.Context, actionType string, unit string) { info, err := cs.captchaRepo.GetActionType(ctx, unit, actionType) if err != nil { log.Error(err) - return 0, err + return } amount := 1 if info != nil { @@ -118,9 +118,8 @@ func (cs *CaptchaService) ActionRecordAdd(ctx context.Context, actionType string } err = cs.captchaRepo.SetActionType(ctx, unit, actionType, "", amount) if err != nil { - return 0, err + log.Error(err) } - return amount, nil } func (cs *CaptchaService) ActionRecordDel(ctx context.Context, actionType string, unit string) { diff --git a/internal/service/action/captcha_strategy.go b/internal/service/action/captcha_strategy.go index 3befda821..b423b583b 100644 --- a/internal/service/action/captcha_strategy.go +++ b/internal/service/action/captcha_strategy.go @@ -89,7 +89,9 @@ func (cs *CaptchaService) CaptchaActionPassword(ctx context.Context, unit string return false } if now-actionInfo.LastTime != 0 && now-actionInfo.LastTime > setTime { - cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionPassword, "", 0) + if err := cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionPassword, "", 0); err != nil { + log.Error(err) + } } return true } @@ -105,7 +107,9 @@ func (cs *CaptchaService) CaptchaActionEditUserinfo(ctx context.Context, unit st return false } if now-actionInfo.LastTime != 0 && now-actionInfo.LastTime > setTime { - cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionEditUserinfo, "", 0) + if err := cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionEditUserinfo, "", 0); err != nil { + log.Error(err) + } } return true } @@ -154,10 +158,7 @@ func (cs *CaptchaService) CaptchaActionEdit(ctx context.Context, unit string, ac return true } setNum := 10 - if actionInfo.Num >= setNum { - return false - } - return true + return actionInfo.Num < setNum } func (cs *CaptchaService) CaptchaActionInvitationAnswer(ctx context.Context, unit string, actionInfo *entity.ActionRecordInfo) bool { @@ -165,10 +166,7 @@ func (cs *CaptchaService) CaptchaActionInvitationAnswer(ctx context.Context, uni return true } setNum := 30 - if actionInfo.Num >= setNum { - return false - } - return true + return actionInfo.Num < setNum } func (cs *CaptchaService) CaptchaActionSearch(ctx context.Context, unit string, actionInfo *entity.ActionRecordInfo) bool { @@ -182,7 +180,9 @@ func (cs *CaptchaService) CaptchaActionSearch(ctx context.Context, unit string, return false } if now-actionInfo.LastTime > setTime { - cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionSearch, "", 0) + if err := cs.captchaRepo.SetActionType(ctx, unit, entity.CaptchaActionSearch, "", 0); err != nil { + log.Error(err) + } } return true } @@ -218,8 +218,5 @@ func (cs *CaptchaService) CaptchaActionVote(ctx context.Context, unit string, ac return true } setNum := 40 - if actionInfo.Num >= setNum { - return false - } - return true + return actionInfo.Num < setNum } diff --git a/internal/service/badge/badge_event_handler.go b/internal/service/badge/badge_event_handler.go index cc161f6ad..24cabf29b 100644 --- a/internal/service/badge/badge_event_handler.go +++ b/internal/service/badge/badge_event_handler.go @@ -32,7 +32,6 @@ import ( type BadgeEventService struct { data *data.Data eventQueueService event_queue.EventQueueService - badgeAwardRepo BadgeAwardRepo badgeRepo BadgeRepo eventRuleRepo EventRuleRepo badgeAwardService *BadgeAwardService diff --git a/internal/service/badge/badge_service.go b/internal/service/badge/badge_service.go index 03b8a8774..ebb90450a 100644 --- a/internal/service/badge/badge_service.go +++ b/internal/service/badge/badge_service.go @@ -206,10 +206,8 @@ func (b *BadgeService) ListPaged(ctx context.Context, req *schema.GetBadgeListPa resp = make([]*schema.GetBadgeListPagedResp, len(badges)) general, siteErr := b.siteInfoCommonService.GetSiteGeneral(ctx) - var baseURL = "" - if siteErr != nil { - baseURL = "" - } else { + baseURL := "" + if siteErr == nil { baseURL = general.SiteUrl } @@ -246,31 +244,23 @@ func (b *BadgeService) searchByName(ctx context.Context, name string) (result [] // GetBadgeInfo get badge info func (b *BadgeService) GetBadgeInfo(ctx *gin.Context, id string, userID string) (info *schema.GetBadgeInfoResp, err error) { - var ( - badge *entity.Badge - earnedTotal int64 = 0 - exists = false - ) - - badge, exists, err = b.badgeRepo.GetByID(ctx, id) + badge, exists, err := b.badgeRepo.GetByID(ctx, id) if err != nil { - return + return nil, err } if !exists || badge.Status == entity.BadgeStatusInactive { - err = errors.BadRequest(reason.BadgeObjectNotFound) - return + return nil, errors.BadRequest(reason.BadgeObjectNotFound) } + var earnedTotal int64 if len(userID) > 0 { earnedTotal = b.badgeAwardRepo.CountByUserIdAndBadgeId(ctx, userID, badge.ID) } + baseURL := "" general, siteErr := b.siteInfoCommonService.GetSiteGeneral(ctx) - var baseURL = "" - if siteErr != nil { - baseURL = "" - } else { + if siteErr == nil { baseURL = general.SiteUrl } diff --git a/internal/service/content/question_service.go b/internal/service/content/question_service.go index 1d1d1af39..da15fae5d 100644 --- a/internal/service/content/question_service.go +++ b/internal/service/content/question_service.go @@ -277,7 +277,7 @@ func (qs *QuestionService) CheckAddQuestion(ctx context.Context, req *schema.Que if tagerr != nil { return errorlist, tagerr } - if !req.QuestionPermission.CanUseReservedTag { + if !req.CanUseReservedTag { taglist, err := qs.AddQuestionCheckTags(ctx, Tags) errMsg := fmt.Sprintf(`"%s" can only be used by moderators.`, strings.Join(taglist, ",")) @@ -350,7 +350,7 @@ func (qs *QuestionService) AddQuestion(ctx context.Context, req *schema.Question if tagerr != nil { return questionInfo, tagerr } - if !req.QuestionPermission.CanUseReservedTag { + if !req.CanUseReservedTag { taglist, err := qs.AddQuestionCheckTags(ctx, tags) errMsg := fmt.Sprintf(`"%s" can only be used by moderators.`, strings.Join(taglist, ",")) @@ -1397,13 +1397,17 @@ func (qs *QuestionService) GetQuestionsByTitle(ctx context.Context, title string for _, question := range res { questionIDs = append(questionIDs, question.ID) } - questions, err = qs.questionRepo.FindByID(ctx, questionIDs) + var questionErr error + questions, questionErr = qs.questionRepo.FindByID(ctx, questionIDs) + if questionErr != nil { + return resp, questionErr + } } else { - questions, err = qs.questionRepo.GetQuestionsByTitle(ctx, title, 10) - } - - if err != nil { - return resp, err + var questionErr error + questions, questionErr = qs.questionRepo.GetQuestionsByTitle(ctx, title, 10) + if questionErr != nil { + return resp, questionErr + } } for _, question := range questions { item := &schema.QuestionBaseInfo{} @@ -1723,7 +1727,7 @@ func (qs *QuestionService) SitemapCron(ctx context.Context) { log.Error(err) return } - ctx = context.WithValue(ctx, constant.ShortIDFlag, siteSeo.IsShortLink()) + ctx = context.WithValue(ctx, constant.ShortIDContextKey, siteSeo.IsShortLink()) qs.questioncommon.SitemapCron(ctx) } diff --git a/internal/service/content/revision_service.go b/internal/service/content/revision_service.go index 1aed4cf82..a5cefeb41 100644 --- a/internal/service/content/revision_service.go +++ b/internal/service/content/revision_service.go @@ -41,7 +41,6 @@ import ( "github.com/apache/answer/internal/service/review" "github.com/apache/answer/internal/service/revision" "github.com/apache/answer/internal/service/tag_common" - tagcommon "github.com/apache/answer/internal/service/tag_common" usercommon "github.com/apache/answer/internal/service/user_common" "github.com/apache/answer/pkg/converter" "github.com/apache/answer/pkg/htmltext" @@ -62,7 +61,7 @@ type RevisionService struct { questionRepo questioncommon.QuestionRepo answerRepo answercommon.AnswerRepo tagRepo tag_common.TagRepo - tagCommon *tagcommon.TagCommonService + tagCommon *tag_common.TagCommonService notificationQueueService notice_queue.NotificationQueueService activityQueueService activity_queue.ActivityQueueService reportRepo report_common.ReportRepo @@ -79,7 +78,7 @@ func NewRevisionService( questionRepo questioncommon.QuestionRepo, answerRepo answercommon.AnswerRepo, tagRepo tag_common.TagRepo, - tagCommon *tagcommon.TagCommonService, + tagCommon *tag_common.TagCommonService, notificationQueueService notice_queue.NotificationQueueService, activityQueueService activity_queue.ActivityQueueService, reportRepo report_common.ReportRepo, diff --git a/internal/service/content/search_service.go b/internal/service/content/search_service.go index 98add0938..ccafcd82c 100644 --- a/internal/service/content/search_service.go +++ b/internal/service/content/search_service.go @@ -93,6 +93,9 @@ func (ss *SearchService) searchByPlugin(ctx context.Context, finder plugin.Searc } else if cond.SearchAnswer() { res, resp.Total, err = finder.SearchAnswers(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order)) } + if err != nil { + return resp, err + } resp.SearchResults, err = ss.searchRepo.ParseSearchPluginResult(ctx, res, cond.Words) return resp, err diff --git a/internal/service/content/vote_service.go b/internal/service/content/vote_service.go index 92f0c9962..aa6150497 100644 --- a/internal/service/content/vote_service.go +++ b/internal/service/content/vote_service.go @@ -26,8 +26,6 @@ import ( "github.com/apache/answer/internal/service/event_queue" - "github.com/apache/answer/internal/service/activity_common" - "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/pager" @@ -64,7 +62,6 @@ type VoteService struct { answerRepo answercommon.AnswerRepo commentCommonRepo comment_common.CommentCommonRepo objectService *object_info.ObjService - activityRepo activity_common.ActivityRepo eventQueueService event_queue.EventQueueService } diff --git a/internal/service/dashboard/dashboard_service.go b/internal/service/dashboard/dashboard_service.go index d9198e6db..91f0e338a 100644 --- a/internal/service/dashboard/dashboard_service.go +++ b/internal/service/dashboard/dashboard_service.go @@ -274,7 +274,9 @@ func (ds *dashboardService) remoteVersion(ctx context.Context) string { log.Errorf("request remote version failed: %s", err) return "" } - defer resp.Body.Close() + defer func() { + _ = resp.Body.Close() + }() respByte, err := io.ReadAll(resp.Body) if err != nil { @@ -358,7 +360,7 @@ func (ds *dashboardService) GetDatabaseSize() (dbSize string) { if err != nil { log.Warnf("get db size failed: %s", err) } else { - if res != nil && len(res) > 0 && res[0]["db_size"] != nil { + if len(res) > 0 && res[0]["db_size"] != nil { dbSizeStr, _ := res[0]["db_size"].(string) dbSize = dir.FormatFileSize(converter.StringToInt64(dbSizeStr)) } @@ -370,7 +372,7 @@ func (ds *dashboardService) GetDatabaseSize() (dbSize string) { if err != nil { log.Warnf("get db size failed: %s", err) } else { - if res != nil && len(res) > 0 && res[0]["db_size"] != nil { + if len(res) > 0 && res[0]["db_size"] != nil { dbSizeStr, _ := res[0]["db_size"].(int32) dbSize = dir.FormatFileSize(int64(dbSizeStr)) } diff --git a/internal/service/file_record/file_record_service.go b/internal/service/file_record/file_record_service.go index 29097ba8c..aa526f014 100644 --- a/internal/service/file_record/file_record_service.go +++ b/internal/service/file_record/file_record_service.go @@ -174,7 +174,6 @@ func (fs *FileRecordService) PurgeDeletedFiles(ctx context.Context) { if err != nil { log.Errorf("create deleted directory error: %v", err) } - return } func (fs *FileRecordService) DeleteAndMoveFileRecord(ctx context.Context, fileRecord *entity.FileRecord) error { diff --git a/internal/service/importer/importer_service.go b/internal/service/importer/importer_service.go index 45aabf39b..c7673ffb5 100644 --- a/internal/service/importer/importer_service.go +++ b/internal/service/importer/importer_service.go @@ -62,8 +62,7 @@ type ImporterFunc struct { } func (ipfunc *ImporterFunc) AddQuestion(ctx context.Context, questionInfo plugin.QuestionImporterInfo) (err error) { - ipfunc.importerService.ImportQuestion(ctx, questionInfo) - return nil + return ipfunc.importerService.ImportQuestion(ctx, questionInfo) } func (ip *ImporterService) NewImporterFunc() plugin.ImporterFunc { @@ -84,7 +83,7 @@ func (ip *ImporterService) ImportQuestion(ctx context.Context, questionInfo plug return err } if !exist { - return fmt.Errorf("User not found") + return fmt.Errorf("user not found") } // To limit rate, remove the following code from comment: Part 2/2 diff --git a/internal/service/meta/meta_service.go b/internal/service/meta/meta_service.go index 4b3104197..c1ca7c619 100644 --- a/internal/service/meta/meta_service.go +++ b/internal/service/meta/meta_service.go @@ -97,7 +97,8 @@ func (ms *MetaService) AddOrUpdateReaction(ctx context.Context, req *schema.Upda return nil, err } var event *schema.EventMsg - if objectType == constant.AnswerObjectType { + switch objectType { + case constant.AnswerObjectType: answerInfo, exist, err := ms.answerRepo.GetAnswer(ctx, req.ObjectID) if err != nil { return nil, err @@ -107,7 +108,7 @@ func (ms *MetaService) AddOrUpdateReaction(ctx context.Context, req *schema.Upda } event = schema.NewEvent(constant.EventAnswerReact, req.UserID).TID(answerInfo.ID). AID(answerInfo.ID, answerInfo.UserID) - } else if objectType == constant.QuestionObjectType { + case constant.QuestionObjectType: questionInfo, exist, err := ms.questionRepo.GetQuestion(ctx, req.ObjectID) if err != nil { return nil, err @@ -117,7 +118,7 @@ func (ms *MetaService) AddOrUpdateReaction(ctx context.Context, req *schema.Upda } event = schema.NewEvent(constant.EventQuestionReact, req.UserID).TID(questionInfo.ID). QID(questionInfo.ID, questionInfo.UserID) - } else { + default: return nil, myErrors.BadRequest(reason.ObjectNotFound) } @@ -159,9 +160,10 @@ func (ms *MetaService) AddOrUpdateReaction(ctx context.Context, req *schema.Upda // updateReaction update reaction func (ms *MetaService) updateReaction(req *schema.UpdateReactionReq, reactions *schema.ReactionsSummaryMeta) { - if req.Reaction == "activate" { + switch req.Reaction { + case "activate": reactions.AddReactionSummary(req.Emoji, req.UserID) - } else if req.Reaction == "deactivate" { + case "deactivate": reactions.RemoveReactionSummary(req.Emoji, req.UserID) } } diff --git a/internal/service/notification/invite_answer_notification.go b/internal/service/notification/invite_answer_notification.go index 4e7c051cd..f68feb067 100644 --- a/internal/service/notification/invite_answer_notification.go +++ b/internal/service/notification/invite_answer_notification.go @@ -70,7 +70,7 @@ func (ns *ExternalNotificationService) sendInviteAnswerNotificationEmail(ctx con // If receiver has set language, use it to send email. if len(lang) > 0 { - ctx = context.WithValue(ctx, constant.AcceptLanguageFlag, i18n.Language(lang)) + ctx = context.WithValue(ctx, constant.AcceptLanguageContextKey, i18n.Language(lang)) } title, body, err := ns.emailService.NewInviteAnswerTemplate(ctx, rawData) if err != nil { diff --git a/internal/service/notification/new_answer_notification.go b/internal/service/notification/new_answer_notification.go index 91b7e2ae3..c54fd961c 100644 --- a/internal/service/notification/new_answer_notification.go +++ b/internal/service/notification/new_answer_notification.go @@ -70,7 +70,7 @@ func (ns *ExternalNotificationService) sendNewAnswerNotificationEmail(ctx contex // If receiver has set language, use it to send email. if len(lang) > 0 { - ctx = context.WithValue(ctx, constant.AcceptLanguageFlag, i18n.Language(lang)) + ctx = context.WithValue(ctx, constant.AcceptLanguageContextKey, i18n.Language(lang)) } title, body, err := ns.emailService.NewAnswerTemplate(ctx, rawData) if err != nil { diff --git a/internal/service/notification/new_comment_notification.go b/internal/service/notification/new_comment_notification.go index 3ec99d13c..e622ed4f7 100644 --- a/internal/service/notification/new_comment_notification.go +++ b/internal/service/notification/new_comment_notification.go @@ -69,7 +69,7 @@ func (ns *ExternalNotificationService) sendNewCommentNotificationEmail(ctx conte } // If receiver has set language, use it to send email. if len(lang) > 0 { - ctx = context.WithValue(ctx, constant.AcceptLanguageFlag, i18n.Language(lang)) + ctx = context.WithValue(ctx, constant.AcceptLanguageContextKey, i18n.Language(lang)) } title, body, err := ns.emailService.NewCommentTemplate(ctx, rawData) if err != nil { diff --git a/internal/service/notification/new_question_notification.go b/internal/service/notification/new_question_notification.go index 8a12d0b8c..debfb8c27 100644 --- a/internal/service/notification/new_question_notification.go +++ b/internal/service/notification/new_question_notification.go @@ -176,7 +176,7 @@ func (ns *ExternalNotificationService) sendNewQuestionNotificationEmail(ctx cont } // If receiver has set language, use it to send email. if len(userInfo.Language) > 0 { - ctx = context.WithValue(ctx, constant.AcceptLanguageFlag, i18n.Language(userInfo.Language)) + ctx = context.WithValue(ctx, constant.AcceptLanguageContextKey, i18n.Language(userInfo.Language)) } title, body, err := ns.emailService.NewQuestionTemplate(ctx, rawData) if err != nil { diff --git a/internal/service/notification/notification_service.go b/internal/service/notification/notification_service.go index 09d871351..0369d4557 100644 --- a/internal/service/notification/notification_service.go +++ b/internal/service/notification/notification_service.go @@ -82,8 +82,8 @@ func (ns *NotificationService) GetRedDot(ctx context.Context, req *schema.GetRed achievementKey := fmt.Sprintf(constant.RedDotCacheKey, constant.NotificationTypeAchievement, req.UserID) redBot := &schema.RedDot{} - redBot.Inbox, _, err = ns.data.Cache.GetInt64(ctx, inboxKey) - redBot.Achievement, _, err = ns.data.Cache.GetInt64(ctx, achievementKey) + redBot.Inbox, _, _ = ns.data.Cache.GetInt64(ctx, inboxKey) + redBot.Achievement, _, _ = ns.data.Cache.GetInt64(ctx, achievementKey) // get review amount if req.CanReviewAnswer || req.CanReviewQuestion || req.CanReviewTag { diff --git a/internal/service/notification_common/notification.go b/internal/service/notification_common/notification.go index 2bceb6298..55d638424 100644 --- a/internal/service/notification_common/notification.go +++ b/internal/service/notification_common/notification.go @@ -206,6 +206,9 @@ func (ns *NotificationCommon) AddNotification(ctx context.Context, msg *schema.N } if req.ObjectInfo.ObjectType == constant.BadgeAwardObjectType { err = ns.AddBadgeAwardAlertCache(ctx, info.UserID, info.ID, req.ObjectInfo.ObjectMap["badge_id"]) + if err != nil { + log.Error("AddBadgeAwardAlertCache Error", err.Error()) + } } go ns.SendNotificationToAllFollower(ctx, msg, questionID) diff --git a/internal/service/report_handle/report_handle.go b/internal/service/report_handle/report_handle.go index 27cffb111..a04681663 100644 --- a/internal/service/report_handle/report_handle.go +++ b/internal/service/report_handle/report_handle.go @@ -112,6 +112,9 @@ func (rh *ReportHandle) updateReportedAnswerReport(ctx context.Context, report * NoNeedReview: true, }) } + if err != nil { + return err + } return nil } @@ -128,5 +131,8 @@ func (rh *ReportHandle) updateReportedCommentReport(ctx context.Context, report UserID: req.UserID, }) } + if err != nil { + return err + } return nil } diff --git a/internal/service/review/review_service.go b/internal/service/review/review_service.go index 40089fb2d..a23b9ee43 100644 --- a/internal/service/review/review_service.go +++ b/internal/service/review/review_service.go @@ -469,7 +469,6 @@ func (cs *ReviewService) notificationCommentOnTheQuestion(ctx context.Context, c cs.notificationAnswerComment(ctx, objInfo.QuestionID, objInfo.Title, objInfo.AnswerID, objInfo.ObjectCreatorUserID, comment.ID, comment.UserID, htmltext.FetchExcerpt(comment.ParsedText, "...", 240)) } - return } func (cs *ReviewService) notificationCommentReply(ctx context.Context, replyUserID, commentID, commentUserID, diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index cf43d68d5..f355d09f4 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -345,7 +345,7 @@ func (s *SiteInfoService) GetPrivilegesConfig(ctx context.Context) (resp *schema return nil, err } privilegeOptions := schema.DefaultPrivilegeOptions - if privilege.CustomPrivileges != nil && len(privilege.CustomPrivileges) > 0 { + if len(privilege.CustomPrivileges) > 0 { privilegeOptions = append(privilegeOptions, &schema.PrivilegeOption{ Level: schema.PrivilegeLevelCustom, LevelDesc: reason.PrivilegeLevelCustomDesc, @@ -358,7 +358,7 @@ func (s *SiteInfoService) GetPrivilegesConfig(ctx context.Context) (resp *schema Options: s.translatePrivilegeOptions(ctx, privilegeOptions), SelectedLevel: schema.PrivilegeLevel3, } - if privilege != nil && privilege.Level > 0 { + if privilege.Level > 0 { resp.SelectedLevel = privilege.Level } return resp, nil diff --git a/internal/service/uploader/upload.go b/internal/service/uploader/upload.go index 2ae5369df..30029193b 100644 --- a/internal/service/uploader/upload.go +++ b/internal/service/uploader/upload.go @@ -119,7 +119,9 @@ func (us *uploaderService) UploadAvatarFile(ctx *gin.Context, userID string) (ur if err != nil { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) } - file.Close() + defer func() { + _ = file.Close() + }() fileExt := strings.ToLower(path.Ext(fileHeader.Filename)) if _, ok := plugin.DefaultFileTypeCheckMapping[plugin.UserAvatar][fileExt]; !ok { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) @@ -148,12 +150,12 @@ func (us *uploaderService) AvatarThumbFile(ctx *gin.Context, fileName string, si thumbFileName := fmt.Sprintf("%d_%d@%s", size, size, fileName) thumbFilePath := fmt.Sprintf("%s/%s/%s", us.serviceConfig.UploadPath, constant.AvatarThumbSubPath, thumbFileName) - avatarFile, err := os.ReadFile(thumbFilePath) + _, err = os.ReadFile(thumbFilePath) if err == nil { return thumbFilePath, nil } filePath := fmt.Sprintf("%s/%s/%s", us.serviceConfig.UploadPath, constant.AvatarSubPath, fileName) - avatarFile, err = os.ReadFile(filePath) + avatarFile, err := os.ReadFile(filePath) if err != nil { return "", errors.NotFound(reason.UnknownError).WithError(err) } @@ -179,7 +181,9 @@ func (us *uploaderService) AvatarThumbFile(ctx *gin.Context, fileName string, si if err != nil { return "", errors.InternalServer(reason.UnknownError).WithError(err).WithStack() } - defer out.Close() + defer func() { + _ = out.Close() + }() thumbReader := bytes.NewReader(buf.Bytes()) if _, err = io.Copy(out, thumbReader); err != nil { @@ -208,7 +212,9 @@ func (us *uploaderService) UploadPostFile(ctx *gin.Context, userID string) ( if err != nil { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) } - defer file.Close() + defer func() { + _ = file.Close() + }() if checker.IsUnAuthorizedExtension(fileHeader.Filename, siteWrite.AuthorizedImageExtensions) { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) } @@ -244,7 +250,9 @@ func (us *uploaderService) UploadPostAttachment(ctx *gin.Context, userID string) if err != nil { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) } - defer file.Close() + defer func() { + _ = file.Close() + }() if checker.IsUnAuthorizedExtension(fileHeader.Filename, resp.AuthorizedAttachmentExtensions) { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) } @@ -280,7 +288,9 @@ func (us *uploaderService) UploadBrandingFile(ctx *gin.Context, userID string) ( if err != nil { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) } - file.Close() + defer func() { + _ = file.Close() + }() fileExt := strings.ToLower(path.Ext(fileHeader.Filename)) if _, ok := plugin.DefaultFileTypeCheckMapping[plugin.AdminBranding][fileExt]; !ok { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) @@ -316,7 +326,9 @@ func (us *uploaderService) uploadImageFile(ctx *gin.Context, file *multipart.Fil if err != nil { return "", errors.InternalServer(reason.UnknownError).WithError(err).WithStack() } - defer src.Close() + defer func() { + _ = src.Close() + }() if !checker.DecodeAndCheckImageFile(filePath, siteWrite.GetMaxImageMegapixel()) { return "", errors.BadRequest(reason.UploadFileUnsupportedFileFormat) diff --git a/internal/service/user_admin/user_backyard.go b/internal/service/user_admin/user_backyard.go index 0f6ec81ed..6fce161ce 100644 --- a/internal/service/user_admin/user_backyard.go +++ b/internal/service/user_admin/user_backyard.go @@ -400,7 +400,7 @@ func (us *UserAdminService) EditUserProfile(ctx context.Context, req *schema.Edi if req.UserID == req.LoginUserID { return nil, errors.BadRequest(reason.AdminCannotEditTheirProfile) } - userInfo, exist, err := us.userRepo.GetUserInfo(ctx, req.UserID) + _, exist, err := us.userRepo.GetUserInfo(ctx, req.UserID) if err != nil { return nil, err } @@ -415,7 +415,7 @@ func (us *UserAdminService) EditUserProfile(ctx context.Context, req *schema.Edi }), errors.BadRequest(reason.UsernameInvalid) } - userInfo, exist, err = us.userCommonService.GetByUsername(ctx, req.Username) + userInfo, exist, err := us.userCommonService.GetByUsername(ctx, req.Username) if err != nil { return nil, err } @@ -620,11 +620,12 @@ func (us *UserAdminService) SendUserActivation(ctx context.Context, req *schema. } func (us *UserAdminService) DeletePermanently(ctx context.Context, req *schema.DeletePermanentlyReq) (err error) { - if req.Type == constant.DeletePermanentlyUsers { + switch req.Type { + case constant.DeletePermanentlyUsers: return us.userRepo.DeletePermanentlyUsers(ctx) - } else if req.Type == constant.DeletePermanentlyQuestions { + case constant.DeletePermanentlyQuestions: return us.questionCommonRepo.DeletePermanentlyQuestions(ctx) - } else if req.Type == constant.DeletePermanentlyAnswers { + case constant.DeletePermanentlyAnswers: return us.answerCommonRepo.DeletePermanentlyAnswers(ctx) } diff --git a/internal/service/user_notification_config/user_notification_config_service.go b/internal/service/user_notification_config/user_notification_config_service.go index 01da3ee2f..c40df55cf 100644 --- a/internal/service/user_notification_config/user_notification_config_service.go +++ b/internal/service/user_notification_config/user_notification_config_service.go @@ -68,21 +68,21 @@ func (us *UserNotificationConfigService) GetUserNotificationConfig(ctx context.C func (us *UserNotificationConfigService) UpdateUserNotificationConfig( ctx context.Context, req *schema.UpdateUserNotificationConfigReq) (err error) { - req.NotificationConfig.Format() + req.Format() err = us.userNotificationConfigRepo.Save(ctx, - us.convertToEntity(ctx, req.UserID, constant.InboxSource, req.NotificationConfig.Inbox)) + us.convertToEntity(ctx, req.UserID, constant.InboxSource, req.Inbox)) if err != nil { return err } err = us.userNotificationConfigRepo.Save(ctx, - us.convertToEntity(ctx, req.UserID, constant.AllNewQuestionSource, req.NotificationConfig.AllNewQuestion)) + us.convertToEntity(ctx, req.UserID, constant.AllNewQuestionSource, req.AllNewQuestion)) if err != nil { return err } err = us.userNotificationConfigRepo.Save(ctx, us.convertToEntity(ctx, req.UserID, constant.AllNewQuestionForFollowingTagsSource, - req.NotificationConfig.AllNewQuestionForFollowingTags)) + req.AllNewQuestionForFollowingTags)) if err != nil { return err } diff --git a/pkg/checker/file_type.go b/pkg/checker/file_type.go index 51f687d6c..ac1fbcaf9 100644 --- a/pkg/checker/file_type.go +++ b/pkg/checker/file_type.go @@ -75,7 +75,9 @@ func decodeAndCheckImageFile(localFilePath string, maxImageMegapixel int, checke log.Errorf("open file error: %v", err) return false } - defer file.Close() + defer func() { + _ = file.Close() + }() if err = checker(file, maxImageMegapixel); err != nil { log.Errorf("check image format error: %v", err) diff --git a/pkg/checker/password.go b/pkg/checker/password.go index ac274f352..ac99fd433 100644 --- a/pkg/checker/password.go +++ b/pkg/checker/password.go @@ -20,6 +20,7 @@ package checker import ( + "errors" "fmt" "regexp" "strings" @@ -40,7 +41,7 @@ const ( // CheckPassword checks the password strength func CheckPassword(password string) error { if strings.Contains(password, " ") { - return fmt.Errorf(PasswordCannotContainSpaces) + return errors.New(PasswordCannotContainSpaces) } // TODO Currently there is no requirement for password strength diff --git a/pkg/converter/markdown.go b/pkg/converter/markdown.go index 1789a32cd..d16915a84 100644 --- a/pkg/converter/markdown.go +++ b/pkg/converter/markdown.go @@ -32,7 +32,6 @@ import ( "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/parser" "github.com/yuin/goldmark/renderer" - "github.com/yuin/goldmark/renderer/html" goldmarkHTML "github.com/yuin/goldmark/renderer/html" "github.com/yuin/goldmark/util" ) @@ -141,7 +140,7 @@ func (r *DangerousHTMLRenderer) renderLink(w util.BufWriter, source []byte, node if entering && r.renderLinkIsUrl(string(n.Destination)) { _, _ = w.WriteString("') } else { @@ -175,7 +174,7 @@ func (r *DangerousHTMLRenderer) renderAutoLink(w util.BufWriter, source []byte, _, _ = w.Write(util.EscapeHTML(util.URLEscape(url, false))) if n.Attributes() != nil { _ = w.WriteByte('"') - html.RenderAttributes(w, n, html.LinkAttributeFilter) + goldmarkHTML.RenderAttributes(w, n, goldmarkHTML.LinkAttributeFilter) _ = w.WriteByte('>') } else { _, _ = w.WriteString(`">`) diff --git a/pkg/htmltext/htmltext.go b/pkg/htmltext/htmltext.go index 707c20a80..56db4d2b2 100644 --- a/pkg/htmltext/htmltext.go +++ b/pkg/htmltext/htmltext.go @@ -194,7 +194,9 @@ func GetPicByUrl(Url string) string { if err != nil { return "" } - defer res.Body.Close() + defer func() { + _ = res.Body.Close() + }() pix, err := io.ReadAll(res.Body) if err != nil { return "" diff --git a/plugin/kv_storage.go b/plugin/kv_storage.go index d1ed3eaa6..204e5ee68 100644 --- a/plugin/kv_storage.go +++ b/plugin/kv_storage.go @@ -88,7 +88,7 @@ func (kv *KVOperator) getSession(ctx context.Context) (*xorm.Session, func()) { session = kv.data.DB.NewSession().Context(ctx) cleanup = func() { if session != nil { - session.Close() + _ = session.Close() } } } @@ -281,7 +281,7 @@ func (kv *KVOperator) Tx(ctx context.Context, fn func(ctx context.Context, kv *K if kv.session == nil { session := kv.data.DB.NewSession().Context(ctx) if err := session.Begin(); err != nil { - session.Close() + _ = session.Close() return fmt.Errorf("%w: begin transaction failed: %v", ErrKVTransactionFailed, err) } @@ -291,7 +291,7 @@ func (kv *KVOperator) Tx(ctx context.Context, fn func(ctx context.Context, kv *K log.Errorf("rollback failed: %v", rollbackErr) } } - session.Close() + _ = session.Close() }() txKv = &KVOperator{ diff --git a/plugin/plugin_test/plugin_main_test.go b/plugin/plugin_test/plugin_main_test.go index add11460b..fd9015c86 100644 --- a/plugin/plugin_test/plugin_main_test.go +++ b/plugin/plugin_test/plugin_main_test.go @@ -78,7 +78,7 @@ func TestMain(t *testing.M) { dbSetting = dbSettingMapping[string(schemas.SQLITE)] } if dbSetting.Driver == string(schemas.SQLITE) { - os.RemoveAll(dbSetting.Connection) + _ = os.RemoveAll(dbSetting.Connection) } defer func() { diff --git a/ui/static.go b/ui/static.go index dc79a1785..65caae461 100644 --- a/ui/static.go +++ b/ui/static.go @@ -21,7 +21,6 @@ package ui import ( "embed" - _ "embed" ) //go:embed build From 670aa323254ca8f2a5d3927353afb83b7724e424 Mon Sep 17 00:00:00 2001 From: ferhat elmas Date: Mon, 1 Dec 2025 21:22:18 +0100 Subject: [PATCH 14/92] refactor(lint): add new linters and fix their issues * gocritic * misspell * modernize (aside, bumping go would be nice) * testifylint * unconvert * unparam * whitespace related to #1432 Signed-off-by: ferhat elmas --- .golangci.yaml | 7 +++ i18n/cs_CZ.yaml | 2 +- i18n/cy_GB.yaml | 2 +- i18n/da_DK.yaml | 2 +- i18n/de_DE.yaml | 2 +- i18n/en_US.yaml | 2 +- i18n/es_ES.yaml | 2 +- i18n/fa_IR.yaml | 2 +- i18n/fr_FR.yaml | 2 +- i18n/hi_IN.yaml | 2 +- i18n/id_ID.yaml | 2 +- i18n/it_IT.yaml | 2 +- i18n/ja_JP.yaml | 2 +- i18n/ko_KR.yaml | 2 +- i18n/ml_IN.yaml | 2 +- i18n/pl_PL.yaml | 2 +- i18n/pt_PT.yaml | 2 +- i18n/ro_RO.yaml | 2 +- i18n/ru_RU.yaml | 2 +- i18n/sk_SK.yaml | 2 +- i18n/sv_SE.yaml | 10 ++-- i18n/te_IN.yaml | 2 +- i18n/tr_TR.yaml | 2 +- i18n/uk_UA.yaml | 2 +- i18n/vi_VN.yaml | 2 +- i18n/zh_CN.yaml | 2 +- i18n/zh_TW.yaml | 2 +- internal/base/middleware/avatar.go | 1 - internal/base/reason/reason.go | 2 +- internal/base/server/http.go | 1 - internal/base/server/http_funcmap.go | 4 +- internal/controller/question_controller.go | 3 +- internal/controller/template_controller.go | 8 +-- .../controller/template_render/comment.go | 1 - .../controller/template_render/controller.go | 10 ++-- internal/controller/user_controller.go | 1 - internal/entity/collection_entity.go | 4 +- internal/install/install_req.go | 9 +-- internal/migrations/v12.go | 1 - internal/migrations/v13.go | 4 +- internal/repo/activity/follow_repo.go | 2 +- internal/repo/activity_common/follow.go | 6 +- internal/repo/answer/answer_repo.go | 2 +- internal/repo/collection/collection_repo.go | 4 +- internal/repo/question/question_repo.go | 8 +-- internal/repo/rank/user_rank_repo.go | 2 +- internal/repo/repo_test/auth_test.go | 31 +++++----- internal/repo/repo_test/captcha_test.go | 11 ++-- internal/repo/repo_test/comment_repo_test.go | 27 ++++----- internal/repo/repo_test/email_repo_test.go | 5 +- internal/repo/repo_test/meta_repo_test.go | 31 +++++----- .../repo/repo_test/notification_repo_test.go | 33 ++++++----- internal/repo/repo_test/reason_repo_test.go | 5 +- internal/repo/repo_test/recommend_test.go | 27 ++++----- internal/repo/repo_test/repo_main_test.go | 2 +- internal/repo/repo_test/revision_repo_test.go | 17 +++--- internal/repo/repo_test/siteinfo_repo_test.go | 9 +-- internal/repo/repo_test/tag_rel_repo_test.go | 25 ++++---- internal/repo/repo_test/tag_repo_test.go | 33 ++++++----- .../repo/repo_test/user_backyard_repo_test.go | 15 ++--- internal/repo/repo_test/user_repo_test.go | 35 +++++------ internal/repo/search_common/search_repo.go | 4 +- internal/schema/backyard_user_schema.go | 2 +- internal/schema/meta_schema.go | 16 ++--- internal/schema/notification_schema.go | 6 +- internal/schema/revision_schema.go | 2 +- internal/schema/siteinfo_schema.go | 2 +- internal/schema/tag_schema.go | 2 +- internal/service/action/captcha_strategy.go | 21 ++++--- internal/service/auth/auth.go | 2 +- internal/service/comment/comment_service.go | 15 +++-- internal/service/content/answer_service.go | 13 ++--- .../content/question_hottest_service.go | 1 - internal/service/content/question_service.go | 58 ++++++++----------- internal/service/content/revision_service.go | 1 - internal/service/content/search_service.go | 14 +++-- internal/service/content/user_service.go | 7 +-- .../service/dashboard/dashboard_service.go | 18 +++--- .../invite_answer_notification.go | 3 +- .../notification/new_answer_notification.go | 3 +- .../notification/new_comment_notification.go | 3 +- .../notification/new_question_notification.go | 3 +- .../notification/notification_service.go | 13 ++--- .../notification_common/notification.go | 2 +- .../plugin_common/plugin_common_service.go | 1 - internal/service/question_common/question.go | 11 ++-- .../siteinfo_common/siteinfo_service_test.go | 5 +- internal/service/tag/tag_service.go | 4 +- internal/service/tag_common/tag_common.go | 8 +-- internal/service/uploader/upload.go | 2 - internal/service/user_admin/user_backyard.go | 23 ++++---- internal/service/user_common/user.go | 4 +- .../user_notification_config_service.go | 2 +- pkg/checker/file_type.go | 8 +-- pkg/checker/path_ignore.go | 15 +---- pkg/checker/question_link.go | 11 ++-- pkg/converter/markdown.go | 18 +++--- pkg/day/day.go | 7 ++- pkg/dir/dir.go | 16 ++--- pkg/htmltext/htmltext.go | 14 ++--- pkg/htmltext/htmltext_test.go | 4 +- plugin/plugin_test/plugin_main_test.go | 13 ++--- 102 files changed, 392 insertions(+), 431 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 611b49bc2..09fca51c5 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -29,6 +29,13 @@ linters: - bodyclose # checks whether HTTP response body is closed successfully - canonicalheader # checks whether net/http.Header uses canonical header - copyloopvar # detects places where loop variables are copied (Go 1.22+) + - gocritic # provides diagnostics that check for bugs, performance and style issues + - misspell # finds commonly misspelled English words in comments and strings + - modernize # detects code that can be modernized to use newer Go features + - testifylint # checks usage of github.com/stretchr/testify + - unconvert # removes unnecessary type conversions + - unparam # reports unused function parameters + - whitespace # detects leading and trailing whitespace formatters: enable: diff --git a/i18n/cs_CZ.yaml b/i18n/cs_CZ.yaml index d9f972a63..ab53cb635 100644 --- a/i18n/cs_CZ.yaml +++ b/i18n/cs_CZ.yaml @@ -234,7 +234,7 @@ backend: other: Nemáte oprávnění pro aktualizaci. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/cy_GB.yaml b/i18n/cy_GB.yaml index 267070a08..5a5b9a654 100644 --- a/i18n/cy_GB.yaml +++ b/i18n/cy_GB.yaml @@ -234,7 +234,7 @@ backend: other: Dim caniatâd i ddiweddaru. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/da_DK.yaml b/i18n/da_DK.yaml index d3f410e45..37adc7db0 100644 --- a/i18n/da_DK.yaml +++ b/i18n/da_DK.yaml @@ -234,7 +234,7 @@ backend: other: Ingen tilladelse til at opdatere. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/de_DE.yaml b/i18n/de_DE.yaml index d7683f03b..542dca9b8 100644 --- a/i18n/de_DE.yaml +++ b/i18n/de_DE.yaml @@ -234,7 +234,7 @@ backend: other: Keine Berechtigung zum Aktualisieren. content_cannot_empty: other: Der Inhalt darf nicht leer sein. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/en_US.yaml b/i18n/en_US.yaml index 40017b75a..6ff6ef3c6 100644 --- a/i18n/en_US.yaml +++ b/i18n/en_US.yaml @@ -235,7 +235,7 @@ backend: other: No permission to update. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/es_ES.yaml b/i18n/es_ES.yaml index 99071e2fe..f53a2810c 100644 --- a/i18n/es_ES.yaml +++ b/i18n/es_ES.yaml @@ -234,7 +234,7 @@ backend: other: Sin permiso para actualizar. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/fa_IR.yaml b/i18n/fa_IR.yaml index 600d5cc11..d013d0172 100644 --- a/i18n/fa_IR.yaml +++ b/i18n/fa_IR.yaml @@ -234,7 +234,7 @@ backend: other: اجازه بروزرسانی ندارید. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/fr_FR.yaml b/i18n/fr_FR.yaml index ecb87bef1..879906fa5 100644 --- a/i18n/fr_FR.yaml +++ b/i18n/fr_FR.yaml @@ -234,7 +234,7 @@ backend: other: Pas de permission pour mettre à jour. content_cannot_empty: other: Le contenu ne peut pas être vide. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/hi_IN.yaml b/i18n/hi_IN.yaml index 09be62019..eb0cb50bd 100644 --- a/i18n/hi_IN.yaml +++ b/i18n/hi_IN.yaml @@ -234,7 +234,7 @@ backend: other: No permission to update. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/id_ID.yaml b/i18n/id_ID.yaml index f8a4a8a88..43c0d70d1 100644 --- a/i18n/id_ID.yaml +++ b/i18n/id_ID.yaml @@ -234,7 +234,7 @@ backend: other: Tidak diizinkan untuk memperbarui. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/it_IT.yaml b/i18n/it_IT.yaml index 29cd1f521..50f60aa6a 100644 --- a/i18n/it_IT.yaml +++ b/i18n/it_IT.yaml @@ -234,7 +234,7 @@ backend: other: Nessun permesso per l'aggiornamento. content_cannot_empty: other: Il contenuto non può essere vuoto. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/ja_JP.yaml b/i18n/ja_JP.yaml index 8e2fb52c3..4bfe45c97 100644 --- a/i18n/ja_JP.yaml +++ b/i18n/ja_JP.yaml @@ -234,7 +234,7 @@ backend: other: 更新する権限がありません。 content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/ko_KR.yaml b/i18n/ko_KR.yaml index be1807457..0ddefa61f 100644 --- a/i18n/ko_KR.yaml +++ b/i18n/ko_KR.yaml @@ -234,7 +234,7 @@ backend: other: 업데이트 권한이 없습니다. content_cannot_empty: other: 내용은 비워둘 수 없습니다. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/ml_IN.yaml b/i18n/ml_IN.yaml index 421350311..e2cac0e0b 100644 --- a/i18n/ml_IN.yaml +++ b/i18n/ml_IN.yaml @@ -234,7 +234,7 @@ backend: other: No permission to update. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/pl_PL.yaml b/i18n/pl_PL.yaml index ae26c6d1a..e5972d9b3 100644 --- a/i18n/pl_PL.yaml +++ b/i18n/pl_PL.yaml @@ -234,7 +234,7 @@ backend: other: Brak uprawnień do edycji. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/pt_PT.yaml b/i18n/pt_PT.yaml index 997bb0552..5989071e8 100644 --- a/i18n/pt_PT.yaml +++ b/i18n/pt_PT.yaml @@ -234,7 +234,7 @@ backend: other: Sem permissão para atualizar. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/ro_RO.yaml b/i18n/ro_RO.yaml index cd0afb8a3..43af2180b 100644 --- a/i18n/ro_RO.yaml +++ b/i18n/ro_RO.yaml @@ -234,7 +234,7 @@ backend: other: Nu aveți permisiunea de a actualiza. content_cannot_empty: other: Conținutul nu poate fi gol. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/ru_RU.yaml b/i18n/ru_RU.yaml index c554ac8d7..458fd2e66 100644 --- a/i18n/ru_RU.yaml +++ b/i18n/ru_RU.yaml @@ -234,7 +234,7 @@ backend: other: Нет разрешения на обновление. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/sk_SK.yaml b/i18n/sk_SK.yaml index 72bd4726e..cd629fc94 100644 --- a/i18n/sk_SK.yaml +++ b/i18n/sk_SK.yaml @@ -234,7 +234,7 @@ backend: other: Žiadne povolenie na aktualizáciu. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/sv_SE.yaml b/i18n/sv_SE.yaml index 243703ce0..abf58112d 100644 --- a/i18n/sv_SE.yaml +++ b/i18n/sv_SE.yaml @@ -162,7 +162,7 @@ backend: cannot_modify_self_status: other: Du får inte ändra din status. email_or_password_wrong: - other: Fel e-post eller lösenord. + other: Fel e-post eller lösenord. answer: not_found: other: Svar hittades inte. @@ -189,12 +189,12 @@ backend: need_to_be_verified: other: E-postadressen ska vara verifierad. verify_url_expired: - other: Länken för att verifiera e-postadressen har gått ut. Vänligen skicka igen. + other: Länken för att verifiera e-postadressen har gått ut. Vänligen skicka igen. illegal_email_domain_error: - other: E-post från den domänen tillåts inte. Vänligen använt en annan. + other: E-post från den domänen tillåts inte. Vänligen använt en annan. lang: not_found: - other: Språkfilen hittas inte. + other: Språkfilen hittas inte. object: captcha_verification_failed: other: Fel Captcha. @@ -234,7 +234,7 @@ backend: other: No permission to update. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/te_IN.yaml b/i18n/te_IN.yaml index dbf4acb14..9e80aa8d8 100644 --- a/i18n/te_IN.yaml +++ b/i18n/te_IN.yaml @@ -234,7 +234,7 @@ backend: other: No permission to update. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/tr_TR.yaml b/i18n/tr_TR.yaml index fdecee532..92d97ebe2 100644 --- a/i18n/tr_TR.yaml +++ b/i18n/tr_TR.yaml @@ -234,7 +234,7 @@ backend: other: Güncelleme izni yok. content_cannot_empty: other: İçerik boş olamaz. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/uk_UA.yaml b/i18n/uk_UA.yaml index ea0e4591c..67496262a 100644 --- a/i18n/uk_UA.yaml +++ b/i18n/uk_UA.yaml @@ -234,7 +234,7 @@ backend: other: Немає дозволу на оновлення. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/vi_VN.yaml b/i18n/vi_VN.yaml index 6f5e5cbbb..af01b1da4 100644 --- a/i18n/vi_VN.yaml +++ b/i18n/vi_VN.yaml @@ -234,7 +234,7 @@ backend: other: Không có quyền cập nhật. content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/i18n/zh_CN.yaml b/i18n/zh_CN.yaml index 0f7a25154..35321ac1f 100644 --- a/i18n/zh_CN.yaml +++ b/i18n/zh_CN.yaml @@ -234,7 +234,7 @@ backend: other: 没有更新权限。 content_cannot_empty: other: 内容不能为空。 - content_less_than_minumum: + content_less_than_minimum: other: 输入的内容不足。 rank: fail_to_meet_the_condition: diff --git a/i18n/zh_TW.yaml b/i18n/zh_TW.yaml index cc362ea1e..4b239c1e1 100644 --- a/i18n/zh_TW.yaml +++ b/i18n/zh_TW.yaml @@ -234,7 +234,7 @@ backend: other: 無更新權限。 content_cannot_empty: other: Content cannot be empty. - content_less_than_minumum: + content_less_than_minimum: other: Not enough content entered. rank: fail_to_meet_the_condition: diff --git a/internal/base/middleware/avatar.go b/internal/base/middleware/avatar.go index 98430638b..42b28da99 100644 --- a/internal/base/middleware/avatar.go +++ b/internal/base/middleware/avatar.go @@ -80,7 +80,6 @@ func (am *AvatarMiddleware) AvatarThumb() gin.HandlerFunc { } ctx.Abort() return - } else { urlInfo, err := url.Parse(uri) if err != nil { diff --git a/internal/base/reason/reason.go b/internal/base/reason/reason.go index 42e29f4c5..97aaa75a9 100644 --- a/internal/base/reason/reason.go +++ b/internal/base/reason/reason.go @@ -47,7 +47,7 @@ const ( QuestionAlreadyDeleted = "error.question.already_deleted" QuestionUnderReview = "error.question.under_review" QuestionContentCannotEmpty = "error.question.content_cannot_empty" - QuestionContentLessThanMinimum = "error.question.content_less_than_minumum" + QuestionContentLessThanMinimum = "error.question.content_less_than_minimum" AnswerNotFound = "error.answer.not_found" AnswerCannotDeleted = "error.answer.cannot_deleted" AnswerCannotUpdate = "error.answer.cannot_update" diff --git a/internal/base/server/http.go b/internal/base/server/http.go index 088bbc9e4..4fbb04cb2 100644 --- a/internal/base/server/http.go +++ b/internal/base/server/http.go @@ -44,7 +44,6 @@ func NewHTTPServer(debug bool, pluginAPIRouter *router.PluginAPIRouter, uiConf *UI, ) *gin.Engine { - if debug { gin.SetMode(gin.DebugMode) } else { diff --git a/internal/base/server/http_funcmap.go b/internal/base/server/http_funcmap.go index db4604572..a5d530b50 100644 --- a/internal/base/server/http_funcmap.go +++ b/internal/base/server/http_funcmap.go @@ -134,9 +134,7 @@ var funcMap = template.FuncMap{ "timezone": tz, } }, - "urlTitle": func(title string) string { - return htmltext.UrlTitle(title) - }, + "urlTitle": htmltext.UrlTitle, } func FormatLinkNofollow(html string) string { diff --git a/internal/controller/question_controller.go b/internal/controller/question_controller.go index 4b1869fa7..581cf548b 100644 --- a/internal/controller/question_controller.go +++ b/internal/controller/question_controller.go @@ -287,7 +287,6 @@ func (qc *QuestionController) GetQuestionInviteUserInfo(ctx *gin.Context) { questionID := uid.DeShortID(ctx.Query("id")) resp, err := qc.questionService.InviteUserInfo(ctx, questionID) handler.HandleResponse(ctx, err, resp) - } // SimilarQuestion godoc @@ -578,7 +577,7 @@ func (qc *QuestionController) AddQuestionByAnswer(ctx *gin.Context) { handler.HandleResponse(ctx, errors.BadRequest(reason.RequestFormatError), errFields) return } - //add the question id to the answer + // add the question id to the answer questionInfo, ok := resp.(*schema.QuestionInfoResp) if ok { answerReq := &schema.AnswerAddReq{} diff --git a/internal/controller/template_controller.go b/internal/controller/template_controller.go index 801e129c2..f6a442c21 100644 --- a/internal/controller/template_controller.go +++ b/internal/controller/template_controller.go @@ -263,14 +263,13 @@ func (tc *TemplateController) QuestionInfoRedirect(ctx *gin.Context, siteInfo *s if needChangeShortID { return true, url } - //not have title + // not have title if titleIsAnswerID || len(title) == 0 { return false, "" } return true, url } else { - detail, err := tc.templateRenderController.QuestionDetail(ctx, questionID) if err != nil { tc.Page404(ctx) @@ -284,7 +283,7 @@ func (tc *TemplateController) QuestionInfoRedirect(ctx *gin.Context, siteInfo *s if len(ctx.Request.URL.Query()) > 0 { url = fmt.Sprintf("%s?%s", url, ctx.Request.URL.RawQuery) } - //have title + // have title if len(title) > 0 && !titleIsAnswerID && correctTitle { if needChangeShortID { return true, url @@ -370,7 +369,7 @@ func (tc *TemplateController) QuestionInfo(ctx *gin.Context) { UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle || siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID - //related question + // related question userID := middleware.GetLoginUserIDFromContext(ctx) relatedQuestion, _, _ := tc.questionService.SimilarQuestion(ctx, id, userID) @@ -553,7 +552,6 @@ func (tc *TemplateController) UserInfo(ctx *gin.Context) { "topQuestions": questionList, "topAnswers": answerList, }) - } func (tc *TemplateController) Page404(ctx *gin.Context) { diff --git a/internal/controller/template_render/comment.go b/internal/controller/template_render/comment.go index 2862ad8dd..c1265bd05 100644 --- a/internal/controller/template_render/comment.go +++ b/internal/controller/template_render/comment.go @@ -33,7 +33,6 @@ func (t *TemplateRenderController) CommentList( comments map[string][]*schema.GetCommentResp, err error, ) { - comments = make(map[string][]*schema.GetCommentResp, len(objectIDs)) for _, objectID := range objectIDs { diff --git a/internal/controller/template_render/controller.go b/internal/controller/template_render/controller.go index 3412010db..297b3f9a6 100644 --- a/internal/controller/template_render/controller.go +++ b/internal/controller/template_render/controller.go @@ -78,10 +78,10 @@ func Paginator(page, pageSize int, nums int64) *schema.Paginator { pageSize = 10 } - var prevpage int //Previous page address - var nextpage int //Address on the last page - //Generate the total number of pages based on the total number of nums and the number of prepage pages - totalpages := int(math.Ceil(float64(nums) / float64(pageSize))) //Total number of Pages + var prevpage int // Previous page address + var nextpage int // Address on the last page + // Generate the total number of pages based on the total number of nums and the number of prepage pages + totalpages := int(math.Ceil(float64(nums) / float64(pageSize))) // Total number of Pages if page > totalpages { page = totalpages } @@ -90,7 +90,7 @@ func Paginator(page, pageSize int, nums int64) *schema.Paginator { } var pages []int switch { - case page >= totalpages-5 && totalpages > 5: //The last 5 pages + case page >= totalpages-5 && totalpages > 5: // The last 5 pages start := totalpages - 5 + 1 prevpage = page - 1 nextpage = int(math.Min(float64(totalpages), float64(page+1))) diff --git a/internal/controller/user_controller.go b/internal/controller/user_controller.go index e4a3b3d3b..cc89caf1a 100644 --- a/internal/controller/user_controller.go +++ b/internal/controller/user_controller.go @@ -509,7 +509,6 @@ func (uc *UserController) ActionRecord(ctx *gin.Context) { resp, err := uc.actionService.ActionRecord(ctx, req) handler.HandleResponse(ctx, err, resp) } - } // GetUserNotificationConfig get user's notification config diff --git a/internal/entity/collection_entity.go b/internal/entity/collection_entity.go index 5fbd5b0eb..24ae232f4 100644 --- a/internal/entity/collection_entity.go +++ b/internal/entity/collection_entity.go @@ -33,8 +33,8 @@ type Collection struct { type CollectionSearch struct { Collection - Page int `json:"page" form:"page"` //Query number of pages - PageSize int `json:"page_size" form:"page_size"` //Search page size + Page int `json:"page" form:"page"` // Query number of pages + PageSize int `json:"page_size" form:"page_size"` // Search page size } // TableName collection table name diff --git a/internal/install/install_req.go b/internal/install/install_req.go index e5b8839e9..39657a546 100644 --- a/internal/install/install_req.go +++ b/internal/install/install_req.go @@ -65,13 +65,14 @@ func (r *CheckDatabaseReq) GetConnection() string { } if r.DbType == string(schemas.POSTGRES) { host, port := parsePgSQLHostPort(r.DbHost) - if !r.Ssl { + switch { + case !r.Ssl: return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", host, port, r.DbUsername, r.DbPassword, r.DbName) - } else if r.SslMode == "require" { + case r.SslMode == "require": return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", host, port, r.DbUsername, r.DbPassword, r.DbName, r.SslMode) - } else if r.SslMode == "verify-ca" || r.SslMode == "verify-full" { + case r.SslMode == "verify-ca" || r.SslMode == "verify-full": connection := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", host, port, r.DbUsername, r.DbPassword, r.DbName, r.SslMode) if len(r.SslRootCert) > 0 && dir.CheckFileExist(r.SslRootCert) { @@ -150,7 +151,7 @@ func (r *InitBaseInfoReq) FormatSiteUrl() { } r.SiteURL = fmt.Sprintf("%s://%s", parsedUrl.Scheme, parsedUrl.Host) if len(parsedUrl.Path) > 0 { - r.SiteURL = r.SiteURL + parsedUrl.Path + r.SiteURL += parsedUrl.Path r.SiteURL = strings.TrimSuffix(r.SiteURL, "/") } } diff --git a/internal/migrations/v12.go b/internal/migrations/v12.go index 2dd3ce71e..23e8acdcd 100644 --- a/internal/migrations/v12.go +++ b/internal/migrations/v12.go @@ -75,7 +75,6 @@ func updateQuestionPostTime(ctx context.Context, x *xorm.Engine) error { return fmt.Errorf("update question failed: %w", err) } } - } return nil diff --git a/internal/migrations/v13.go b/internal/migrations/v13.go index 57d248482..16ba177e8 100644 --- a/internal/migrations/v13.go +++ b/internal/migrations/v13.go @@ -136,7 +136,7 @@ func addPrivilegeForInviteSomeoneToAnswer(ctx context.Context, x *xorm.Engine) e } func updateQuestionCount(ctx context.Context, x *xorm.Engine) error { - //question answer count + // question answer count answers := make([]AnswerV13, 0) err := x.Context(ctx).Find(&answers, &AnswerV13{Status: entity.AnswerStatusAvailable}) if err != nil { @@ -216,7 +216,7 @@ func updateTagCount(ctx context.Context, x *xorm.Engine) error { } } - //select tag count + // select tag count newTagRelList := make([]entity.TagRel, 0) err = x.Context(ctx).Find(&newTagRelList, &entity.TagRel{Status: entity.TagRelStatusAvailable}) if err != nil { diff --git a/internal/repo/activity/follow_repo.go b/internal/repo/activity/follow_repo.go index 7af2189a6..4c6fc431b 100644 --- a/internal/repo/activity/follow_repo.go +++ b/internal/repo/activity/follow_repo.go @@ -168,7 +168,7 @@ func (ar *FollowRepo) FollowCancel(ctx context.Context, objectID, userID string) return err } -func (ar *FollowRepo) updateFollows(ctx context.Context, session *xorm.Session, objectID string, follows int) error { +func (ar *FollowRepo) updateFollows(_ context.Context, session *xorm.Session, objectID string, follows int) error { objectType, err := obj.GetObjectTypeStrByObjectID(objectID) if err != nil { return err diff --git a/internal/repo/activity_common/follow.go b/internal/repo/activity_common/follow.go index 99e5a6e67..a185c3d8a 100644 --- a/internal/repo/activity_common/follow.go +++ b/internal/repo/activity_common/follow.go @@ -66,19 +66,19 @@ func (ar *FollowRepo) GetFollowAmount(ctx context.Context, objectID string) (fol model := &entity.Question{} _, err = ar.data.DB.Context(ctx).Where("id = ?", objectID).Cols("`follow_count`").Get(model) if err == nil { - follows = int(model.FollowCount) + follows = model.FollowCount } case "user": model := &entity.User{} _, err = ar.data.DB.Context(ctx).Where("id = ?", objectID).Cols("`follow_count`").Get(model) if err == nil { - follows = int(model.FollowCount) + follows = model.FollowCount } case "tag": model := &entity.Tag{} _, err = ar.data.DB.Context(ctx).Where("id = ?", objectID).Cols("`follow_count`").Get(model) if err == nil { - follows = int(model.FollowCount) + follows = model.FollowCount } default: err = errors.InternalServer(reason.DisallowFollow).WithMsg("this object can't be followed") diff --git a/internal/repo/answer/answer_repo.go b/internal/repo/answer/answer_repo.go index 0f1ae8146..52963c44c 100644 --- a/internal/repo/answer/answer_repo.go +++ b/internal/repo/answer/answer_repo.go @@ -335,7 +335,7 @@ func (ar *answerRepo) SearchList(ctx context.Context, search *entity.AnswerSearc var err error rows := make([]*entity.Answer, 0) if search.Page > 0 { - search.Page = search.Page - 1 + search.Page-- } else { search.Page = 0 } diff --git a/internal/repo/collection/collection_repo.go b/internal/repo/collection/collection_repo.go index f30692c97..482cb075d 100644 --- a/internal/repo/collection/collection_repo.go +++ b/internal/repo/collection/collection_repo.go @@ -167,7 +167,7 @@ func (cr *collectionRepo) GetCollectionPage(ctx context.Context, page, pageSize // SearchObjectCollected check object is collected or not func (cr *collectionRepo) SearchObjectCollected(ctx context.Context, userID string, objectIds []string) (map[string]bool, error) { - for i := 0; i < len(objectIds); i++ { + for i := range objectIds { objectIds[i] = uid.DeShortID(objectIds[i]) } @@ -193,7 +193,7 @@ func (cr *collectionRepo) SearchList(ctx context.Context, search *entity.Collect var err error rows := make([]*entity.Collection, 0) if search.Page > 0 { - search.Page = search.Page - 1 + search.Page-- } else { search.Page = 0 } diff --git a/internal/repo/question/question_repo.go b/internal/repo/question/question_repo.go index 3935e6102..3449efb8b 100644 --- a/internal/repo/question/question_repo.go +++ b/internal/repo/question/question_repo.go @@ -89,9 +89,9 @@ func (qr *questionRepo) RemoveQuestion(ctx context.Context, id string) (err erro } // UpdateQuestion update question -func (qr *questionRepo) UpdateQuestion(ctx context.Context, question *entity.Question, Cols []string) (err error) { +func (qr *questionRepo) UpdateQuestion(ctx context.Context, question *entity.Question, cols []string) (err error) { question.ID = uid.DeShortID(question.ID) - _, err = qr.data.DB.Context(ctx).Where("id =?", question.ID).Cols(Cols...).Update(question) + _, err = qr.data.DB.Context(ctx).Where("id =?", question.ID).Cols(cols...).Update(question) if err != nil { return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() } @@ -344,7 +344,7 @@ func (qr *questionRepo) GetUserQuestionCount(ctx context.Context, userID string, func (qr *questionRepo) SitemapQuestions(ctx context.Context, page, pageSize int) ( questionIDList []*schema.SiteMapQuestionInfo, err error) { - page = page - 1 + page-- questionIDList = make([]*schema.SiteMapQuestionInfo, 0) // try to get sitemap data from cache @@ -524,7 +524,7 @@ func (qr *questionRepo) AdminQuestionPage(ctx context.Context, search *schema.Ad rows := make([]*entity.Question, 0) if search.Page > 0 { - search.Page = search.Page - 1 + search.Page-- } else { search.Page = 0 } diff --git a/internal/repo/rank/user_rank_repo.go b/internal/repo/rank/user_rank_repo.go index cb9ca1b3d..5e86f5929 100644 --- a/internal/repo/rank/user_rank_repo.go +++ b/internal/repo/rank/user_rank_repo.go @@ -141,7 +141,7 @@ func (ur *UserRankRepo) TriggerUserRank(ctx context.Context, return false, nil } -func (ur *UserRankRepo) checkUserMinRank(ctx context.Context, session *xorm.Session, userID string, deltaRank int) ( +func (ur *UserRankRepo) checkUserMinRank(_ context.Context, session *xorm.Session, userID string, deltaRank int) ( isReachStandard bool, err error, ) { bean := &entity.User{ID: userID} diff --git a/internal/repo/repo_test/auth_test.go b/internal/repo/repo_test/auth_test.go index 387332399..0c9919020 100644 --- a/internal/repo/repo_test/auth_test.go +++ b/internal/repo/repo_test/auth_test.go @@ -26,6 +26,7 @@ import ( "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/repo/auth" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( @@ -38,10 +39,10 @@ func Test_authRepo_SetUserCacheInfo(t *testing.T) { authRepo := auth.NewAuthRepo(testDataSource) err := authRepo.SetUserCacheInfo(context.TODO(), accessToken, visitToken, &entity.UserCacheInfo{UserID: userID}) - assert.NoError(t, err) + require.NoError(t, err) cacheInfo, err := authRepo.GetUserCacheInfo(context.TODO(), accessToken) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, userID, cacheInfo.UserID) } @@ -49,13 +50,13 @@ func Test_authRepo_RemoveUserCacheInfo(t *testing.T) { authRepo := auth.NewAuthRepo(testDataSource) err := authRepo.SetUserCacheInfo(context.TODO(), accessToken, visitToken, &entity.UserCacheInfo{UserID: userID}) - assert.NoError(t, err) + require.NoError(t, err) err = authRepo.RemoveUserCacheInfo(context.TODO(), accessToken) - assert.NoError(t, err) + require.NoError(t, err) userInfo, err := authRepo.GetUserCacheInfo(context.TODO(), accessToken) - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, userInfo) } @@ -63,23 +64,23 @@ func Test_authRepo_SetUserStatus(t *testing.T) { authRepo := auth.NewAuthRepo(testDataSource) err := authRepo.SetUserStatus(context.TODO(), userID, &entity.UserCacheInfo{UserID: userID}) - assert.NoError(t, err) + require.NoError(t, err) cacheInfo, err := authRepo.GetUserStatus(context.TODO(), userID) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, userID, cacheInfo.UserID) } func Test_authRepo_RemoveUserStatus(t *testing.T) { authRepo := auth.NewAuthRepo(testDataSource) err := authRepo.SetUserStatus(context.TODO(), userID, &entity.UserCacheInfo{UserID: userID}) - assert.NoError(t, err) + require.NoError(t, err) err = authRepo.RemoveUserStatus(context.TODO(), userID) - assert.NoError(t, err) + require.NoError(t, err) userInfo, err := authRepo.GetUserStatus(context.TODO(), userID) - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, userInfo) } @@ -87,10 +88,10 @@ func Test_authRepo_SetAdminUserCacheInfo(t *testing.T) { authRepo := auth.NewAuthRepo(testDataSource) err := authRepo.SetAdminUserCacheInfo(context.TODO(), accessToken, &entity.UserCacheInfo{UserID: userID}) - assert.NoError(t, err) + require.NoError(t, err) cacheInfo, err := authRepo.GetAdminUserCacheInfo(context.TODO(), accessToken) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, userID, cacheInfo.UserID) } @@ -98,12 +99,12 @@ func Test_authRepo_RemoveAdminUserCacheInfo(t *testing.T) { authRepo := auth.NewAuthRepo(testDataSource) err := authRepo.SetAdminUserCacheInfo(context.TODO(), accessToken, &entity.UserCacheInfo{UserID: userID}) - assert.NoError(t, err) + require.NoError(t, err) err = authRepo.RemoveAdminUserCacheInfo(context.TODO(), accessToken) - assert.NoError(t, err) + require.NoError(t, err) userInfo, err := authRepo.GetAdminUserCacheInfo(context.TODO(), accessToken) - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, userInfo) } diff --git a/internal/repo/repo_test/captcha_test.go b/internal/repo/repo_test/captcha_test.go index 48e9dd806..e6954a232 100644 --- a/internal/repo/repo_test/captcha_test.go +++ b/internal/repo/repo_test/captcha_test.go @@ -25,6 +25,7 @@ import ( "github.com/apache/answer/internal/repo/captcha" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( @@ -36,23 +37,23 @@ var ( func Test_captchaRepo_DelActionType(t *testing.T) { captchaRepo := captcha.NewCaptchaRepo(testDataSource) err := captchaRepo.SetActionType(context.TODO(), ip, actionType, "", amount) - assert.NoError(t, err) + require.NoError(t, err) actionInfo, err := captchaRepo.GetActionType(context.TODO(), ip, actionType) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, amount, actionInfo.Num) err = captchaRepo.DelActionType(context.TODO(), ip, actionType) - assert.NoError(t, err) + require.NoError(t, err) } func Test_captchaRepo_SetCaptcha(t *testing.T) { captchaRepo := captcha.NewCaptchaRepo(testDataSource) key, capt := "key", "1234" err := captchaRepo.SetCaptcha(context.TODO(), key, capt) - assert.NoError(t, err) + require.NoError(t, err) gotCaptcha, err := captchaRepo.GetCaptcha(context.TODO(), key) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, capt, gotCaptcha) } diff --git a/internal/repo/repo_test/comment_repo_test.go b/internal/repo/repo_test/comment_repo_test.go index 3de154817..41ba04464 100644 --- a/internal/repo/repo_test/comment_repo_test.go +++ b/internal/repo/repo_test/comment_repo_test.go @@ -29,6 +29,7 @@ import ( "github.com/apache/answer/internal/repo/unique" commentService "github.com/apache/answer/internal/service/comment" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func buildCommentEntity() *entity.Comment { @@ -48,10 +49,10 @@ func Test_commentRepo_AddComment(t *testing.T) { commentRepo := comment.NewCommentRepo(testDataSource, uniqueIDRepo) testCommentEntity := buildCommentEntity() err := commentRepo.AddComment(context.TODO(), testCommentEntity) - assert.NoError(t, err) + require.NoError(t, err) err = commentRepo.RemoveComment(context.TODO(), testCommentEntity.ID) - assert.NoError(t, err) + require.NoError(t, err) } func Test_commentRepo_GetCommentPage(t *testing.T) { @@ -59,7 +60,7 @@ func Test_commentRepo_GetCommentPage(t *testing.T) { commentRepo := comment.NewCommentRepo(testDataSource, uniqueIDRepo) testCommentEntity := buildCommentEntity() err := commentRepo.AddComment(context.TODO(), testCommentEntity) - assert.NoError(t, err) + require.NoError(t, err) resp, total, err := commentRepo.GetCommentPage(context.TODO(), &commentService.CommentQuery{ PageCond: pager.PageCond{ @@ -67,12 +68,12 @@ func Test_commentRepo_GetCommentPage(t *testing.T) { PageSize: 10, }, }) - assert.NoError(t, err) - assert.Equal(t, total, int64(1)) + require.NoError(t, err) + assert.Equal(t, int64(1), total) assert.Equal(t, resp[0].ID, testCommentEntity.ID) err = commentRepo.RemoveComment(context.TODO(), testCommentEntity.ID) - assert.NoError(t, err) + require.NoError(t, err) } func Test_commentRepo_UpdateComment(t *testing.T) { @@ -81,19 +82,19 @@ func Test_commentRepo_UpdateComment(t *testing.T) { commonCommentRepo := comment.NewCommentCommonRepo(testDataSource, uniqueIDRepo) testCommentEntity := buildCommentEntity() err := commentRepo.AddComment(context.TODO(), testCommentEntity) - assert.NoError(t, err) + require.NoError(t, err) testCommentEntity.ParsedText = "test" err = commentRepo.UpdateCommentContent(context.TODO(), testCommentEntity.ID, "test", "test") - assert.NoError(t, err) + require.NoError(t, err) newComment, exist, err := commonCommentRepo.GetComment(context.TODO(), testCommentEntity.ID) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, testCommentEntity.ParsedText, newComment.ParsedText) err = commentRepo.RemoveComment(context.TODO(), testCommentEntity.ID) - assert.NoError(t, err) + require.NoError(t, err) } func Test_commentRepo_CannotGetDeletedComment(t *testing.T) { @@ -102,12 +103,12 @@ func Test_commentRepo_CannotGetDeletedComment(t *testing.T) { testCommentEntity := buildCommentEntity() err := commentRepo.AddComment(context.TODO(), testCommentEntity) - assert.NoError(t, err) + require.NoError(t, err) err = commentRepo.RemoveComment(context.TODO(), testCommentEntity.ID) - assert.NoError(t, err) + require.NoError(t, err) _, exist, err := commentRepo.GetComment(context.TODO(), testCommentEntity.ID) - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, exist) } diff --git a/internal/repo/repo_test/email_repo_test.go b/internal/repo/repo_test/email_repo_test.go index 82fc6c571..03ca9efe3 100644 --- a/internal/repo/repo_test/email_repo_test.go +++ b/internal/repo/repo_test/email_repo_test.go @@ -26,15 +26,16 @@ import ( "github.com/apache/answer/internal/repo/export" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func Test_emailRepo_VerifyCode(t *testing.T) { emailRepo := export.NewEmailRepo(testDataSource) code, content := "1111", "{\"source_type\":\"\",\"e_mail\":\"\",\"user_id\":\"1\",\"skip_validation_latest_code\":false}" err := emailRepo.SetCode(context.TODO(), "1", code, content, time.Minute) - assert.NoError(t, err) + require.NoError(t, err) verifyContent, err := emailRepo.VerifyCode(context.TODO(), code) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, content, verifyContent) } diff --git a/internal/repo/repo_test/meta_repo_test.go b/internal/repo/repo_test/meta_repo_test.go index e910dab3f..68965f22b 100644 --- a/internal/repo/repo_test/meta_repo_test.go +++ b/internal/repo/repo_test/meta_repo_test.go @@ -26,6 +26,7 @@ import ( "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/repo/meta" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func buildMetaEntity() *entity.Meta { @@ -41,15 +42,15 @@ func Test_metaRepo_GetMetaByObjectIdAndKey(t *testing.T) { metaEnt := buildMetaEntity() err := metaRepo.AddMeta(context.TODO(), metaEnt) - assert.NoError(t, err) + require.NoError(t, err) gotMeta, exist, err := metaRepo.GetMetaByObjectIdAndKey(context.TODO(), metaEnt.ObjectID, metaEnt.Key) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, metaEnt.ID, gotMeta.ID) err = metaRepo.RemoveMeta(context.TODO(), metaEnt.ID) - assert.NoError(t, err) + require.NoError(t, err) } func Test_metaRepo_GetMetaList(t *testing.T) { @@ -57,15 +58,15 @@ func Test_metaRepo_GetMetaList(t *testing.T) { metaEnt := buildMetaEntity() err := metaRepo.AddMeta(context.TODO(), metaEnt) - assert.NoError(t, err) + require.NoError(t, err) gotMetaList, err := metaRepo.GetMetaList(context.TODO(), metaEnt) - assert.NoError(t, err) - assert.Equal(t, len(gotMetaList), 1) + require.NoError(t, err) + assert.Len(t, gotMetaList, 1) assert.Equal(t, gotMetaList[0].ID, metaEnt.ID) err = metaRepo.RemoveMeta(context.TODO(), metaEnt.ID) - assert.NoError(t, err) + require.NoError(t, err) } func Test_metaRepo_GetMetaPage(t *testing.T) { @@ -73,15 +74,15 @@ func Test_metaRepo_GetMetaPage(t *testing.T) { metaEnt := buildMetaEntity() err := metaRepo.AddMeta(context.TODO(), metaEnt) - assert.NoError(t, err) + require.NoError(t, err) gotMetaList, err := metaRepo.GetMetaList(context.TODO(), metaEnt) - assert.NoError(t, err) - assert.Equal(t, len(gotMetaList), 1) + require.NoError(t, err) + assert.Len(t, gotMetaList, 1) assert.Equal(t, gotMetaList[0].ID, metaEnt.ID) err = metaRepo.RemoveMeta(context.TODO(), metaEnt.ID) - assert.NoError(t, err) + require.NoError(t, err) } func Test_metaRepo_UpdateMeta(t *testing.T) { @@ -89,17 +90,17 @@ func Test_metaRepo_UpdateMeta(t *testing.T) { metaEnt := buildMetaEntity() err := metaRepo.AddMeta(context.TODO(), metaEnt) - assert.NoError(t, err) + require.NoError(t, err) metaEnt.Value = "testing" err = metaRepo.UpdateMeta(context.TODO(), metaEnt) - assert.NoError(t, err) + require.NoError(t, err) gotMeta, exist, err := metaRepo.GetMetaByObjectIdAndKey(context.TODO(), metaEnt.ObjectID, metaEnt.Key) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, gotMeta.Value, metaEnt.Value) err = metaRepo.RemoveMeta(context.TODO(), metaEnt.ID) - assert.NoError(t, err) + require.NoError(t, err) } diff --git a/internal/repo/repo_test/notification_repo_test.go b/internal/repo/repo_test/notification_repo_test.go index a05913ba1..4f843e777 100644 --- a/internal/repo/repo_test/notification_repo_test.go +++ b/internal/repo/repo_test/notification_repo_test.go @@ -27,6 +27,7 @@ import ( "github.com/apache/answer/internal/repo/notification" "github.com/apache/answer/internal/schema" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func buildNotificationEntity() *entity.Notification { @@ -44,13 +45,13 @@ func Test_notificationRepo_ClearIDUnRead(t *testing.T) { notificationRepo := notification.NewNotificationRepo(testDataSource) ent := buildNotificationEntity() err := notificationRepo.AddNotification(context.TODO(), ent) - assert.NoError(t, err) + require.NoError(t, err) err = notificationRepo.ClearIDUnRead(context.TODO(), ent.UserID, ent.ID) - assert.NoError(t, err) + require.NoError(t, err) got, exists, err := notificationRepo.GetById(context.TODO(), ent.ID) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exists) assert.Equal(t, schema.NotificationRead, got.IsRead) } @@ -59,13 +60,13 @@ func Test_notificationRepo_ClearUnRead(t *testing.T) { notificationRepo := notification.NewNotificationRepo(testDataSource) ent := buildNotificationEntity() err := notificationRepo.AddNotification(context.TODO(), ent) - assert.NoError(t, err) + require.NoError(t, err) err = notificationRepo.ClearUnRead(context.TODO(), ent.UserID, ent.Type) - assert.NoError(t, err) + require.NoError(t, err) got, exists, err := notificationRepo.GetById(context.TODO(), ent.ID) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exists) assert.Equal(t, schema.NotificationRead, got.IsRead) } @@ -74,10 +75,10 @@ func Test_notificationRepo_GetById(t *testing.T) { notificationRepo := notification.NewNotificationRepo(testDataSource) ent := buildNotificationEntity() err := notificationRepo.AddNotification(context.TODO(), ent) - assert.NoError(t, err) + require.NoError(t, err) got, exists, err := notificationRepo.GetById(context.TODO(), ent.ID) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exists) assert.Equal(t, got.ID, ent.ID) } @@ -86,10 +87,10 @@ func Test_notificationRepo_GetByUserIdObjectIdTypeId(t *testing.T) { notificationRepo := notification.NewNotificationRepo(testDataSource) ent := buildNotificationEntity() err := notificationRepo.AddNotification(context.TODO(), ent) - assert.NoError(t, err) + require.NoError(t, err) got, exists, err := notificationRepo.GetByUserIdObjectIdTypeId(context.TODO(), ent.UserID, ent.ObjectID, ent.Type) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exists) assert.Equal(t, got.ObjectID, ent.ObjectID) } @@ -98,11 +99,11 @@ func Test_notificationRepo_GetNotificationPage(t *testing.T) { notificationRepo := notification.NewNotificationRepo(testDataSource) ent := buildNotificationEntity() err := notificationRepo.AddNotification(context.TODO(), ent) - assert.NoError(t, err) + require.NoError(t, err) notificationPage, total, err := notificationRepo.GetNotificationPage(context.TODO(), &schema.NotificationSearch{UserID: ent.UserID}) - assert.NoError(t, err) - assert.True(t, total > 0) + require.NoError(t, err) + assert.Positive(t, total) assert.Equal(t, notificationPage[0].UserID, ent.UserID) } @@ -110,14 +111,14 @@ func Test_notificationRepo_UpdateNotificationContent(t *testing.T) { notificationRepo := notification.NewNotificationRepo(testDataSource) ent := buildNotificationEntity() err := notificationRepo.AddNotification(context.TODO(), ent) - assert.NoError(t, err) + require.NoError(t, err) ent.Content = "test" err = notificationRepo.UpdateNotificationContent(context.TODO(), ent) - assert.NoError(t, err) + require.NoError(t, err) got, exists, err := notificationRepo.GetById(context.TODO(), ent.ID) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exists) assert.Equal(t, got.Content, ent.Content) } diff --git a/internal/repo/repo_test/reason_repo_test.go b/internal/repo/repo_test/reason_repo_test.go index 636f8d278..acb8c861a 100644 --- a/internal/repo/repo_test/reason_repo_test.go +++ b/internal/repo/repo_test/reason_repo_test.go @@ -28,12 +28,13 @@ import ( "github.com/apache/answer/internal/repo/reason" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func Test_reasonRepo_ListReasons(t *testing.T) { configRepo := config.NewConfigRepo(testDataSource) reasonRepo := reason.NewReasonRepo(serviceconfig.NewConfigService(configRepo)) reasonItems, err := reasonRepo.ListReasons(context.TODO(), "question", "close") - assert.NoError(t, err) - assert.Equal(t, 4, len(reasonItems)) + require.NoError(t, err) + assert.Len(t, reasonItems, 4) } diff --git a/internal/repo/repo_test/recommend_test.go b/internal/repo/repo_test/recommend_test.go index a21693886..7675aa204 100644 --- a/internal/repo/repo_test/recommend_test.go +++ b/internal/repo/repo_test/recommend_test.go @@ -34,6 +34,7 @@ import ( "github.com/apache/answer/internal/repo/user" config2 "github.com/apache/answer/internal/service/config" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func Test_questionRepo_GetRecommend(t *testing.T) { @@ -61,8 +62,8 @@ func Test_questionRepo_GetRecommend(t *testing.T) { IsAdmin: false, } err := userRepo.AddUser(context.TODO(), user) - assert.NoError(t, err) - assert.NotEqual(t, "", user.ID) + require.NoError(t, err) + assert.NotEmpty(t, user.ID) questions := make([]*entity.Question, 0) // tag, unjoin, unfollow @@ -140,8 +141,8 @@ func Test_questionRepo_GetRecommend(t *testing.T) { for _, question := range questions { err = questionRepo.AddQuestion(context.TODO(), question) - assert.NoError(t, err) - assert.NotEqual(t, "", question.ID) + require.NoError(t, err) + assert.NotEmpty(t, question.ID) } tags := []*entity.Tag{ @@ -161,7 +162,7 @@ func Test_questionRepo_GetRecommend(t *testing.T) { }, } err = tagCommenRepo.AddTagList(context.TODO(), tags) - assert.NoError(t, err) + require.NoError(t, err) tagRels := make([]*entity.TagRel, 0) for i, question := range questions { @@ -173,7 +174,7 @@ func Test_questionRepo_GetRecommend(t *testing.T) { tagRels = append(tagRels, tagRel) } err = tagRelRepo.AddTagRelList(context.TODO(), tagRels) - assert.NoError(t, err) + require.NoError(t, err) followQuestionIDs := make([]string, 0) for i := range questions { @@ -181,15 +182,15 @@ func Test_questionRepo_GetRecommend(t *testing.T) { continue } err = followRepo.Follow(context.TODO(), questions[i].ID, user.ID) - assert.NoError(t, err) + require.NoError(t, err) followQuestionIDs = append(followQuestionIDs, questions[i].ID) } // get recommend questionList, total, err := questionRepo.GetRecommendQuestionPageByTags(context.TODO(), user.ID, []string{tags[0].ID}, followQuestionIDs, 1, 20) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, int64(5), total) - assert.Equal(t, 5, len(questionList)) + assert.Len(t, questionList, 5) // recovery t.Cleanup(func() { @@ -197,19 +198,19 @@ func Test_questionRepo_GetRecommend(t *testing.T) { for i, tagRel := range tagRels { if i%2 == 1 { err = followRepo.FollowCancel(context.TODO(), questions[i].ID, user.ID) - assert.NoError(t, err) + require.NoError(t, err) } tagRelIDs = append(tagRelIDs, tagRel.ID) } err = tagRelRepo.RemoveTagRelListByIDs(context.TODO(), tagRelIDs) - assert.NoError(t, err) + require.NoError(t, err) for _, tag := range tags { err = tagRepo.RemoveTag(context.TODO(), tag.ID) - assert.NoError(t, err) + require.NoError(t, err) } for _, q := range questions { err = questionRepo.RemoveQuestion(context.TODO(), q.ID) - assert.NoError(t, err) + require.NoError(t, err) } }) } diff --git a/internal/repo/repo_test/repo_main_test.go b/internal/repo/repo_test/repo_main_test.go index 919ca94e8..e2f40f276 100644 --- a/internal/repo/repo_test/repo_main_test.go +++ b/internal/repo/repo_test/repo_main_test.go @@ -153,7 +153,7 @@ func initDatabaseImage(dbSetting TestDBSetting) (connection string, cleanup func return "", nil, fmt.Errorf("could not connect to docker: %s", err) } - //resource, err := pool.Run(dbSetting.ImageName, dbSetting.ImageVersion, dbSetting.ENV) + // resource, err := pool.Run(dbSetting.ImageName, dbSetting.ImageVersion, dbSetting.ENV) resource, err := pool.RunWithOptions(&dockertest.RunOptions{ Repository: dbSetting.ImageName, Tag: dbSetting.ImageVersion, diff --git a/internal/repo/repo_test/revision_repo_test.go b/internal/repo/repo_test/revision_repo_test.go index 01d262d2b..6fd067b30 100644 --- a/internal/repo/repo_test/revision_repo_test.go +++ b/internal/repo/repo_test/revision_repo_test.go @@ -29,6 +29,7 @@ import ( "github.com/apache/answer/internal/repo/revision" "github.com/apache/answer/internal/repo/unique" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var q = &entity.Question{ @@ -69,29 +70,29 @@ func Test_revisionRepo_AddRevision(t *testing.T) { // create question err := questionRepo.AddQuestion(context.TODO(), q) - assert.NoError(t, err) - assert.NotEqual(t, "", q.ID) + require.NoError(t, err) + assert.NotEmpty(t, q.ID) content, err := json.Marshal(q) - assert.NoError(t, err) + require.NoError(t, err) // auto update false rev := getRev(q.ID, q.Title, string(content)) err = revisionRepo.AddRevision(context.TODO(), rev, false) - assert.NoError(t, err) + require.NoError(t, err) qr, _, _ := questionRepo.GetQuestion(context.TODO(), q.ID) assert.NotEqual(t, rev.ID, qr.RevisionID) // auto update false rev = getRev(q.ID, q.Title, string(content)) err = revisionRepo.AddRevision(context.TODO(), rev, true) - assert.NoError(t, err) + require.NoError(t, err) qr, _, _ = questionRepo.GetQuestion(context.TODO(), q.ID) assert.Equal(t, rev.ID, qr.RevisionID) // recovery t.Cleanup(func() { err = questionRepo.RemoveQuestion(context.TODO(), q.ID) - assert.NoError(t, err) + require.NoError(t, err) }) } @@ -103,7 +104,7 @@ func Test_revisionRepo_GetLastRevisionByObjectID(t *testing.T) { Test_revisionRepo_AddRevision(t) rev, exists, err := revisionRepo.GetLastRevisionByObjectID(context.TODO(), q.ID) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exists) assert.NotNil(t, rev) } @@ -115,6 +116,6 @@ func Test_revisionRepo_GetRevisionList(t *testing.T) { ) Test_revisionRepo_AddRevision(t) revs, err := revisionRepo.GetRevisionList(context.TODO(), &entity.Revision{ObjectID: q.ID}) - assert.NoError(t, err) + require.NoError(t, err) assert.GreaterOrEqual(t, len(revs), 1) } diff --git a/internal/repo/repo_test/siteinfo_repo_test.go b/internal/repo/repo_test/siteinfo_repo_test.go index cb5d8fc0d..9fa59d177 100644 --- a/internal/repo/repo_test/siteinfo_repo_test.go +++ b/internal/repo/repo_test/siteinfo_repo_test.go @@ -26,6 +26,7 @@ import ( "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/repo/site_info" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func Test_siteInfoRepo_SaveByType(t *testing.T) { @@ -34,19 +35,19 @@ func Test_siteInfoRepo_SaveByType(t *testing.T) { data := &entity.SiteInfo{Content: "site_info", Type: "test"} err := siteInfoRepo.SaveByType(context.TODO(), data.Type, data) - assert.NoError(t, err) + require.NoError(t, err) got, exist, err := siteInfoRepo.GetByType(context.TODO(), data.Type) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, data.Content, got.Content) data.Content = "new site_info" err = siteInfoRepo.SaveByType(context.TODO(), data.Type, data) - assert.NoError(t, err) + require.NoError(t, err) got, exist, err = siteInfoRepo.GetByType(context.TODO(), data.Type) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, data.Content, got.Content) } diff --git a/internal/repo/repo_test/tag_rel_repo_test.go b/internal/repo/repo_test/tag_rel_repo_test.go index e3af67a14..47c09a6a3 100644 --- a/internal/repo/repo_test/tag_rel_repo_test.go +++ b/internal/repo/repo_test/tag_rel_repo_test.go @@ -30,6 +30,7 @@ import ( "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/repo/tag" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( @@ -61,15 +62,15 @@ func Test_tagListRepo_BatchGetObjectTagRelList(t *testing.T) { tagRelRepo := tag.NewTagRelRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource)) relList, err := tagRelRepo.BatchGetObjectTagRelList(context.TODO(), []string{testTagRelList[0].ObjectID, testTagRelList[1].ObjectID}) - assert.NoError(t, err) - assert.Equal(t, 2, len(relList)) + require.NoError(t, err) + assert.Len(t, relList, 2) } func Test_tagListRepo_CountTagRelByTagID(t *testing.T) { tagRelOnce.Do(addTagRelList) tagRelRepo := tag.NewTagRelRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource)) count, err := tagRelRepo.CountTagRelByTagID(context.TODO(), "10030000000000101") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, int64(1), count) } @@ -79,8 +80,8 @@ func Test_tagListRepo_GetObjectTagRelList(t *testing.T) { relList, err := tagRelRepo.GetObjectTagRelList(context.TODO(), testTagRelList[0].ObjectID) - assert.NoError(t, err) - assert.Equal(t, 1, len(relList)) + require.NoError(t, err) + assert.Len(t, relList, 1) } func Test_tagListRepo_GetObjectTagRelWithoutStatus(t *testing.T) { @@ -89,25 +90,25 @@ func Test_tagListRepo_GetObjectTagRelWithoutStatus(t *testing.T) { relList, err := tagRelRepo.BatchGetObjectTagRelList(context.TODO(), []string{testTagRelList[0].ObjectID, testTagRelList[1].ObjectID}) - assert.NoError(t, err) - assert.Equal(t, 2, len(relList)) + require.NoError(t, err) + assert.Len(t, relList, 2) ids := []int64{relList[0].ID, relList[1].ID} err = tagRelRepo.RemoveTagRelListByIDs(context.TODO(), ids) - assert.NoError(t, err) + require.NoError(t, err) count, err := tagRelRepo.CountTagRelByTagID(context.TODO(), "10030000000000101") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, int64(0), count) _, exist, err := tagRelRepo.GetObjectTagRelWithoutStatus(context.TODO(), relList[0].ObjectID, relList[0].TagID) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) err = tagRelRepo.EnableTagRelByIDs(context.TODO(), ids, false) - assert.NoError(t, err) + require.NoError(t, err) count, err = tagRelRepo.CountTagRelByTagID(context.TODO(), "10030000000000101") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, int64(1), count) } diff --git a/internal/repo/repo_test/tag_repo_test.go b/internal/repo/repo_test/tag_repo_test.go index b2475a227..aa1ec1a25 100644 --- a/internal/repo/repo_test/tag_repo_test.go +++ b/internal/repo/repo_test/tag_repo_test.go @@ -32,6 +32,7 @@ import ( "github.com/apache/answer/internal/repo/unique" "github.com/apache/answer/pkg/converter" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( @@ -75,7 +76,7 @@ func Test_tagRepo_GetTagByID(t *testing.T) { tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource)) gotTag, exist, err := tagCommonRepo.GetTagByID(context.TODO(), testTagList[0].ID, true) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, testTagList[0].SlugName, gotTag.SlugName) } @@ -85,7 +86,7 @@ func Test_tagRepo_GetTagBySlugName(t *testing.T) { tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource)) gotTag, exist, err := tagCommonRepo.GetTagBySlugName(context.TODO(), testTagList[0].SlugName) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, testTagList[0].SlugName, gotTag.SlugName) } @@ -95,7 +96,7 @@ func Test_tagRepo_GetTagList(t *testing.T) { tagRepo := tag.NewTagRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource)) gotTags, err := tagRepo.GetTagList(context.TODO(), &entity.Tag{ID: testTagList[0].ID}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName) } @@ -104,7 +105,7 @@ func Test_tagRepo_GetTagListByIDs(t *testing.T) { tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource)) gotTags, err := tagCommonRepo.GetTagListByIDs(context.TODO(), []string{testTagList[0].ID}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName) } @@ -113,7 +114,7 @@ func Test_tagRepo_GetTagListByName(t *testing.T) { tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource)) gotTags, err := tagCommonRepo.GetTagListByName(context.TODO(), testTagList[0].SlugName, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName) } @@ -122,7 +123,7 @@ func Test_tagRepo_GetTagListByNames(t *testing.T) { tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource)) gotTags, err := tagCommonRepo.GetTagListByNames(context.TODO(), []string{testTagList[0].SlugName}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName) } @@ -131,7 +132,7 @@ func Test_tagRepo_GetTagPage(t *testing.T) { tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource)) gotTags, _, err := tagCommonRepo.GetTagPage(context.TODO(), 1, 1, &entity.Tag{SlugName: testTagList[0].SlugName}, "") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testTagList[0].SlugName, gotTags[0].SlugName) } @@ -140,12 +141,12 @@ func Test_tagRepo_RemoveTag(t *testing.T) { uniqueIDRepo := unique.NewUniqueIDRepo(testDataSource) tagRepo := tag.NewTagRepo(testDataSource, uniqueIDRepo) err := tagRepo.RemoveTag(context.TODO(), testTagList[1].ID) - assert.NoError(t, err) + require.NoError(t, err) tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource)) _, exist, err := tagCommonRepo.GetTagBySlugName(context.TODO(), testTagList[1].SlugName) - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, exist) } @@ -155,12 +156,12 @@ func Test_tagRepo_UpdateTag(t *testing.T) { testTagList[0].DisplayName = "golang" err := tagRepo.UpdateTag(context.TODO(), testTagList[0]) - assert.NoError(t, err) + require.NoError(t, err) tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource)) gotTag, exist, err := tagCommonRepo.GetTagByID(context.TODO(), testTagList[0].ID, true) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, testTagList[0].DisplayName, gotTag.DisplayName) } @@ -170,10 +171,10 @@ func Test_tagRepo_UpdateTagQuestionCount(t *testing.T) { testTagList[0].DisplayName = "golang" err := tagCommonRepo.UpdateTagQuestionCount(context.TODO(), testTagList[0].ID, 100) - assert.NoError(t, err) + require.NoError(t, err) gotTag, exist, err := tagCommonRepo.GetTagByID(context.TODO(), testTagList[0].ID, true) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, 100, gotTag.QuestionCount) } @@ -184,16 +185,16 @@ func Test_tagRepo_UpdateTagSynonym(t *testing.T) { testTagList[0].DisplayName = "golang" err := tagRepo.UpdateTag(context.TODO(), testTagList[0]) - assert.NoError(t, err) + require.NoError(t, err) err = tagRepo.UpdateTagSynonym(context.TODO(), []string{testTagList[2].SlugName}, converter.StringToInt64(testTagList[0].ID), testTagList[0].SlugName) - assert.NoError(t, err) + require.NoError(t, err) tagCommonRepo := tag_common.NewTagCommonRepo(testDataSource, unique.NewUniqueIDRepo(testDataSource)) gotTag, exist, err := tagCommonRepo.GetTagByID(context.TODO(), testTagList[2].ID, true) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, testTagList[0].ID, fmt.Sprintf("%d", gotTag.MainTagID)) } diff --git a/internal/repo/repo_test/user_backyard_repo_test.go b/internal/repo/repo_test/user_backyard_repo_test.go index 073a600cf..eb4db102b 100644 --- a/internal/repo/repo_test/user_backyard_repo_test.go +++ b/internal/repo/repo_test/user_backyard_repo_test.go @@ -28,12 +28,13 @@ import ( "github.com/apache/answer/internal/repo/auth" "github.com/apache/answer/internal/repo/user" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func Test_userAdminRepo_GetUserInfo(t *testing.T) { userAdminRepo := user.NewUserAdminRepo(testDataSource, auth.NewAuthRepo(testDataSource)) got, exist, err := userAdminRepo.GetUserInfo(context.TODO(), "1") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, "1", got.ID) } @@ -41,7 +42,7 @@ func Test_userAdminRepo_GetUserInfo(t *testing.T) { func Test_userAdminRepo_GetUserPage(t *testing.T) { userAdminRepo := user.NewUserAdminRepo(testDataSource, auth.NewAuthRepo(testDataSource)) got, total, err := userAdminRepo.GetUserPage(context.TODO(), 1, 1, &entity.User{Username: "admin"}, "", false) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, int64(1), total) assert.Equal(t, "1", got[0].ID) } @@ -49,25 +50,25 @@ func Test_userAdminRepo_GetUserPage(t *testing.T) { func Test_userAdminRepo_UpdateUserStatus(t *testing.T) { userAdminRepo := user.NewUserAdminRepo(testDataSource, auth.NewAuthRepo(testDataSource)) got, exist, err := userAdminRepo.GetUserInfo(context.TODO(), "1") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, entity.UserStatusAvailable, got.Status) err = userAdminRepo.UpdateUserStatus(context.TODO(), "1", entity.UserStatusSuspended, entity.EmailStatusAvailable, "admin@admin.com", time.Now().Add(time.Minute*5)) - assert.NoError(t, err) + require.NoError(t, err) got, exist, err = userAdminRepo.GetUserInfo(context.TODO(), "1") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, entity.UserStatusSuspended, got.Status) err = userAdminRepo.UpdateUserStatus(context.TODO(), "1", entity.UserStatusAvailable, entity.EmailStatusAvailable, "admin@admin.com", time.Time{}) - assert.NoError(t, err) + require.NoError(t, err) got, exist, err = userAdminRepo.GetUserInfo(context.TODO(), "1") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, entity.UserStatusAvailable, got.Status) } diff --git a/internal/repo/repo_test/user_repo_test.go b/internal/repo/repo_test/user_repo_test.go index 7b18833dd..95a85ab99 100644 --- a/internal/repo/repo_test/user_repo_test.go +++ b/internal/repo/repo_test/user_repo_test.go @@ -26,6 +26,7 @@ import ( "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/repo/user" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func Test_userRepo_AddUser(t *testing.T) { @@ -40,21 +41,21 @@ func Test_userRepo_AddUser(t *testing.T) { IsAdmin: false, } err := userRepo.AddUser(context.TODO(), userInfo) - assert.NoError(t, err) + require.NoError(t, err) } func Test_userRepo_BatchGetByID(t *testing.T) { userRepo := user.NewUserRepo(testDataSource) got, err := userRepo.BatchGetByID(context.TODO(), []string{"1"}) - assert.NoError(t, err) - assert.Equal(t, 1, len(got)) + require.NoError(t, err) + assert.Len(t, got, 1) assert.Equal(t, "admin", got[0].Username) } func Test_userRepo_GetByEmail(t *testing.T) { userRepo := user.NewUserRepo(testDataSource) got, exist, err := userRepo.GetByEmail(context.TODO(), "admin@admin.com") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, "admin", got.Username) } @@ -62,7 +63,7 @@ func Test_userRepo_GetByEmail(t *testing.T) { func Test_userRepo_GetByUserID(t *testing.T) { userRepo := user.NewUserRepo(testDataSource) got, exist, err := userRepo.GetByUserID(context.TODO(), "1") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, "admin", got.Username) } @@ -70,7 +71,7 @@ func Test_userRepo_GetByUserID(t *testing.T) { func Test_userRepo_GetByUsername(t *testing.T) { userRepo := user.NewUserRepo(testDataSource) got, exist, err := userRepo.GetByUsername(context.TODO(), "admin") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, "admin", got.Username) } @@ -78,10 +79,10 @@ func Test_userRepo_GetByUsername(t *testing.T) { func Test_userRepo_IncreaseAnswerCount(t *testing.T) { userRepo := user.NewUserRepo(testDataSource) err := userRepo.IncreaseAnswerCount(context.TODO(), "1", 1) - assert.NoError(t, err) + require.NoError(t, err) got, exist, err := userRepo.GetByUserID(context.TODO(), "1") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, 1, got.AnswerCount) } @@ -89,10 +90,10 @@ func Test_userRepo_IncreaseAnswerCount(t *testing.T) { func Test_userRepo_IncreaseQuestionCount(t *testing.T) { userRepo := user.NewUserRepo(testDataSource) err := userRepo.IncreaseQuestionCount(context.TODO(), "1", 1) - assert.NoError(t, err) + require.NoError(t, err) got, exist, err := userRepo.GetByUserID(context.TODO(), "1") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, 1, got.AnswerCount) } @@ -100,22 +101,22 @@ func Test_userRepo_IncreaseQuestionCount(t *testing.T) { func Test_userRepo_UpdateEmail(t *testing.T) { userRepo := user.NewUserRepo(testDataSource) err := userRepo.UpdateEmail(context.TODO(), "1", "admin@admin.com") - assert.NoError(t, err) + require.NoError(t, err) } func Test_userRepo_UpdateEmailStatus(t *testing.T) { userRepo := user.NewUserRepo(testDataSource) err := userRepo.UpdateEmailStatus(context.TODO(), "1", entity.EmailStatusToBeVerified) - assert.NoError(t, err) + require.NoError(t, err) } func Test_userRepo_UpdateInfo(t *testing.T) { userRepo := user.NewUserRepo(testDataSource) err := userRepo.UpdateInfo(context.TODO(), &entity.User{ID: "1", Bio: "test"}) - assert.NoError(t, err) + require.NoError(t, err) got, exist, err := userRepo.GetByUserID(context.TODO(), "1") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, exist) assert.Equal(t, "test", got.Bio) } @@ -123,17 +124,17 @@ func Test_userRepo_UpdateInfo(t *testing.T) { func Test_userRepo_UpdateLastLoginDate(t *testing.T) { userRepo := user.NewUserRepo(testDataSource) err := userRepo.UpdateLastLoginDate(context.TODO(), "1") - assert.NoError(t, err) + require.NoError(t, err) } func Test_userRepo_UpdateNoticeStatus(t *testing.T) { userRepo := user.NewUserRepo(testDataSource) err := userRepo.UpdateNoticeStatus(context.TODO(), "1", 1) - assert.NoError(t, err) + require.NoError(t, err) } func Test_userRepo_UpdatePass(t *testing.T) { userRepo := user.NewUserRepo(testDataSource) err := userRepo.UpdatePass(context.TODO(), "1", "admin") - assert.NoError(t, err) + require.NoError(t, err) } diff --git a/internal/repo/search_common/search_repo.go b/internal/repo/search_common/search_repo.go index 806517234..a56b8edb6 100644 --- a/internal/repo/search_common/search_repo.go +++ b/internal/repo/search_common/search_repo.go @@ -190,7 +190,7 @@ func (sr *searchRepo) SearchContents(ctx context.Context, words []string, tagIDs argsA = append(argsA, votes) } - //b = b.Union("all", ub) + // b = b.Union("all", ub) ubSQL, _, err := ub.ToSQL() if err != nil { return @@ -447,7 +447,7 @@ func (sr *searchRepo) SearchAnswers(ctx context.Context, words []string, tagIDs return } -func (sr *searchRepo) parseOrder(ctx context.Context, order string) (res string) { +func (sr *searchRepo) parseOrder(_ context.Context, order string) (res string) { switch order { case "newest": res = "created_at desc" diff --git a/internal/schema/backyard_user_schema.go b/internal/schema/backyard_user_schema.go index 6ec848721..d36ff8083 100644 --- a/internal/schema/backyard_user_schema.go +++ b/internal/schema/backyard_user_schema.go @@ -222,7 +222,7 @@ func (req *AddUsersReq) ParseUsers(ctx context.Context) (errFields []*validator. } // check users amount - if len(req.Users) <= 0 || len(req.Users) > constant.DefaultBulkUser { + if len(req.Users) == 0 || len(req.Users) > constant.DefaultBulkUser { errFields = append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "users", ErrorMsg: translator.TrWithData(handler.GetLangByCtx(ctx), reason.AddBulkUsersAmountError, diff --git a/internal/schema/meta_schema.go b/internal/schema/meta_schema.go index 286e2e7d6..e5a072529 100644 --- a/internal/schema/meta_schema.go +++ b/internal/schema/meta_schema.go @@ -19,6 +19,8 @@ package schema +import "slices" + type UpdateReactionReq struct { ObjectID string `validate:"required" json:"object_id"` Emoji string `validate:"required,oneof=heart smile frown" json:"emoji"` @@ -48,13 +50,7 @@ func (r *ReactionsSummaryMeta) AddReactionSummary(emoji, userID string) { if reaction.Emoji != emoji { continue } - exist := false - for _, id := range reaction.UserIDs { - if id == userID { - exist = true - break - } - } + exist := slices.Contains(reaction.UserIDs, userID) if !exist { reaction.UserIDs = append(reaction.UserIDs, userID) } @@ -94,10 +90,8 @@ func (r *ReactionsSummaryMeta) CheckUserInReactionSummary(emoji, userID string) if reaction.Emoji != emoji { continue } - for _, id := range reaction.UserIDs { - if id == userID { - return true - } + if slices.Contains(reaction.UserIDs, userID) { + return true } } return false diff --git a/internal/schema/notification_schema.go b/internal/schema/notification_schema.go index e5d60615e..b9e029389 100644 --- a/internal/schema/notification_schema.go +++ b/internal/schema/notification_schema.go @@ -53,7 +53,7 @@ var NotificationInboxType = map[string]int{ type NotificationContent struct { ID string `json:"id"` - TriggerUserID string `json:"-"` //show userid + TriggerUserID string `json:"-"` // show userid ReceiverUserID string `json:"-"` // receiver userid UserInfo *UserBasicInfo `json:"user_info,omitempty"` ObjectInfo ObjectInfo `json:"object_info"` @@ -169,8 +169,8 @@ func (r *RedDotBadgeAwardCache) RemoveBadgeAward(notificationID string) { } type NotificationSearch struct { - Page int `json:"page" form:"page"` //Query number of pages - PageSize int `json:"page_size" form:"page_size"` //Search page size + Page int `json:"page" form:"page"` // Query number of pages + PageSize int `json:"page_size" form:"page_size"` // Search page size Type int `json:"-" form:"-"` TypeStr string `json:"type" form:"type"` // inbox achievement InboxTypeStr string `json:"inbox_type" form:"inbox_type"` // inbox achievement diff --git a/internal/schema/revision_schema.go b/internal/schema/revision_schema.go index b3ac0aadd..6f3246e51 100644 --- a/internal/schema/revision_schema.go +++ b/internal/schema/revision_schema.go @@ -53,7 +53,7 @@ const RevisionAuditReject = "reject" type RevisionAuditReq struct { // object id ID string `validate:"required" comment:"id" form:"id"` - Operation string `validate:"required" comment:"operation" form:"operation"` //approve or reject + Operation string `validate:"required" comment:"operation" form:"operation"` // approve or reject UserID string `json:"-"` CanReviewQuestion bool `json:"-"` CanReviewAnswer bool `json:"-"` diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index 0e43bb420..7ab657512 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -52,7 +52,7 @@ func (r *SiteGeneralReq) FormatSiteUrl() { } r.SiteUrl = fmt.Sprintf("%s://%s", parsedUrl.Scheme, parsedUrl.Host) if len(parsedUrl.Path) > 0 { - r.SiteUrl = r.SiteUrl + parsedUrl.Path + r.SiteUrl += parsedUrl.Path r.SiteUrl = strings.TrimSuffix(r.SiteUrl, "/") } } diff --git a/internal/schema/tag_schema.go b/internal/schema/tag_schema.go index a51b2d2d5..8eb3212c4 100644 --- a/internal/schema/tag_schema.go +++ b/internal/schema/tag_schema.go @@ -109,7 +109,7 @@ type GetTagPageResp struct { DisplayName string `json:"display_name"` // excerpt Excerpt string `json:"excerpt"` - //description + // description Description string `json:"description"` // original text OriginalText string `json:"original_text"` diff --git a/internal/service/action/captcha_strategy.go b/internal/service/action/captcha_strategy.go index b423b583b..edda73252 100644 --- a/internal/service/action/captcha_strategy.go +++ b/internal/service/action/captcha_strategy.go @@ -67,9 +67,8 @@ func (cs *CaptchaService) ValidationStrategy(ctx context.Context, unit, actionTy return cs.CaptchaActionDelete(ctx, unit, info) case entity.CaptchaActionVote: return cs.CaptchaActionVote(ctx, unit, info) - } - //actionType not found + // actionType not found return false } @@ -83,7 +82,7 @@ func (cs *CaptchaService) CaptchaActionPassword(ctx context.Context, unit string return true } setNum := 3 - setTime := int64(60 * 30) //seconds + setTime := int64(60 * 30) // seconds now := time.Now().Unix() if now-actionInfo.LastTime <= setTime && actionInfo.Num >= setNum { return false @@ -101,7 +100,7 @@ func (cs *CaptchaService) CaptchaActionEditUserinfo(ctx context.Context, unit st return true } setNum := 3 - setTime := int64(60 * 30) //seconds + setTime := int64(60 * 30) // seconds now := time.Now().Unix() if now-actionInfo.LastTime <= setTime && actionInfo.Num >= setNum { return false @@ -119,7 +118,7 @@ func (cs *CaptchaService) CaptchaActionQuestion(ctx context.Context, unit string return true } setNum := 10 - setTime := int64(5) //seconds + setTime := int64(5) // seconds now := time.Now().Unix() if now-actionInfo.LastTime <= setTime || actionInfo.Num >= setNum { return false @@ -132,7 +131,7 @@ func (cs *CaptchaService) CaptchaActionAnswer(ctx context.Context, unit string, return true } setNum := 10 - setTime := int64(5) //seconds + setTime := int64(5) // seconds now := time.Now().Unix() if now-actionInfo.LastTime <= setTime || actionInfo.Num >= setNum { return false @@ -145,7 +144,7 @@ func (cs *CaptchaService) CaptchaActionComment(ctx context.Context, unit string, return true } setNum := 30 - setTime := int64(1) //seconds + setTime := int64(1) // seconds now := time.Now().Unix() if now-actionInfo.LastTime <= setTime || actionInfo.Num >= setNum { return false @@ -175,8 +174,8 @@ func (cs *CaptchaService) CaptchaActionSearch(ctx context.Context, unit string, } now := time.Now().Unix() setNum := 20 - setTime := int64(60) //seconds - if now-int64(actionInfo.LastTime) <= setTime && actionInfo.Num >= setNum { + setTime := int64(60) // seconds + if now-actionInfo.LastTime <= setTime && actionInfo.Num >= setNum { return false } if now-actionInfo.LastTime > setTime { @@ -192,7 +191,7 @@ func (cs *CaptchaService) CaptchaActionReport(ctx context.Context, unit string, return true } setNum := 30 - setTime := int64(1) //seconds + setTime := int64(1) // seconds now := time.Now().Unix() if now-actionInfo.LastTime <= setTime || actionInfo.Num >= setNum { return false @@ -205,7 +204,7 @@ func (cs *CaptchaService) CaptchaActionDelete(ctx context.Context, unit string, return true } setNum := 5 - setTime := int64(5) //seconds + setTime := int64(5) // seconds now := time.Now().Unix() if now-actionInfo.LastTime <= setTime || actionInfo.Num >= setNum { return false diff --git a/internal/service/auth/auth.go b/internal/service/auth/auth.go index 9ee5f3ee0..b94f7912a 100644 --- a/internal/service/auth/auth.go +++ b/internal/service/auth/auth.go @@ -138,7 +138,7 @@ func (as *AuthService) RemoveTokensExceptCurrentUser(ctx context.Context, userID as.authRepo.RemoveUserTokens(ctx, userID, accessToken) } -//Admin +// Admin func (as *AuthService) GetAdminUserCacheInfo(ctx context.Context, accessToken string) (userInfo *entity.UserCacheInfo, err error) { return as.authRepo.GetAdminUserCacheInfo(ctx, accessToken) diff --git a/internal/service/comment/comment_service.go b/internal/service/comment/comment_service.go index 3a5b3e6c9..dc599e6df 100644 --- a/internal/service/comment/comment_service.go +++ b/internal/service/comment/comment_service.go @@ -178,9 +178,8 @@ func (cs *CommentService) AddComment(ctx context.Context, req *schema.AddComment time.Now(), req.CanEdit, req.CanDelete) if comment.Status == entity.CommentStatusAvailable { - commentResp, err := cs.addCommentNotification(ctx, req, resp, comment, objInfo) - if err != nil { - return commentResp, err + if err := cs.addCommentNotification(ctx, req, resp, comment, objInfo); err != nil { + return nil, err } } @@ -220,7 +219,7 @@ func (cs *CommentService) AddComment(ctx context.Context, req *schema.AddComment func (cs *CommentService) addCommentNotification( ctx context.Context, req *schema.AddCommentReq, resp *schema.GetCommentResp, - comment *entity.Comment, objInfo *schema.SimpleObjectInfo) (*schema.GetCommentResp, error) { + comment *entity.Comment, objInfo *schema.SimpleObjectInfo) error { // The priority of the notification // 1. reply to user // 2. comment mention to user @@ -231,7 +230,7 @@ func (cs *CommentService) addCommentNotification( if len(resp.ReplyUserID) > 0 && resp.ReplyUserID != req.UserID { replyUser, exist, err := cs.userCommon.GetUserBasicInfoByID(ctx, resp.ReplyUserID) if err != nil { - return nil, err + return err } if exist { resp.ReplyUsername = replyUser.Username @@ -241,7 +240,7 @@ func (cs *CommentService) addCommentNotification( cs.notificationCommentReply(ctx, replyUser.ID, comment.ID, req.UserID, objInfo.QuestionID, objInfo.Title, htmltext.FetchExcerpt(comment.ParsedText, "...", 240)) alreadyNotifiedUserID[replyUser.ID] = true - return nil, nil + return nil } if len(req.MentionUsernameList) > 0 { @@ -250,7 +249,7 @@ func (cs *CommentService) addCommentNotification( for _, userID := range alreadyNotifiedUserIDs { alreadyNotifiedUserID[userID] = true } - return nil, nil + return nil } if objInfo.ObjectType == constant.QuestionObjectType && !alreadyNotifiedUserID[objInfo.ObjectCreatorUserID] { @@ -260,7 +259,7 @@ func (cs *CommentService) addCommentNotification( cs.notificationAnswerComment(ctx, objInfo.QuestionID, objInfo.Title, objInfo.AnswerID, objInfo.ObjectCreatorUserID, comment.ID, req.UserID, htmltext.FetchExcerpt(comment.ParsedText, "...", 240)) } - return nil, nil + return nil } // RemoveComment delete comment diff --git a/internal/service/content/answer_service.go b/internal/service/content/answer_service.go index 982bbf88a..f904b82f0 100644 --- a/internal/service/content/answer_service.go +++ b/internal/service/content/answer_service.go @@ -146,7 +146,6 @@ func (as *AnswerService) RemoveAnswer(ctx context.Context, req *schema.RemoveAns if !exist { return errors.BadRequest(reason.AnswerCannotDeleted) } - } err = as.answerRepo.RemoveAnswer(ctx, req.ID) @@ -180,10 +179,10 @@ func (as *AnswerService) RemoveAnswer(ctx context.Context, req *schema.RemoveAns // #2372 In order to simplify the process and complexity, as well as to consider if it is in-house, // facing the problem of recovery. - //err = as.answerActivityService.DeleteAnswer(ctx, answerInfo.ID, answerInfo.CreatedAt, answerInfo.VoteCount) - //if err != nil { - // log.Errorf("delete answer activity change failed: %s", err.Error()) - //} + // err = as.answerActivityService.DeleteAnswer(ctx, answerInfo.ID, answerInfo.CreatedAt, answerInfo.VoteCount) + // if err != nil { + // log.Errorf("delete answer activity change failed: %s", err.Error()) + // } as.activityQueueService.Send(ctx, &schema.ActivityMsg{ UserID: req.UserID, TriggerUserID: converter.StringToInt64(req.UserID), @@ -264,7 +263,7 @@ func (as *AnswerService) Insert(ctx context.Context, req *schema.AnswerAddReq) ( insertData.RevisionID = "0" insertData.LastEditUserID = "0" insertData.Status = entity.AnswerStatusPending - //insertData.UpdatedAt = now + // insertData.UpdatedAt = now if err = as.answerRepo.AddAnswer(ctx, insertData); err != nil { return "", err } @@ -365,7 +364,7 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq return "", errors.BadRequest(reason.QuestionNotFound) } - //If the content is the same, ignore it + // If the content is the same, ignore it if answerInfo.OriginalText == req.Content { return "", nil } diff --git a/internal/service/content/question_hottest_service.go b/internal/service/content/question_hottest_service.go index 085b36709..b73e7a30d 100644 --- a/internal/service/content/question_hottest_service.go +++ b/internal/service/content/question_hottest_service.go @@ -30,7 +30,6 @@ import ( ) func (q *QuestionService) RefreshHottestCron(ctx context.Context) { - var ( page = 1 pageSize = 100 diff --git a/internal/service/content/question_service.go b/internal/service/content/question_service.go index da15fae5d..b8372a72e 100644 --- a/internal/service/content/question_service.go +++ b/internal/service/content/question_service.go @@ -216,9 +216,9 @@ func (qs *QuestionService) ReopenQuestion(ctx context.Context, req *schema.Reope return nil } -func (qs *QuestionService) AddQuestionCheckTags(ctx context.Context, Tags []*entity.Tag) ([]string, error) { +func (qs *QuestionService) AddQuestionCheckTags(ctx context.Context, tags []*entity.Tag) ([]string, error) { list := make([]string, 0) - for _, tag := range Tags { + for _, tag := range tags { if tag.Reserved { list = append(list, tag.DisplayName) } @@ -374,14 +374,14 @@ func (qs *QuestionService) AddQuestion(ctx context.Context, req *schema.Question question.AcceptedAnswerID = "0" question.LastAnswerID = "0" question.LastEditUserID = "0" - //question.PostUpdateTime = nil + // question.PostUpdateTime = nil question.Status = entity.QuestionStatusPending question.RevisionID = "0" question.CreatedAt = now question.PostUpdateTime = now question.Pin = entity.QuestionUnPin question.Show = entity.QuestionShow - //question.UpdatedAt = nil + // question.UpdatedAt = nil err = qs.questionRepo.AddQuestion(ctx, question) if err != nil { return @@ -416,10 +416,7 @@ func (qs *QuestionService) AddQuestion(ctx context.Context, req *schema.Question Title: question.Title, } - questionWithTagsRevision, err := qs.changeQuestionToRevision(ctx, question, tags) - if err != nil { - return nil, err - } + questionWithTagsRevision := qs.changeQuestionToRevision(ctx, question, tags) infoJSON, _ := json.Marshal(questionWithTagsRevision) revisionDTO.Content = string(infoJSON) revisionID, err := qs.revisionService.AddRevision(ctx, revisionDTO, true) @@ -554,7 +551,7 @@ func (qs *QuestionService) RemoveQuestion(ctx context.Context, req *schema.Remov if err != nil { return err } - //if the status is deleted, return directly + // if the status is deleted, return directly if questionInfo.Status == entity.QuestionStatusDeleted { return nil } @@ -613,7 +610,7 @@ func (qs *QuestionService) RemoveQuestion(ctx context.Context, req *schema.Remov } } - //tag count + // tag count tagIDs := make([]string, 0) Tags, tagerr := qs.tagCommon.GetObjectEntityTag(ctx, req.ID) if tagerr != nil { @@ -684,7 +681,7 @@ func (qs *QuestionService) UpdateQuestionCheckTags(ctx context.Context, req *sch isChange := qs.tagCommon.CheckTagsIsChange(ctx, tagNameList, oldtagNameList) - //If the content is the same, ignore it + // If the content is the same, ignore it if dbinfo.Title == req.Title && dbinfo.OriginalText == req.Content && !isChange { return } @@ -798,7 +795,7 @@ func (qs *QuestionService) UpdateQuestionInviteUser(ctx context.Context, req *sc return errors.BadRequest(reason.QuestionNotFound) } - //verify invite user + // verify invite user inviteUserInfoList, err := qs.userCommon.BatchGetUserBasicInfoByUserNames(ctx, req.InviteUser) if err != nil { log.Error("BatchGetUserBasicInfoByUserNames error", err.Error()) @@ -826,7 +823,7 @@ func (qs *QuestionService) UpdateQuestionInviteUser(ctx context.Context, req *sc if saveerr != nil { return saveerr } - //send notification + // send notification oldInviteUserIDsStr := originQuestion.InviteUserID oldInviteUserIDs := make([]string, 0) needSendNotificationUserIDs := make([]string, 0) @@ -964,7 +961,7 @@ func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.Quest isChange := qs.tagCommon.CheckTagsIsChange(ctx, tagNameList, oldtagNameList) - //If the content is the same, ignore it + // If the content is the same, ignore it if dbinfo.Title == req.Title && dbinfo.OriginalText == req.Content && !isChange { return } @@ -1015,7 +1012,7 @@ func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.Quest return errorlist, err } - //Administrators and themselves do not need to be audited + // Administrators and themselves do not need to be audited revisionDTO := &schema.AddRevisionDTO{ UserID: question.UserID, @@ -1031,11 +1028,11 @@ func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.Quest // It's not you or the administrator that needs to be reviewed if !canUpdate { revisionDTO.Status = entity.RevisionUnreviewedStatus - revisionDTO.UserID = req.UserID //use revision userid + revisionDTO.UserID = req.UserID // use revision userid } else { - //Direct modification + // Direct modification revisionDTO.Status = entity.RevisionReviewPassStatus - //update question to db + // update question to db question.ParsedText, err = qs.questioncommon.UpdateQuestionLink(ctx, question.ID, "", question.ParsedText, question.OriginalText) if err != nil { return questionInfo, err @@ -1054,10 +1051,7 @@ func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.Quest } } - questionWithTagsRevision, err := qs.changeQuestionToRevision(ctx, question, Tags) - if err != nil { - return nil, err - } + questionWithTagsRevision := qs.changeQuestionToRevision(ctx, question, Tags) infoJSON, _ := json.Marshal(questionWithTagsRevision) revisionDTO.Content = string(infoJSON) revisionID, err := qs.revisionService.AddRevision(ctx, revisionDTO, true) @@ -1165,7 +1159,6 @@ func (qs *QuestionService) CheckChangeReservedTag(ctx context.Context, oldobject // PersonalQuestionPage get question list by user func (qs *QuestionService) PersonalQuestionPage(ctx context.Context, req *schema.PersonalQuestionPageReq) ( pageModel *pager.PageModel, err error) { - userinfo, exist, err := qs.userCommon.GetUserBasicInfoByUserName(ctx, req.Username) if err != nil { return nil, err @@ -1250,7 +1243,6 @@ func (qs *QuestionService) PersonalAnswerPage(ctx context.Context, req *schema.P info.QuestionID = item.QuestionID if item.QuestionInfo.Status == entity.QuestionStatusDeleted { info.QuestionInfo.Title = "Deleted question" - } userAnswerlist = append(userAnswerlist, info) } @@ -1489,7 +1481,8 @@ func (qs *QuestionService) GetQuestionPage(ctx context.Context, req *schema.Ques if err != nil { return nil, 0, err } - tagIDs = append(synTagIds, tagInfo.ID) + tagIDs = append(tagIDs, synTagIds...) + tagIDs = append(tagIDs, tagInfo.ID) } else { return questions, 0, nil } @@ -1585,10 +1578,10 @@ func (qs *QuestionService) AdminSetQuestionStatus(ctx context.Context, req *sche if setStatus == entity.QuestionStatusDeleted { // #2372 In order to simplify the process and complexity, as well as to consider if it is in-house, // facing the problem of recovery. - //err = qs.answerActivityService.DeleteQuestion(ctx, questionInfo.ID, questionInfo.CreatedAt, questionInfo.VoteCount) - //if err != nil { - // log.Errorf("admin delete question then rank rollback error %s", err.Error()) - //} + // err = qs.answerActivityService.DeleteQuestion(ctx, questionInfo.ID, questionInfo.CreatedAt, questionInfo.VoteCount) + // if err != nil { + // log.Errorf("admin delete question then rank rollback error %s", err.Error()) + // } qs.activityQueueService.Send(ctx, &schema.ActivityMsg{ UserID: questionInfo.UserID, TriggerUserID: converter.StringToInt64(req.UserID), @@ -1642,7 +1635,6 @@ func (qs *QuestionService) AdminSetQuestionStatus(ctx context.Context, req *sche func (qs *QuestionService) AdminQuestionPage( ctx context.Context, req *schema.AdminQuestionPageReq) ( resp *pager.PageModel, err error) { - list := make([]*schema.AdminQuestionInfo, 0) questionList, count, err := qs.questionRepo.AdminQuestionPage(ctx, req) if err != nil { @@ -1708,8 +1700,8 @@ func (qs *QuestionService) AdminAnswerPage(ctx context.Context, req *schema.Admi return pager.NewPageModel(count, answerResp), nil } -func (qs *QuestionService) changeQuestionToRevision(ctx context.Context, questionInfo *entity.Question, tags []*entity.Tag) ( - questionRevision *entity.QuestionWithTagsRevision, err error) { +func (qs *QuestionService) changeQuestionToRevision(_ context.Context, questionInfo *entity.Question, tags []*entity.Tag) ( + questionRevision *entity.QuestionWithTagsRevision) { questionRevision = &entity.QuestionWithTagsRevision{} questionRevision.Question = *questionInfo @@ -1718,7 +1710,7 @@ func (qs *QuestionService) changeQuestionToRevision(ctx context.Context, questio _ = copier.Copy(item, tag) questionRevision.Tags = append(questionRevision.Tags, item) } - return questionRevision, nil + return questionRevision } func (qs *QuestionService) SitemapCron(ctx context.Context) { diff --git a/internal/service/content/revision_service.go b/internal/service/content/revision_service.go index a5cefeb41..4ac08e769 100644 --- a/internal/service/content/revision_service.go +++ b/internal/service/content/revision_service.go @@ -235,7 +235,6 @@ func (rs *RevisionService) revisionAuditQuestion(ctx context.Context, revisionit func (rs *RevisionService) revisionAuditAnswer(ctx context.Context, revisionitem *schema.GetRevisionResp) (err error) { answerinfo, ok := revisionitem.ContentParsed.(*schema.AnswerInfo) if ok { - var PostUpdateTime time.Time dbquestion, exist, dberr := rs.questionRepo.GetQuestion(ctx, answerinfo.QuestionID) if dberr != nil || !exist { diff --git a/internal/service/content/search_service.go b/internal/service/content/search_service.go index ccafcd82c..866f1c6e2 100644 --- a/internal/service/content/search_service.go +++ b/internal/service/content/search_service.go @@ -68,13 +68,14 @@ func (ss *SearchService) Search(ctx context.Context, dto *schema.SearchDTO) (res resp = &schema.SearchResp{} // search plugin is not found, call system search if finder == nil { - if cond.SearchAll() { + switch { + case cond.SearchAll(): resp.SearchResults, resp.Total, err = ss.searchRepo.SearchContents(ctx, cond.Words, cond.Tags, cond.UserID, cond.VoteAmount, dto.Page, dto.Size, dto.Order) - } else if cond.SearchQuestion() { + case cond.SearchQuestion(): resp.SearchResults, resp.Total, err = ss.searchRepo.SearchQuestions(ctx, cond.Words, cond.Tags, cond.NotAccepted, cond.Views, cond.AnswerAmount, dto.Page, dto.Size, dto.Order) - } else if cond.SearchAnswer() { + case cond.SearchAnswer(): resp.SearchResults, resp.Total, err = ss.searchRepo.SearchAnswers(ctx, cond.Words, cond.Tags, cond.Accepted, cond.QuestionID, dto.Page, dto.Size, dto.Order) } @@ -86,11 +87,12 @@ func (ss *SearchService) Search(ctx context.Context, dto *schema.SearchDTO) (res func (ss *SearchService) searchByPlugin(ctx context.Context, finder plugin.Search, cond *schema.SearchCondition, dto *schema.SearchDTO) (resp *schema.SearchResp, err error) { var res []plugin.SearchResult resp = &schema.SearchResp{} - if cond.SearchAll() { + switch { + case cond.SearchAll(): res, resp.Total, err = finder.SearchContents(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order)) - } else if cond.SearchQuestion() { + case cond.SearchQuestion(): res, resp.Total, err = finder.SearchQuestions(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order)) - } else if cond.SearchAnswer() { + case cond.SearchAnswer(): res, resp.Total, err = finder.SearchAnswers(ctx, cond.Convert2PluginSearchCond(dto.Page, dto.Size, dto.Order)) } if err != nil { diff --git a/internal/service/content/user_service.go b/internal/service/content/user_service.go index 81f7ac824..e9cc35788 100644 --- a/internal/service/content/user_service.go +++ b/internal/service/content/user_service.go @@ -314,7 +314,6 @@ func (us *UserService) UserModifyPassword(ctx context.Context, req *schema.UserM // UpdateInfo update user info func (us *UserService) UpdateInfo(ctx context.Context, req *schema.UpdateInfoRequest) ( errFields []*validator.FormErrorField, err error) { - if len(req.Username) > 0 { if checker.IsInvalidUsername(req.Username) { return append(errFields, &validator.FormErrorField{ @@ -598,7 +597,7 @@ func (us *UserService) UserVerifyEmail(ctx context.Context, req *schema.UserVeri // verifyPassword // Compare whether the password is correct -func (us *UserService) verifyPassword(ctx context.Context, loginPass, userPass string) bool { +func (us *UserService) verifyPassword(_ context.Context, loginPass, userPass string) bool { if len(loginPass) == 0 && len(userPass) == 0 { return true } @@ -608,8 +607,8 @@ func (us *UserService) verifyPassword(ctx context.Context, loginPass, userPass s // encryptPassword // The password does irreversible encryption. -func (us *UserService) encryptPassword(ctx context.Context, Pass string) (string, error) { - hashPwd, err := bcrypt.GenerateFromPassword([]byte(Pass), bcrypt.DefaultCost) +func (us *UserService) encryptPassword(_ context.Context, pass string) (string, error) { + hashPwd, err := bcrypt.GenerateFromPassword([]byte(pass), bcrypt.DefaultCost) // This encrypted string can be saved to the database and can be used as password matching verification return string(hashPwd), err } diff --git a/internal/service/dashboard/dashboard_service.go b/internal/service/dashboard/dashboard_service.go index 91f0e338a..8b08ba02f 100644 --- a/internal/service/dashboard/dashboard_service.go +++ b/internal/service/dashboard/dashboard_service.go @@ -264,7 +264,7 @@ func (ds *dashboardService) voteCount(ctx context.Context) int64 { return voteCount } -func (ds *dashboardService) remoteVersion(ctx context.Context) string { +func (ds *dashboardService) remoteVersion(_ context.Context) string { req, _ := http.NewRequest("GET", "https://answer.apache.org/data/latest.json?from_version="+constant.Version, nil) req.Header.Set("User-Agent", "Answer/"+constant.Version) httpClient := &http.Client{} @@ -359,11 +359,9 @@ func (ds *dashboardService) GetDatabaseSize() (dbSize string) { res, err := ds.data.DB.QueryInterface(sql) if err != nil { log.Warnf("get db size failed: %s", err) - } else { - if len(res) > 0 && res[0]["db_size"] != nil { - dbSizeStr, _ := res[0]["db_size"].(string) - dbSize = dir.FormatFileSize(converter.StringToInt64(dbSizeStr)) - } + } else if len(res) > 0 && res[0]["db_size"] != nil { + dbSizeStr, _ := res[0]["db_size"].(string) + dbSize = dir.FormatFileSize(converter.StringToInt64(dbSizeStr)) } case schemas.POSTGRES: sql := fmt.Sprintf("SELECT pg_database_size('%s') AS db_size", @@ -371,11 +369,9 @@ func (ds *dashboardService) GetDatabaseSize() (dbSize string) { res, err := ds.data.DB.QueryInterface(sql) if err != nil { log.Warnf("get db size failed: %s", err) - } else { - if len(res) > 0 && res[0]["db_size"] != nil { - dbSizeStr, _ := res[0]["db_size"].(int32) - dbSize = dir.FormatFileSize(int64(dbSizeStr)) - } + } else if len(res) > 0 && res[0]["db_size"] != nil { + dbSizeStr, _ := res[0]["db_size"].(int32) + dbSize = dir.FormatFileSize(int64(dbSizeStr)) } case schemas.SQLITE: dirSize, err := dir.DirSize(ds.data.DB.DataSourceName()) diff --git a/internal/service/notification/invite_answer_notification.go b/internal/service/notification/invite_answer_notification.go index f68feb067..6b0407f9f 100644 --- a/internal/service/notification/invite_answer_notification.go +++ b/internal/service/notification/invite_answer_notification.go @@ -45,8 +45,7 @@ func (ns *ExternalNotificationService) handleInviteAnswerNotification(ctx contex if !channel.Enable { continue } - switch channel.Key { - case constant.EmailChannel: + if channel.Key == constant.EmailChannel { ns.sendInviteAnswerNotificationEmail(ctx, msg.ReceiverUserID, msg.ReceiverEmail, msg.ReceiverLang, msg.NewInviteAnswerTemplateRawData) } } diff --git a/internal/service/notification/new_answer_notification.go b/internal/service/notification/new_answer_notification.go index c54fd961c..4ae9ca9ea 100644 --- a/internal/service/notification/new_answer_notification.go +++ b/internal/service/notification/new_answer_notification.go @@ -45,8 +45,7 @@ func (ns *ExternalNotificationService) handleNewAnswerNotification(ctx context.C if !channel.Enable { continue } - switch channel.Key { - case constant.EmailChannel: + if channel.Key == constant.EmailChannel { ns.sendNewAnswerNotificationEmail(ctx, msg.ReceiverUserID, msg.ReceiverEmail, msg.ReceiverLang, msg.NewAnswerTemplateRawData) } } diff --git a/internal/service/notification/new_comment_notification.go b/internal/service/notification/new_comment_notification.go index e622ed4f7..9734e54e5 100644 --- a/internal/service/notification/new_comment_notification.go +++ b/internal/service/notification/new_comment_notification.go @@ -45,8 +45,7 @@ func (ns *ExternalNotificationService) handleNewCommentNotification(ctx context. if !channel.Enable { continue } - switch channel.Key { - case constant.EmailChannel: + if channel.Key == constant.EmailChannel { ns.sendNewCommentNotificationEmail(ctx, msg.ReceiverUserID, msg.ReceiverEmail, msg.ReceiverLang, msg.NewCommentTemplateRawData) } } diff --git a/internal/service/notification/new_question_notification.go b/internal/service/notification/new_question_notification.go index debfb8c27..2f83042b2 100644 --- a/internal/service/notification/new_question_notification.go +++ b/internal/service/notification/new_question_notification.go @@ -55,8 +55,7 @@ func (ns *ExternalNotificationService) handleNewQuestionNotification(ctx context if !channel.Enable { continue } - switch channel.Key { - case constant.EmailChannel: + if channel.Key == constant.EmailChannel { ns.sendNewQuestionNotificationEmail(ctx, subscriber.UserID, &schema.NewQuestionTemplateRawData{ QuestionTitle: msg.NewQuestionTemplateRawData.QuestionTitle, QuestionID: msg.NewQuestionTemplateRawData.QuestionID, diff --git a/internal/service/notification/notification_service.go b/internal/service/notification/notification_service.go index 0369d4557..6a69cbaef 100644 --- a/internal/service/notification/notification_service.go +++ b/internal/service/notification/notification_service.go @@ -226,15 +226,12 @@ func (ns *NotificationService) GetNotificationPage(ctx context.Context, searchCo if err != nil { return nil, err } - resp, err = ns.formatNotificationPage(ctx, notifications) - if err != nil { - return nil, err - } + resp = ns.formatNotificationPage(ctx, notifications) return pager.NewPageModel(total, resp), nil } func (ns *NotificationService) formatNotificationPage(ctx context.Context, notifications []*entity.Notification) ( - resp []*schema.NotificationContent, err error) { + resp []*schema.NotificationContent) { lang := handler.GetLangByCtx(ctx) enableShortID := handler.GetEnableShortID(ctx) userIDs := make([]string, 0) @@ -287,13 +284,13 @@ func (ns *NotificationService) formatNotificationPage(ctx context.Context, notif } if len(userIDs) == 0 { - return resp, nil + return resp } users, err := ns.userRepo.BatchGetByID(ctx, userIDs) if err != nil { log.Error(err) - return resp, nil + return resp } userIDMapping := make(map[string]*entity.User, len(users)) for _, user := range users { @@ -314,5 +311,5 @@ func (ns *NotificationService) formatNotificationPage(ctx context.Context, notif } } } - return resp, nil + return resp } diff --git a/internal/service/notification_common/notification.go b/internal/service/notification_common/notification.go index 55d638424..0bbd1865f 100644 --- a/internal/service/notification_common/notification.go +++ b/internal/service/notification_common/notification.go @@ -155,7 +155,7 @@ func (ns *NotificationCommon) AddNotification(ctx context.Context, msg *schema.N } req.Rank = rank if exist { - //modify notification + // modify notification updateContent := &schema.NotificationContent{} err := json.Unmarshal([]byte(notificationInfo.Content), updateContent) if err != nil { diff --git a/internal/service/plugin_common/plugin_common_service.go b/internal/service/plugin_common/plugin_common_service.go index d3aa839b2..7d39a5aa0 100644 --- a/internal/service/plugin_common/plugin_common_service.go +++ b/internal/service/plugin_common/plugin_common_service.go @@ -69,7 +69,6 @@ func NewPluginCommonService( data *data.Data, importerService *importer.ImporterService, ) *PluginCommonService { - p := &PluginCommonService{ configService: configService, pluginConfigRepo: pluginConfigRepo, diff --git a/internal/service/question_common/question.go b/internal/service/question_common/question.go index 333806445..846dea894 100644 --- a/internal/service/question_common/question.go +++ b/internal/service/question_common/question.go @@ -179,17 +179,17 @@ func (qs *QuestionCommon) UpdateCollectionCount(ctx context.Context, questionID return qs.questionRepo.UpdateCollectionCount(ctx, questionID) } -func (qs *QuestionCommon) UpdateAccepted(ctx context.Context, questionID, AnswerID string) error { +func (qs *QuestionCommon) UpdateAccepted(ctx context.Context, questionID, answerID string) error { question := &entity.Question{} question.ID = questionID - question.AcceptedAnswerID = AnswerID + question.AcceptedAnswerID = answerID return qs.questionRepo.UpdateAccepted(ctx, question) } -func (qs *QuestionCommon) UpdateLastAnswer(ctx context.Context, questionID, AnswerID string) error { +func (qs *QuestionCommon) UpdateLastAnswer(ctx context.Context, questionID, answerID string) error { question := &entity.Question{} question.ID = questionID - question.LastAnswerID = AnswerID + question.LastAnswerID = answerID return qs.questionRepo.UpdateLastAnswer(ctx, question) } @@ -232,7 +232,7 @@ func (qs *QuestionCommon) InviteUserInfo(ctx context.Context, questionID string) if !has { return InviteUserInfo, errors.NotFound(reason.QuestionNotFound) } - //InviteUser + // InviteUser if dbinfo.InviteUserID != "" { InviteUserIDs := make([]string, 0) err := json.Unmarshal([]byte(dbinfo.InviteUserID), &InviteUserIDs) @@ -681,7 +681,6 @@ func (qs *QuestionCommon) ShowFormat(ctx context.Context, data *entity.Question) info.LastAnsweredUserID = answerInfo.UserID } } - } info.Tags = make([]*schema.TagResp, 0) return &info diff --git a/internal/service/siteinfo_common/siteinfo_service_test.go b/internal/service/siteinfo_common/siteinfo_service_test.go index 3a567dcb9..a87d427f2 100644 --- a/internal/service/siteinfo_common/siteinfo_service_test.go +++ b/internal/service/siteinfo_common/siteinfo_service_test.go @@ -27,6 +27,7 @@ import ( "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/service/mock" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -46,6 +47,6 @@ func TestSiteInfoCommonService_GetSiteGeneral(t *testing.T) { mockInit(ctl) siteInfoCommonService := NewSiteInfoCommonService(mockSiteInfoRepo) resp, err := siteInfoCommonService.GetSiteGeneral(context.TODO()) - assert.NoError(t, err) - assert.Equal(t, resp.Name, "name") + require.NoError(t, err) + assert.Equal(t, "name", resp.Name) } diff --git a/internal/service/tag/tag_service.go b/internal/service/tag/tag_service.go index 577199ec8..e61bfa06e 100644 --- a/internal/service/tag/tag_service.go +++ b/internal/service/tag/tag_service.go @@ -74,7 +74,7 @@ func NewTagService( // RemoveTag delete tag func (ts *TagService) RemoveTag(ctx context.Context, req *schema.RemoveTagReq) (err error) { - //If the tag has associated problems, it cannot be deleted + // If the tag has associated problems, it cannot be deleted tagCount, err := ts.tagCommonService.CountTagRelByTagID(ctx, req.TagID) if err != nil { return err @@ -83,7 +83,7 @@ func (ts *TagService) RemoveTag(ctx context.Context, req *schema.RemoveTagReq) ( return errors.BadRequest(reason.TagIsUsedCannotDelete) } - //If the tag has associated problems, it cannot be deleted + // If the tag has associated problems, it cannot be deleted tagSynonymCount, err := ts.tagRepo.GetTagSynonymCount(ctx, req.TagID) if err != nil { return err diff --git a/internal/service/tag_common/tag_common.go b/internal/service/tag_common/tag_common.go index fed5dfbfb..87c10bcc9 100644 --- a/internal/service/tag_common/tag_common.go +++ b/internal/service/tag_common/tag_common.go @@ -591,7 +591,6 @@ func (ts *TagCommonService) CheckTag(ctx context.Context, tags []string, userID err = errors.BadRequest(reason.TagNotFound).WithMsg(fmt.Sprintf("tag [%s] does not exist", strings.Join(addTagMsgList, ","))) return err - } return nil @@ -660,9 +659,8 @@ func (ts *TagCommonService) CheckChangeReservedTag(ctx context.Context, oldobjec // ObjectChangeTag change object tag list func (ts *TagCommonService) ObjectChangeTag(ctx context.Context, objectTagData *schema.TagChange, minimumTags int) (errorlist []*validator.FormErrorField, err error) { - //checks if the tags sent in the put req are less than the minimum, if so, tag changes are not applied + // checks if the tags sent in the put req are less than the minimum, if so, tag changes are not applied if len(objectTagData.Tags) < minimumTags { - errorlist := make([]*validator.FormErrorField, 0) errorlist = append(errorlist, &validator.FormErrorField{ ErrorField: "tags", @@ -884,11 +882,11 @@ func (ts *TagCommonService) UpdateTag(ctx context.Context, req *schema.UpdateTag return errors.BadRequest(reason.TagNotFound) } - //Adding equivalent slug formatting for tag update + // Adding equivalent slug formatting for tag update slugName := strings.ReplaceAll(req.SlugName, " ", "-") slugName = strings.ToLower(slugName) - //If the content is the same, ignore it + // If the content is the same, ignore it if tagInfo.OriginalText == req.OriginalText && tagInfo.DisplayName == req.DisplayName && tagInfo.SlugName == slugName { diff --git a/internal/service/uploader/upload.go b/internal/service/uploader/upload.go index 30029193b..8dea746ce 100644 --- a/internal/service/uploader/upload.go +++ b/internal/service/uploader/upload.go @@ -135,7 +135,6 @@ func (us *uploaderService) UploadAvatarFile(ctx *gin.Context, userID string) (ur } us.fileRecordService.AddFileRecord(ctx, userID, avatarFilePath, url, string(plugin.UserAvatar)) return url, nil - } func (us *uploaderService) AvatarThumbFile(ctx *gin.Context, fileName string, size int) (url string, err error) { @@ -304,7 +303,6 @@ func (us *uploaderService) UploadBrandingFile(ctx *gin.Context, userID string) ( } us.fileRecordService.AddFileRecord(ctx, userID, avatarFilePath, url, string(plugin.AdminBranding)) return url, nil - } func (us *uploaderService) uploadImageFile(ctx *gin.Context, file *multipart.FileHeader, fileSubPath string) ( diff --git a/internal/service/user_admin/user_backyard.go b/internal/service/user_admin/user_backyard.go index 6fce161ce..fcced1c8b 100644 --- a/internal/service/user_admin/user_backyard.go +++ b/internal/service/user_admin/user_backyard.go @@ -470,14 +470,15 @@ func (us *UserAdminService) GetUserPage(ctx context.Context, req *schema.GetUser user := &entity.User{} _ = copier.Copy(user, req) - if req.IsInactive() { + switch { + case req.IsInactive(): user.MailStatus = entity.EmailStatusToBeVerified user.Status = entity.UserStatusAvailable - } else if req.IsSuspended() { + case req.IsSuspended(): user.Status = entity.UserStatusSuspended - } else if req.IsDeleted() { + case req.IsDeleted(): user.Status = entity.UserStatusDeleted - } else { + default: user.MailStatus = entity.EmailStatusAvailable user.Status = entity.UserStatusAvailable } @@ -486,8 +487,8 @@ func (us *UserAdminService) GetUserPage(ctx context.Context, req *schema.GetUser if email, e := mail.ParseAddress(req.Query); e == nil { user.EMail = email.Address req.Query = "" - } else if strings.HasPrefix(req.Query, "user:") { - id := strings.TrimSpace(strings.TrimPrefix(req.Query, "user:")) + } else if after, ok := strings.CutPrefix(req.Query, "user:"); ok { + id := strings.TrimSpace(after) idSearch := true for _, r := range id { if !unicode.IsDigit(r) { @@ -521,18 +522,19 @@ func (us *UserAdminService) GetUserPage(ctx context.Context, req *schema.GetUser DisplayName: u.DisplayName, Avatar: avatarMapping[u.ID].GetURL(), } - if u.Status == entity.UserStatusDeleted { + switch { + case u.Status == entity.UserStatusDeleted: t.Status = constant.UserDeleted t.DeletedAt = u.DeletedAt.Unix() - } else if u.Status == entity.UserStatusSuspended { + case u.Status == entity.UserStatusSuspended: t.Status = constant.UserSuspended t.SuspendedAt = u.SuspendedAt.Unix() if !u.SuspendedUntil.IsZero() { t.SuspendedUntil = u.SuspendedUntil.Unix() } - } else if u.MailStatus == entity.EmailStatusToBeVerified { + case u.MailStatus == entity.EmailStatusToBeVerified: t.Status = constant.UserInactive - } else { + default: t.Status = constant.UserNormal } resp = append(resp, t) @@ -646,7 +648,6 @@ func (us *UserAdminService) CheckAndUnsuspendExpiredUsers(ctx context.Context) e if user.Status == entity.UserStatusSuspended && !user.SuspendedUntil.IsZero() && user.SuspendedUntil.Before(now) { - log.Infof("Unsuspending user %s (ID: %s) - suspension expired at %v", user.Username, user.ID, user.SuspendedUntil) diff --git a/internal/service/user_common/user.go b/internal/service/user_common/user.go index 124972a16..2e777f14c 100644 --- a/internal/service/user_common/user.go +++ b/internal/service/user_common/user.go @@ -85,9 +85,9 @@ func NewUserCommon( } } -func (us *UserCommon) GetUserBasicInfoByID(ctx context.Context, ID string) ( +func (us *UserCommon) GetUserBasicInfoByID(ctx context.Context, id string) ( userBasicInfo *schema.UserBasicInfo, exist bool, err error) { - userInfo, exist, err := us.userRepo.GetByUserID(ctx, ID) + userInfo, exist, err := us.userRepo.GetByUserID(ctx, id) if err != nil { return nil, exist, err } diff --git a/internal/service/user_notification_config/user_notification_config_service.go b/internal/service/user_notification_config/user_notification_config_service.go index c40df55cf..8ab72fa94 100644 --- a/internal/service/user_notification_config/user_notification_config_service.go +++ b/internal/service/user_notification_config/user_notification_config_service.go @@ -96,7 +96,7 @@ func (us *UserNotificationConfigService) SetDefaultUserNotificationConfig(ctx co string(constant.InboxSource), `[{"key":"email","enable":true}]`) } -func (us *UserNotificationConfigService) convertToEntity(ctx context.Context, userID string, +func (us *UserNotificationConfigService) convertToEntity(_ context.Context, userID string, source constant.NotificationSource, channel schema.NotificationChannelConfig) (c *entity.UserNotificationConfig) { var channels schema.NotificationChannels channels = append(channels, &channel) diff --git a/pkg/checker/file_type.go b/pkg/checker/file_type.go index ac1fbcaf9..8eaabcbfc 100644 --- a/pkg/checker/file_type.go +++ b/pkg/checker/file_type.go @@ -28,6 +28,7 @@ import ( "io" "os" "path/filepath" + "slices" "strings" "github.com/segmentfault/pacman/log" @@ -38,12 +39,7 @@ import ( // WANING Only checks the file extension is not reliable, but `http.DetectContentType` and `mimetype` are not reliable for all file types. func IsUnAuthorizedExtension(fileName string, allowedExtensions []string) bool { ext := strings.ToLower(strings.Trim(filepath.Ext(fileName), ".")) - for _, extension := range allowedExtensions { - if extension == ext { - return false - } - } - return true + return !slices.Contains(allowedExtensions, ext) } // DecodeAndCheckImageFile currently answers support image type is diff --git a/pkg/checker/path_ignore.go b/pkg/checker/path_ignore.go index 8be757be5..24b092f7c 100644 --- a/pkg/checker/path_ignore.go +++ b/pkg/checker/path_ignore.go @@ -20,6 +20,7 @@ package checker import ( + "slices" "sync" "github.com/apache/answer/configs" @@ -46,21 +47,11 @@ func initPathIgnore() { // IsUsersIgnorePath checks whether the username is in ignore path func IsUsersIgnorePath(username string) bool { ignorePathInit.Do(initPathIgnore) - for _, u := range pathIgnore.Users { - if u == username { - return true - } - } - return false + return slices.Contains(pathIgnore.Users, username) } // IsQuestionsIgnorePath checks whether the questionID is in ignore path func IsQuestionsIgnorePath(questionID string) bool { ignorePathInit.Do(initPathIgnore) - for _, u := range pathIgnore.Questions { - if u == questionID { - return true - } - } - return false + return slices.Contains(pathIgnore.Questions, questionID) } diff --git a/pkg/checker/question_link.go b/pkg/checker/question_link.go index 41b246c36..efd19b3c3 100644 --- a/pkg/checker/question_link.go +++ b/pkg/checker/question_link.go @@ -44,15 +44,16 @@ func GetQuestionLink(content string) []QuestionLink { left, right := 0, 0 for right < len(content) { // find "/questions/" or "#" - if right+11 < len(content) && content[right:right+11] == "/questions/" { + switch { + case right+11 < len(content) && content[right:right+11] == "/questions/": left = right right += 11 processURL(content, &left, &right, uniqueIDs, &questionLinks) - } else if content[right] == '#' { + case content[right] == '#': left = right + 1 right = left processID(content, &left, &right, uniqueIDs, &questionLinks) - } else { + default: right++ } } @@ -101,9 +102,7 @@ func addUniqueID(questionID, answerID string, linkType int, uniqueIDs map[string objectType, err := obj.GetObjectTypeStrByObjectID(uid.DeShortID(answerID)) if err != nil { answerID = "" - } - - if objectType == constant.AnswerObjectType { + } else if objectType == constant.AnswerObjectType { if _, ok := uniqueIDs[answerID]; !ok { uniqueIDs[answerID] = struct{}{} isAdd = true diff --git a/pkg/converter/markdown.go b/pkg/converter/markdown.go index d16915a84..adae3faf6 100644 --- a/pkg/converter/markdown.go +++ b/pkg/converter/markdown.go @@ -107,7 +107,7 @@ func (r *DangerousHTMLRenderer) renderRawHTML(w util.BufWriter, source []byte, n } n := node.(*ast.RawHTML) l := n.Segments.Len() - for i := 0; i < l; i++ { + for i := range l { segment := n.Segments.At(i) if string(source[segment.Start:segment.Stop]) == "" || string(source[segment.Start:segment.Stop]) == "" { _, _ = w.Write(segment.Value(source)) @@ -122,15 +122,13 @@ func (r *DangerousHTMLRenderer) renderHTMLBlock(w util.BufWriter, source []byte, n := node.(*ast.HTMLBlock) if entering { l := n.Lines().Len() - for i := 0; i < l; i++ { + for i := range l { line := n.Lines().At(i) r.Writer.SecureWrite(w, line.Value(source)) } - } else { - if n.HasClosure() { - closure := n.ClosureLine - r.Writer.SecureWrite(w, closure.Value(source)) - } + } else if n.HasClosure() { + closure := n.ClosureLine + r.Writer.SecureWrite(w, closure.Value(source)) } return ast.WalkContinue, nil } @@ -184,8 +182,8 @@ func (r *DangerousHTMLRenderer) renderAutoLink(w util.BufWriter, source []byte, return ast.WalkContinue, nil } -func (r *DangerousHTMLRenderer) renderLinkIsUrl(verifyUrl string) bool { - isURL := govalidator.IsURL(verifyUrl) - isPath, _ := regexp.MatchString(`^/`, verifyUrl) +func (r *DangerousHTMLRenderer) renderLinkIsUrl(verifyURL string) bool { + isURL := govalidator.IsURL(verifyURL) + isPath, _ := regexp.MatchString(`^/`, verifyURL) return isURL || isPath } diff --git a/pkg/day/day.go b/pkg/day/day.go index 90afac0ad..2fd86a6c9 100644 --- a/pkg/day/day.go +++ b/pkg/day/day.go @@ -20,6 +20,7 @@ package day import ( + "strings" "time" ) @@ -50,16 +51,16 @@ func Format(unix int64, format, tz string) (formatted string) { for i := l; i >= 0; i-- { format = strings.ReplaceAll(format, placeholders[i].old, placeholders[i].new) }*/ - toFormat := "" + var toFormat strings.Builder from := []rune(format) for len(from) > 0 { to, suffix := nextStdChunk(from) - toFormat += string(to) + toFormat.WriteString(string(to)) from = suffix } _, _ = time.LoadLocation(tz) - formatted = time.Unix(unix, 0).Format(toFormat) + formatted = time.Unix(unix, 0).Format(toFormat.String()) return } diff --git a/pkg/dir/dir.go b/pkg/dir/dir.go index 928883c2e..09591f6ca 100644 --- a/pkg/dir/dir.go +++ b/pkg/dir/dir.go @@ -51,19 +51,19 @@ func DirSize(path string) (int64, error) { } func FormatFileSize(fileSize int64) (size string) { - if fileSize < 1024 { - //return strconv.FormatInt(fileSize, 10) + "B" + switch { + case fileSize < 1024: + // return strconv.FormatInt(fileSize, 10) + "B" return fmt.Sprintf("%.2f B", float64(fileSize)/float64(1)) - } else if fileSize < (1024 * 1024) { + case fileSize < (1024 * 1024): return fmt.Sprintf("%.2f KB", float64(fileSize)/float64(1024)) - } else if fileSize < (1024 * 1024 * 1024) { + case fileSize < (1024 * 1024 * 1024): return fmt.Sprintf("%.2f MB", float64(fileSize)/float64(1024*1024)) - } else if fileSize < (1024 * 1024 * 1024 * 1024) { + case fileSize < (1024 * 1024 * 1024 * 1024): return fmt.Sprintf("%.2f GB", float64(fileSize)/float64(1024*1024*1024)) - } else if fileSize < (1024 * 1024 * 1024 * 1024 * 1024) { + case fileSize < (1024 * 1024 * 1024 * 1024 * 1024): return fmt.Sprintf("%.2f TB", float64(fileSize)/float64(1024*1024*1024*1024)) - } else { //if fileSize < (1024 * 1024 * 1024 * 1024 * 1024 * 1024) + default: // if fileSize < (1024 * 1024 * 1024 * 1024 * 1024 * 1024) return fmt.Sprintf("%.2f EB", float64(fileSize)/float64(1024*1024*1024*1024*1024)) } - } diff --git a/pkg/htmltext/htmltext.go b/pkg/htmltext/htmltext.go index 56db4d2b2..e2e017c8d 100644 --- a/pkg/htmltext/htmltext.go +++ b/pkg/htmltext/htmltext.go @@ -77,14 +77,14 @@ func UrlTitle(title string) (text string) { } func clearEmoji(s string) string { - ret := "" + var ret strings.Builder rs := []rune(s) - for i := 0; i < len(rs); i++ { + for i := range rs { if len(string(rs[i])) != 4 { - ret += string(rs[i]) + ret.WriteString(string(rs[i])) } } - return ret + return ret.String() } func convertChinese(content string) string { @@ -164,7 +164,7 @@ func FetchRangedExcerpt(html, trimMarker string, offset int, limit int) (text st text = trimMarker + text } if end < len(runeText) { - text = text + trimMarker + text += trimMarker } return @@ -189,8 +189,8 @@ func FetchMatchedExcerpt(html string, words []string, trimMarker string, trimLen return FetchRangedExcerpt(html, trimMarker, runeOffset, runeLimit) } -func GetPicByUrl(Url string) string { - res, err := http.Get(Url) +func GetPicByUrl(url string) string { + res, err := http.Get(url) if err != nil { return "" } diff --git a/pkg/htmltext/htmltext_test.go b/pkg/htmltext/htmltext_test.go index 63866eb28..39de9e960 100644 --- a/pkg/htmltext/htmltext_test.go +++ b/pkg/htmltext/htmltext_test.go @@ -186,11 +186,11 @@ func TestCutLongTitle(t *testing.T) { // Exactly max bytes, no cutting needed exact150 := strings.Repeat("a", 150) - assert.Equal(t, 150, len(cutLongTitle(exact150))) + assert.Len(t, cutLongTitle(exact150), 150) // Just over max bytes, should be cut exact151 := strings.Repeat("a", 151) - assert.Equal(t, 150, len(cutLongTitle(exact151))) + assert.Len(t, cutLongTitle(exact151), 150) // Multi-byte rune at boundary gets removed properly asciiPart := strings.Repeat("a", 149) // 149 bytes diff --git a/plugin/plugin_test/plugin_main_test.go b/plugin/plugin_test/plugin_main_test.go index fd9015c86..7ba6f8ae3 100644 --- a/plugin/plugin_test/plugin_main_test.go +++ b/plugin/plugin_test/plugin_main_test.go @@ -81,19 +81,16 @@ func TestMain(t *testing.M) { _ = os.RemoveAll(dbSetting.Connection) } - defer func() { - if tearDown != nil { - tearDown() - } - }() if err := initTestDataSource(dbSetting); err != nil { panic(err) } log.Info("init test database successfully") - if ret := t.Run(); ret != 0 { - os.Exit(ret) + ret := t.Run() + if tearDown != nil { + tearDown() } + os.Exit(ret) } type TestDBSetting struct { @@ -155,7 +152,7 @@ func initDatabaseImage(dbSetting TestDBSetting) (connection string, cleanup func return "", nil, fmt.Errorf("could not connect to docker: %s", err) } - //resource, err := pool.Run(dbSetting.ImageName, dbSetting.ImageVersion, dbSetting.ENV) + // resource, err := pool.Run(dbSetting.ImageName, dbSetting.ImageVersion, dbSetting.ENV) resource, err := pool.RunWithOptions(&dockertest.RunOptions{ Repository: dbSetting.ImageName, Tag: dbSetting.ImageVersion, From 6660cdf6e25df42a6e86deca5d25e9817d67a5d2 Mon Sep 17 00:00:00 2001 From: Krypt0n123 <352600525@qq.com> Date: Tue, 2 Dec 2025 22:59:33 +0800 Subject: [PATCH 15/92] fix: add missing revision data for default content (fixes #1436) --- internal/migrations/init.go | 95 ++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/internal/migrations/init.go b/internal/migrations/init.go index 184c986b9..8a72794fe 100644 --- a/internal/migrations/init.go +++ b/internal/migrations/init.go @@ -28,6 +28,7 @@ import ( "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/data" + "github.com/apache/answer/internal/repo/revision" "github.com/apache/answer/internal/repo/unique" "github.com/apache/answer/internal/schema" "github.com/segmentfault/pacman/log" @@ -311,6 +312,7 @@ func (m *Mentor) initSiteInfoWrite() { func (m *Mentor) initDefaultContent() { uniqueIDRepo := unique.NewUniqueIDRepo(&data.Data{DB: m.engine}) + revisionRepo := revision.NewRevisionRepo(&data.Data{DB: m.engine}, uniqueIDRepo) now := time.Now() tagId, err := uniqueIDRepo.GenUniqueIDStr(m.ctx, entity.Tag{}.TableName()) @@ -343,7 +345,7 @@ func (m *Mentor) initDefaultContent() { return } - tag := entity.Tag{ + tag := &entity.Tag{ ID: tagId, SlugName: "support", DisplayName: "support", @@ -419,16 +421,74 @@ func (m *Mentor) initDefaultContent() { if m.err != nil { return } + tagContent, err := json.Marshal(tag) + if err != nil { + m.err = err + return + } + m.err = revisionRepo.AddRevision(m.ctx, &entity.Revision{ + UserID: tag.UserID, + ObjectID: tag.ID, + Title: tag.SlugName, + Content: string(tagContent), + Status: entity.RevisionReviewPassStatus, + }, true) + if m.err != nil { + return + } + tagForRevision := &entity.TagSimpleInfoForRevision{ + ID: tag.ID, + MainTagID: tag.MainTagID, + MainTagSlugName: tag.MainTagSlugName, + SlugName: tag.SlugName, + DisplayName: tag.DisplayName, + Recommend: tag.Recommend, + Reserved: tag.Reserved, + RevisionID: tag.RevisionID, + } _, m.err = m.engine.Context(m.ctx).Insert(q1) if m.err != nil { return } + q1Revision := &entity.QuestionWithTagsRevision{ + Question: *q1, + Tags: []*entity.TagSimpleInfoForRevision{tagForRevision}, + } + q1Content, err := json.Marshal(q1Revision) + if err != nil { + m.err = err + return + } + m.err = revisionRepo.AddRevision(m.ctx, &entity.Revision{ + UserID: q1.UserID, + ObjectID: q1.ID, + Title: q1.Title, + Content: string(q1Content), + Status: entity.RevisionReviewPassStatus, + }, true) + if m.err != nil { + return + } _, m.err = m.engine.Context(m.ctx).Insert(a1) if m.err != nil { return } + a1Content, err := json.Marshal(a1) + if err != nil { + m.err = err + return + } + m.err = revisionRepo.AddRevision(m.ctx, &entity.Revision{ + UserID: a1.UserID, + ObjectID: a1.ID, + Content: string(a1Content), + Status: entity.RevisionReviewPassStatus, + }, true) + if m.err != nil { + return + } _, m.err = m.engine.Context(m.ctx).Insert(entity.TagRel{ ObjectID: q1.ID, @@ -443,11 +503,44 @@ func (m *Mentor) initDefaultContent() { if m.err != nil { return } + q2Revision := &entity.QuestionWithTagsRevision{ + Question: *q2, + Tags: []*entity.TagSimpleInfoForRevision{tagForRevision}, + } + q2Content, err := json.Marshal(q2Revision) + if err != nil { + m.err = err + return + } + m.err = revisionRepo.AddRevision(m.ctx, &entity.Revision{ + UserID: q2.UserID, + ObjectID: q2.ID, + Title: q2.Title, + Content: string(q2Content), + Status: entity.RevisionReviewPassStatus, + }, true) + if m.err != nil { + return + } _, m.err = m.engine.Context(m.ctx).Insert(a2) if m.err != nil { return } + a2Content, err := json.Marshal(a2) + if err != nil { + m.err = err + return + } + m.err = revisionRepo.AddRevision(m.ctx, &entity.Revision{ + UserID: a2.UserID, + ObjectID: a2.ID, + Content: string(a2Content), + Status: entity.RevisionReviewPassStatus, + }, true) + if m.err != nil { + return + } _, m.err = m.engine.Context(m.ctx).Insert(entity.TagRel{ ObjectID: q2.ID, From 740ac61bb228ec48bf3d15231e4ec6ccc30a8bfc Mon Sep 17 00:00:00 2001 From: liruohrh <2372221537@qq.com> Date: Tue, 2 Dec 2025 01:21:49 +0800 Subject: [PATCH 16/92] fix: get right lang --- internal/base/handler/handler.go | 8 +++---- internal/base/handler/lang.go | 10 --------- internal/base/middleware/accept_language.go | 5 ++--- internal/controller/answer_controller.go | 6 ++--- internal/controller/comment_controller.go | 6 ++--- internal/controller/lang_controller.go | 2 +- internal/controller/question_controller.go | 14 ++++++------ internal/controller/report_controller.go | 2 +- internal/controller/search_controller.go | 2 +- internal/controller/template_controller.go | 10 ++++----- internal/controller/user_controller.go | 22 +++++++++---------- internal/controller/vote_controller.go | 8 +++---- .../user_backyard_controller.go | 2 +- internal/service/importer/importer_service.go | 2 +- plugin/plugin.go | 2 +- 15 files changed, 44 insertions(+), 57 deletions(-) diff --git a/internal/base/handler/handler.go b/internal/base/handler/handler.go index b545b5e01..0c2fe8f4f 100644 --- a/internal/base/handler/handler.go +++ b/internal/base/handler/handler.go @@ -23,7 +23,6 @@ import ( "errors" "net/http" - "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/reason" "github.com/apache/answer/internal/base/validator" "github.com/gin-gonic/gin" @@ -33,7 +32,7 @@ import ( // HandleResponse Handle response body func HandleResponse(ctx *gin.Context, err error, data any) { - lang := GetLang(ctx) + lang := GetLangByCtx(ctx) // no error if err == nil { ctx.JSON(http.StatusOK, NewRespBodyData(http.StatusOK, reason.Success, data).TrMsg(lang)) @@ -63,8 +62,7 @@ func HandleResponse(ctx *gin.Context, err error, data any) { // BindAndCheck bind request and check func BindAndCheck(ctx *gin.Context, data any) bool { - lang := GetLang(ctx) - ctx.Set(constant.AcceptLanguageFlag, lang) + lang := GetLangByCtx(ctx) if err := ctx.ShouldBind(data); err != nil { log.Errorf("http_handle BindAndCheck fail, %s", err.Error()) HandleResponse(ctx, myErrors.New(http.StatusBadRequest, reason.RequestFormatError), nil) @@ -81,7 +79,7 @@ func BindAndCheck(ctx *gin.Context, data any) bool { // BindAndCheckReturnErr bind request and check func BindAndCheckReturnErr(ctx *gin.Context, data any) (errFields []*validator.FormErrorField) { - lang := GetLang(ctx) + lang := GetLangByCtx(ctx) if err := ctx.ShouldBind(data); err != nil { log.Errorf("http_handle BindAndCheck fail, %s", err.Error()) HandleResponse(ctx, myErrors.New(http.StatusBadRequest, reason.RequestFormatError), nil) diff --git a/internal/base/handler/lang.go b/internal/base/handler/lang.go index 4ff1ac7f1..8886f0631 100644 --- a/internal/base/handler/lang.go +++ b/internal/base/handler/lang.go @@ -23,19 +23,9 @@ import ( "context" "github.com/apache/answer/internal/base/constant" - "github.com/gin-gonic/gin" "github.com/segmentfault/pacman/i18n" ) -// GetLang get language from header -func GetLang(ctx *gin.Context) i18n.Language { - acceptLanguage := ctx.GetHeader(constant.AcceptLanguageFlag) - if len(acceptLanguage) == 0 { - return i18n.DefaultLanguage - } - return i18n.Language(acceptLanguage) -} - // GetLangByCtx get language from header func GetLangByCtx(ctx context.Context) i18n.Language { acceptLanguage, ok := ctx.Value(constant.AcceptLanguageContextKey).(i18n.Language) diff --git a/internal/base/middleware/accept_language.go b/internal/base/middleware/accept_language.go index ca8a1f903..5d1b12b2d 100644 --- a/internal/base/middleware/accept_language.go +++ b/internal/base/middleware/accept_language.go @@ -23,7 +23,6 @@ import ( "strings" "github.com/apache/answer/internal/base/constant" - "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/translator" "github.com/gin-gonic/gin" "github.com/segmentfault/pacman/i18n" @@ -33,8 +32,8 @@ import ( // ExtractAndSetAcceptLanguage extract accept language from header and set to context func ExtractAndSetAcceptLanguage(ctx *gin.Context) { // The language of our front-end configuration, like en_US - lang := handler.GetLang(ctx) - tag, _, err := language.ParseAcceptLanguage(string(lang)) + acceptLanguage := ctx.GetHeader(constant.AcceptLanguageFlag) + tag, _, err := language.ParseAcceptLanguage(acceptLanguage) if err != nil || len(tag) == 0 { ctx.Set(constant.AcceptLanguageFlag, i18n.LanguageEnglish) return diff --git a/internal/controller/answer_controller.go b/internal/controller/answer_controller.go index 0e43121c5..e76b02ccc 100644 --- a/internal/controller/answer_controller.go +++ b/internal/controller/answer_controller.go @@ -89,7 +89,7 @@ func (ac *AnswerController) RemoveAnswer(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -225,7 +225,7 @@ func (ac *AnswerController) AddAnswer(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -325,7 +325,7 @@ func (ac *AnswerController) UpdateAnswer(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return diff --git a/internal/controller/comment_controller.go b/internal/controller/comment_controller.go index 65fbedf04..7289a0e18 100644 --- a/internal/controller/comment_controller.go +++ b/internal/controller/comment_controller.go @@ -106,7 +106,7 @@ func (cc *CommentController) AddComment(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -154,7 +154,7 @@ func (cc *CommentController) RemoveComment(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -215,7 +215,7 @@ func (cc *CommentController) UpdateComment(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return diff --git a/internal/controller/lang_controller.go b/internal/controller/lang_controller.go index c7c607bdc..1e70fa88c 100644 --- a/internal/controller/lang_controller.go +++ b/internal/controller/lang_controller.go @@ -48,7 +48,7 @@ func NewLangController(tr i18n.Translator, siteInfoService siteinfo_common.SiteI // @Success 200 {object} handler.RespBody{} // @Router /answer/api/v1/language/config [get] func (u *LangController) GetLangMapping(ctx *gin.Context) { - data, _ := u.translator.Dump(handler.GetLang(ctx)) + data, _ := u.translator.Dump(handler.GetLangByCtx(ctx)) var resp map[string]any _ = json.Unmarshal(data, &resp) handler.HandleResponse(ctx, nil, resp) diff --git a/internal/controller/question_controller.go b/internal/controller/question_controller.go index 581cf548b..d5164fc86 100644 --- a/internal/controller/question_controller.go +++ b/internal/controller/question_controller.go @@ -94,7 +94,7 @@ func (qc *QuestionController) RemoveQuestion(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -419,7 +419,7 @@ func (qc *QuestionController) AddQuestion(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -445,7 +445,7 @@ func (qc *QuestionController) AddQuestion(ctx *gin.Context) { return } if !req.CanAddTag && hasNewTag { - lang := handler.GetLang(ctx) + lang := handler.GetLangByCtx(ctx) msg := translator.TrWithData(lang, reason.NoEnoughRankToOperate, &schema.PermissionTrTplData{Rank: requireRanks[6]}) handler.HandleResponse(ctx, errors.Forbidden(reason.NoEnoughRankToOperate).WithMsg(msg), nil) return @@ -524,7 +524,7 @@ func (qc *QuestionController) AddQuestionByAnswer(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -646,7 +646,7 @@ func (qc *QuestionController) UpdateQuestion(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -681,7 +681,7 @@ func (qc *QuestionController) UpdateQuestion(ctx *gin.Context) { return } if !req.CanAddTag && hasNewTag { - lang := handler.GetLang(ctx) + lang := handler.GetLangByCtx(ctx) msg := translator.TrWithData(lang, reason.NoEnoughRankToOperate, &schema.PermissionTrTplData{Rank: requireRanks[4]}) handler.HandleResponse(ctx, errors.Forbidden(reason.NoEnoughRankToOperate).WithMsg(msg), nil) return @@ -765,7 +765,7 @@ func (qc *QuestionController) UpdateQuestionInviteUser(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return diff --git a/internal/controller/report_controller.go b/internal/controller/report_controller.go index 28048dd3d..13b4c0953 100644 --- a/internal/controller/report_controller.go +++ b/internal/controller/report_controller.go @@ -79,7 +79,7 @@ func (rc *ReportController) AddReport(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return diff --git a/internal/controller/search_controller.go b/internal/controller/search_controller.go index 64acbe252..a5d3e8d13 100644 --- a/internal/controller/search_controller.go +++ b/internal/controller/search_controller.go @@ -78,7 +78,7 @@ func (sc *SearchController) Search(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return diff --git a/internal/controller/template_controller.go b/internal/controller/template_controller.go index f6a442c21..257b02fa4 100644 --- a/internal/controller/template_controller.go +++ b/internal/controller/template_controller.go @@ -206,7 +206,7 @@ func (tc *TemplateController) QuestionList(ctx *gin.Context) { UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle || siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID - siteInfo.Title = fmt.Sprintf("%s - %s", translator.Tr(handler.GetLang(ctx), constant.QuestionsTitleTrKey), siteInfo.General.Name) + siteInfo.Title = fmt.Sprintf("%s - %s", translator.Tr(handler.GetLangByCtx(ctx), constant.QuestionsTitleTrKey), siteInfo.General.Name) tc.html(ctx, http.StatusOK, "question.html", siteInfo, gin.H{ "data": data, "useTitle": UrlUseTitle, @@ -461,7 +461,7 @@ func (tc *TemplateController) TagList(ctx *gin.Context) { if req.Page > 1 { siteInfo.Canonical = fmt.Sprintf("%s/tags?page=%d", siteInfo.General.SiteUrl, req.Page) } - siteInfo.Title = fmt.Sprintf("%s - %s", translator.Tr(handler.GetLang(ctx), constant.TagsListTitleTrKey), siteInfo.General.Name) + siteInfo.Title = fmt.Sprintf("%s - %s", translator.Tr(handler.GetLangByCtx(ctx), constant.TagsListTitleTrKey), siteInfo.General.Name) tc.html(ctx, http.StatusOK, "tags.html", siteInfo, gin.H{ "page": page, "data": data, @@ -492,14 +492,14 @@ func (tc *TemplateController) TagInfo(ctx *gin.Context) { } siteInfo.Description = htmltext.FetchExcerpt(tagInfo.ParsedText, "...", 240) if len(tagInfo.ParsedText) == 0 { - siteInfo.Description = translator.Tr(handler.GetLang(ctx), constant.TagHasNoDescription) + siteInfo.Description = translator.Tr(handler.GetLangByCtx(ctx), constant.TagHasNoDescription) } siteInfo.Keywords = tagInfo.DisplayName UrlUseTitle := siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitle || siteInfo.SiteSeo.Permalink == constant.PermalinkQuestionIDAndTitleByShortID - siteInfo.Title = fmt.Sprintf("'%s' %s - %s", tagInfo.DisplayName, translator.Tr(handler.GetLang(ctx), constant.QuestionsTitleTrKey), siteInfo.General.Name) + siteInfo.Title = fmt.Sprintf("'%s' %s - %s", tagInfo.DisplayName, translator.Tr(handler.GetLangByCtx(ctx), constant.QuestionsTitleTrKey), siteInfo.General.Name) tc.html(ctx, http.StatusOK, "tag-detail.html", siteInfo, gin.H{ "tag": tagInfo, "questionList": questionList, @@ -597,7 +597,7 @@ func (tc *TemplateController) html(ctx *gin.Context, code int, tpl string, siteI data["title"] = siteInfo.General.Name } data["description"] = siteInfo.Description - data["language"] = handler.GetLang(ctx) + data["language"] = handler.GetLangByCtx(ctx) data["timezone"] = siteInfo.Interface.TimeZone language := strings.ReplaceAll(siteInfo.Interface.Language, "_", "-") data["lang"] = language diff --git a/internal/controller/user_controller.go b/internal/controller/user_controller.go index cc89caf1a..77c806e07 100644 --- a/internal/controller/user_controller.go +++ b/internal/controller/user_controller.go @@ -142,7 +142,7 @@ func (uc *UserController) UserEmailLogin(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -154,7 +154,7 @@ func (uc *UserController) UserEmailLogin(ctx *gin.Context) { uc.actionService.ActionRecordAdd(ctx, entity.CaptchaActionPassword, ctx.ClientIP()) errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "e_mail", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.EmailOrPasswordWrong), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.EmailOrPasswordWrong), }) handler.HandleResponse(ctx, errors.BadRequest(reason.EmailOrPasswordWrong), errFields) return @@ -191,7 +191,7 @@ func (uc *UserController) RetrievePassWord(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -286,7 +286,7 @@ func (uc *UserController) UserRegisterByEmail(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -297,7 +297,7 @@ func (uc *UserController) UserRegisterByEmail(ctx *gin.Context) { if len(errFields) > 0 { for _, field := range errFields { field.ErrorMsg = translator. - Tr(handler.GetLang(ctx), field.ErrorMsg) + Tr(handler.GetLangByCtx(ctx), field.ErrorMsg) } handler.HandleResponse(ctx, err, errFields) } else { @@ -364,7 +364,7 @@ func (uc *UserController) UserVerifyEmailSend(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -399,7 +399,7 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -415,7 +415,7 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) { if !oldPassVerification { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "old_pass", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.OldPasswordVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.OldPasswordVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.OldPasswordVerificationFailed), errFields) return @@ -424,7 +424,7 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) { if req.OldPass == req.Pass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "pass", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.NewPasswordSameAsPreviousSetting), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.NewPasswordSameAsPreviousSetting), }) handler.HandleResponse(ctx, errors.BadRequest(reason.NewPasswordSameAsPreviousSetting), errFields) return @@ -456,7 +456,7 @@ func (uc *UserController) UserUpdateInfo(ctx *gin.Context) { req.IsAdmin = middleware.GetUserIsAdminModerator(ctx) errFields, err := uc.userService.UpdateInfo(ctx, req) for _, field := range errFields { - field.ErrorMsg = translator.Tr(handler.GetLang(ctx), field.ErrorMsg) + field.ErrorMsg = translator.Tr(handler.GetLangByCtx(ctx), field.ErrorMsg) } handler.HandleResponse(ctx, err, errFields) } @@ -587,7 +587,7 @@ func (uc *UserController) UserChangeEmailSendCode(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return diff --git a/internal/controller/vote_controller.go b/internal/controller/vote_controller.go index 2e0ee6121..302796677 100644 --- a/internal/controller/vote_controller.go +++ b/internal/controller/vote_controller.go @@ -79,7 +79,7 @@ func (vc *VoteController) VoteUp(ctx *gin.Context) { return } if !can { - lang := handler.GetLang(ctx) + lang := handler.GetLangByCtx(ctx) msg := translator.TrWithData(lang, reason.NoEnoughRankToOperate, &schema.PermissionTrTplData{Rank: needRank}) handler.HandleResponse(ctx, errors.Forbidden(reason.NoEnoughRankToOperate).WithMsg(msg), nil) return @@ -91,7 +91,7 @@ func (vc *VoteController) VoteUp(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return @@ -134,7 +134,7 @@ func (vc *VoteController) VoteDown(ctx *gin.Context) { return } if !can { - lang := handler.GetLang(ctx) + lang := handler.GetLangByCtx(ctx) msg := translator.TrWithData(lang, reason.NoEnoughRankToOperate, &schema.PermissionTrTplData{Rank: needRank}) handler.HandleResponse(ctx, errors.Forbidden(reason.NoEnoughRankToOperate).WithMsg(msg), nil) return @@ -145,7 +145,7 @@ func (vc *VoteController) VoteDown(ctx *gin.Context) { if !captchaPass { errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ ErrorField: "captcha_code", - ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), + ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.CaptchaVerificationFailed), }) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) return diff --git a/internal/controller_admin/user_backyard_controller.go b/internal/controller_admin/user_backyard_controller.go index 00dfa2c3d..1356c55a1 100644 --- a/internal/controller_admin/user_backyard_controller.go +++ b/internal/controller_admin/user_backyard_controller.go @@ -177,7 +177,7 @@ func (uc *UserAdminController) EditUserProfile(ctx *gin.Context) { errFields, err := uc.userService.EditUserProfile(ctx, req) for _, field := range errFields { - field.ErrorMsg = translator.Tr(handler.GetLang(ctx), field.ErrorMsg) + field.ErrorMsg = translator.Tr(handler.GetLangByCtx(ctx), field.ErrorMsg) } handler.HandleResponse(ctx, err, errFields) } diff --git a/internal/service/importer/importer_service.go b/internal/service/importer/importer_service.go index c7673ffb5..9d12bf07b 100644 --- a/internal/service/importer/importer_service.go +++ b/internal/service/importer/importer_service.go @@ -135,7 +135,7 @@ func (ip *ImporterService) ImportQuestion(ctx context.Context, questionInfo plug return err } if !req.CanAddTag && hasNewTag { - lang := handler.GetLang(ctx.(*gin.Context)) + lang := handler.GetLangByCtx(ctx.(*gin.Context)) msg := translator.TrWithData(lang, reason.NoEnoughRankToOperate, &schema.PermissionTrTplData{Rank: requireRanks[6]}) log.Errorf("error: %v", msg) return errors.BadRequest(msg) diff --git a/plugin/plugin.go b/plugin/plugin.go index 266848353..8778b1625 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -216,7 +216,7 @@ func (m *statusManager) UnmarshalJSON(data []byte) error { // Translate translates the key to the current language of the context func Translate(ctx *GinContext, key string) string { - return translator.Tr(handler.GetLang(ctx), key) + return translator.Tr(handler.GetLangByCtx(ctx), key) } // TranslateWithData translates the key to the language with data From 8e395d421e5ded9277414c69cee1452429acc524 Mon Sep 17 00:00:00 2001 From: kinjelom Date: Sat, 22 Nov 2025 12:36:06 +0100 Subject: [PATCH 17/92] Polish translation --- i18n/pl_PL.yaml | 544 ++++++++++++++++++++++++++---------------------- 1 file changed, 300 insertions(+), 244 deletions(-) diff --git a/i18n/pl_PL.yaml b/i18n/pl_PL.yaml index e5972d9b3..c5c97d118 100644 --- a/i18n/pl_PL.yaml +++ b/i18n/pl_PL.yaml @@ -486,43 +486,42 @@ backend: title: other: "[{{.SiteName}}] Potwierdź swój nowy adres e-mail" body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
\n
{{.ChangeEmailUrl}}

\n\nIf you did not request this change, please ignore this email.

\n\n--
\nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + other: "Potwierdź swój nowy adres e-mail dla {{.SiteName}}, klikając poniższy link:
\n{{.ChangeEmailUrl}}

\n\nJeśli nie prosiłeś(-aś) o zmianę adresu e-mail, zignoruj tę wiadomość.

\n\n--
\nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana." new_answer: title: other: "[{{.SiteName}}] {{.DisplayName}} odpowiedział(-a) na pytanie" body: - other: "{{.QuestionTitle}}

\n\n{{.DisplayName}}:
\n
{{.AnswerSummary}}

\nView it on {{.SiteName}}

\n\n--
\nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

\n\nUnsubscribe" + other: "{{.QuestionTitle}}

\n\n{{.DisplayName}} napisał(-a):
\n
{{.AnswerSummary}}

\nZobacz na {{.SiteName}}

\n\n--
\nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana.

\n\nZrezygnuj z subskrypcji" invited_you_to_answer: title: - other: "[{{.SiteName}}] {{.DisplayName}} zaprosił(a) Cię do odpowiedzi" + other: "[{{.SiteName}}] {{.DisplayName}} zaprosił(-a) Cię do odpowiedzi" body: - other: "{{.QuestionTitle}}

\n\n{{.DisplayName}}:
\n
I think you may know the answer.

\nView it on {{.SiteName}}

\n\n--
\nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

\n\nUnsubscribe" + other: "{{.QuestionTitle}}

\n\n{{.DisplayName}} napisał(-a):
\n
Myślę, że możesz znać odpowiedź.

\nZobacz na {{.SiteName}}

\n\n--
\nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana.

\n\nZrezygnuj z subskrypcji" new_comment: title: - other: "[{{.SiteName}}] {{.DisplayName}} skomentował/-a Twój wpis" + other: "[{{.SiteName}}] {{.DisplayName}} skomentował(-a) Twój wpis" body: - other: "{{.QuestionTitle}}

\n\n{{.DisplayName}}:
\n
{{.CommentSummary}}

\nView it on {{.SiteName}}

\n\n--
\nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

\n\nUnsubscribe" + other: "{{.QuestionTitle}}

\n\n{{.DisplayName}} napisał(-a):
\n
{{.CommentSummary}}

\nZobacz na {{.SiteName}}

\n\n--
\nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana.

\n\nZrezygnuj z subskrypcji" new_question: title: other: "[{{.SiteName}}] Nowe pytanie: {{.QuestionTitle}}" body: - other: "{{.QuestionTitle}}
\n{{.Tags}}

\n\n--
\nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

\n\nUnsubscribe" + other: "{{.QuestionTitle}}
\n{{.Tags}}

\n\n--
\nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana.

\n\nZrezygnuj z subskrypcji" pass_reset: title: - other: "[{{.SiteName }}] Reset hasła" + other: "[{{.SiteName}}] Reset hasła" body: - other: "Somebody asked to reset your password on {{.SiteName}}.

\n\nIf it was not you, you can safely ignore this email.

\n\nClick the following link to choose a new password:
\n{{.PassResetUrl}}\n

\n\n--
\nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + other: "Otrzymaliśmy prośbę o zresetowanie Twojego hasła w serwisie {{.SiteName}}.

\n\nJeśli to nie Ty wysłałeś(-aś) tę prośbę, możesz bezpiecznie zignorować tę wiadomość.

\n\nKliknij poniższy link, aby ustawić nowe hasło:
\n{{.PassResetUrl}}\n

\n\n--
\nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana." register: title: other: "[{{.SiteName}}] Potwierdź swoje nowe konto" body: - other: "Welcome to {{.SiteName}}!

\n\nClick the following link to confirm and activate your new account:
\n{{.RegisterUrl}}

\n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

\n\n--
\nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + other: "Witamy w {{.SiteName}}!

\n\nKliknij poniższy link, aby potwierdzić i aktywować swoje nowe konto:
\n{{.RegisterUrl}}

\n\nJeśli powyższy link nie jest klikalny, spróbuj skopiować go i wkleić do paska adresu przeglądarki.\n

\n\n--
\nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana." test: title: other: "[{{.SiteName}}] Wiadomość testowa" body: - other: "This is a test email.\n

\n\n--
\nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: + other: "To jest testowa wiadomość e-mail.\n

\n\n--
\nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana." upvote: other: oceń pozytywnie upvoted: @@ -573,244 +572,300 @@ backend: name: other: Pierwszy pozytywny głos desc: - other: First up voted a post. + other: Po raz pierwszy oddano pozytywny głos na post. first_link: name: other: Pierwszy odnośnik desc: - other: First added a link to another post. + other: Po raz pierwszy dodano link do innego wpisu. + first_reaction: name: - other: Pierwsza Reakcja + other: Pierwsza reakcja desc: - other: First reacted to the post. + other: Po raz pierwszy zareagowano na wpis. + first_share: name: - other: Pierwsze udostępnianie + other: Pierwsze udostępnienie desc: - other: First shared a post. + other: Po raz pierwszy udostępniono wpis. + scholar: name: other: Scholar desc: - other: Zadane pytania i zaakceptowane odpowiedź. + other: Zadano pytanie i zaakceptowano odpowiedź. + commentator: name: - other: Commentator + other: Komentator desc: - other: Pozostaw 5 komentarzy. + other: Pozostawiono 5 komentarzy. + new_user_of_the_month: name: other: Nowy użytkownik miesiąca desc: - other: Outstanding contributions in their first month. + other: Wyjątkowy wkład w pierwszym miesiącu aktywności. + read_guidelines: name: - other: Read Guidelines + other: Przeczytano zasady desc: - other: Read the [community guidelines]. + other: Przeczytano [zasady społeczności]. + reader: name: - other: Reader + other: Czytelnik desc: - other: Read every answers in a topic with more than 10 answers. + other: Przeczytano wszystkie odpowiedzi w wątku mającym ponad 10 odpowiedzi. + welcome: name: - other: Welcome + other: Witamy desc: - other: Received a up vote. + other: Otrzymano pozytywny głos. + nice_share: name: - other: Nice Share + other: Udane udostępnienie desc: - other: Shared a post with 25 unique visitors. + other: Udostępniono wpis, który odwiedziło 25 unikalnych użytkowników. + good_share: name: - other: Good Share + other: Dobre udostępnienie desc: - other: Shared a post with 300 unique visitors. + other: Udostępniono wpis, który odwiedziło 300 unikalnych użytkowników. + great_share: name: - other: Great Share + other: Świetne udostępnienie desc: - other: Shared a post with 1000 unique visitors. + other: Udostępniono wpis, który odwiedziło 1000 unikalnych użytkowników. + out_of_love: name: - other: Out of Love + other: Z miłości desc: - other: Used 50 up votes in a day. + other: Wykorzystano 50 pozytywnych głosów w ciągu dnia. + higher_love: name: - other: Higher Love + other: Więcej miłości desc: - other: Used 50 up votes in a day 5 times. + other: Wykorzystano 50 pozytywnych głosów w ciągu dnia - 5 razy. + crazy_in_love: name: - other: Crazy in Love + other: Szaleństwo miłości desc: - other: Used 50 up votes in a day 20 times. + other: Wykorzystano 50 pozytywnych głosów w ciągu dnia - 20 razy. + promoter: name: - other: Promoter + other: Promotor desc: - other: Invited a user. + other: Zaproszono użytkownika. + campaigner: name: - other: Campaigner + other: Kampanier desc: - other: Invited 3 basic users. + other: Zaproszono 3 podstawowych użytkowników. + champion: name: - other: Champion + other: Mistrz desc: - other: Invited 5 members. + other: Zaproszono 5 użytkowników. + thank_you: name: - other: Thank You + other: Dziękuję desc: - other: Has 20 up voted posts and gave 10 up votes. + other: Otrzymano 20 pozytywnych głosów i oddano 10. + gives_back: name: - other: Gives Back + other: Oddający dalej desc: - other: Has 100 up voted posts and gave 100 up votes. + other: Otrzymano 100 pozytywnych głosów i oddano 100. + empathetic: name: - other: Empathetic + other: Empatyczny desc: - other: Has 500 up voted posts and gave 1000 up votes. + other: Otrzymano 500 pozytywnych głosów i oddano 1000. + enthusiast: name: - other: Enthusiast + other: Entuzjasta desc: - other: Visited 10 consecutive days. + other: Odwiedzono serwis 10 dni z rzędu. + aficionado: name: - other: Aficionado + other: Koneser desc: - other: Visited 100 consecutive days. + other: Odwiedzono serwis 100 dni z rzędu. + devotee: name: - other: Devotee + other: Wytrwały desc: - other: Visited 365 consecutive days. + other: Odwiedzono serwis 365 dni z rzędu. + anniversary: name: - other: Anniversary + other: Rocznica desc: - other: Active member for a year, posted at least once. + other: Aktywny użytkownik od roku, co najmniej jeden wpis. + appreciated: name: - other: Appreciated + other: Doceniony desc: - other: Received 1 up vote on 20 posts. + other: Otrzymano 1 pozytywny głos na 20 wpisach. + respected: name: - other: Respected + other: Szanujący desc: - other: Received 2 up votes on 100 posts. + other: Otrzymano 2 pozytywne głosy na 100 wpisach. + admired: name: - other: Admired + other: Podziwiany desc: - other: Received 5 up votes on 300 posts. + other: Otrzymano 5 pozytywnych głosów na 300 wpisach. + solved: name: - other: Solved + other: Rozwiązane desc: - other: Have an answer be accepted. + other: Udzielono odpowiedzi, która została zaakceptowana. + guidance_counsellor: name: - other: Guidance Counsellor + other: Doradca desc: - other: Have 10 answers be accepted. + other: 10 udzielonych odpowiedzi zostało zaakceptowanych. + know_it_all: name: - other: Know-it-All + other: Wszystkowiedzący desc: - other: Have 50 answers be accepted. + other: 50 udzielonych odpowiedzi zostało zaakceptowanych. + solution_institution: name: - other: Solution Institution + other: Instytucja rozwiązań desc: - other: Have 150 answers be accepted. + other: 150 udzielonych odpowiedzi zostało zaakceptowanych. + nice_answer: name: - other: Nice Answer + other: Dobra odpowiedź desc: - other: Answer score of 10 or more. + other: Odpowiedź z wynikiem co najmniej 10. + good_answer: name: - other: Good Answer + other: Bardzo dobra odpowiedź desc: - other: Answer score of 25 or more. + other: Odpowiedź z wynikiem co najmniej 25. + great_answer: name: - other: Great Answer + other: Świetna odpowiedź desc: - other: Answer score of 50 or more. + other: Odpowiedź z wynikiem co najmniej 50. + nice_question: name: - other: Nice Question + other: Dobre pytanie desc: - other: Question score of 10 or more. + other: Pytanie z wynikiem co najmniej 10. + good_question: name: - other: Good Question + other: Bardzo dobre pytanie desc: - other: Question score of 25 or more. + other: Pytanie z wynikiem co najmniej 25. + great_question: name: - other: Great Question + other: Świetne pytanie desc: - other: Question score of 50 or more. + other: Pytanie z wynikiem co najmniej 50. + popular_question: name: - other: Popular Question + other: Popularne pytanie desc: - other: Question with 500 views. + other: Pytanie z 500 wyświetleniami. + notable_question: name: - other: Notable Question + other: Zauważalne pytanie desc: - other: Question with 1,000 views. + other: Pytanie z 1000 wyświetleniami. + famous_question: name: - other: Famous Question + other: Słynne pytanie desc: - other: Question with 5,000 views. + other: Pytanie z 5000 wyświetleniami. + popular_link: name: - other: Popular Link + other: Popularny link desc: - other: Posted an external link with 50 clicks. + other: Opublikowano zewnętrzny link z 50 kliknięciami. + hot_link: name: - other: Hot Link + other: Gorący link desc: - other: Posted an external link with 300 clicks. + other: Opublikowano zewnętrzny link z 300 kliknięciami. + famous_link: name: - other: Famous Link + other: Słynny link desc: - other: Posted an external link with 100 clicks. + other: Opublikowano zewnętrzny link z 1000 kliknięciami. default_badge_groups: getting_started: name: - other: Getting Started + other: Pierwsze kroki community: name: - other: Community + other: Społeczność posting: name: - other: Posting + other: Publikowanie # The following fields are used for interface presentation(Front-end) ui: how_to_format: title: Jak formatować desc: >- -
  • mention a post: #post_id

  • to make links

    <https://url.com>

    [Title](https://url.com)
  • put returns between paragraphs

  • _italic_ or **bold**

  • indent code by 4 spaces

  • quote by placing > at start of line

  • backtick escapes `like _this_`

  • create code fences with backticks `

    ```
    code here
    ```
- pagination: +
    +
  • wspomnij wpis: #post_id

  • +
  • tworzenie linków

    +
    <https://url.com>

    [Tytuł](https://url.com)
    +
  • +
  • oddziel akapity pustą linią

  • +
  • _kursywa_ lub **pogrubienie**

  • +
  • zagnieźdź kod, dodając 4 spacje na początku wiersza

  • +
  • cytuj, dodając > na początku wiersza

  • +
  • użyj odwrotnego apostrofu (backtick) do zagnieżdżonego kodu `tak _to_ działa`

  • +
  • twórz bloki kodu przy pomocy potrójnych odwrotnych apostrofów `

    +
    ```
    kod tutaj
    ```
    +
  • +
+ pagination: prev: Poprzedni next: Następny page_title: @@ -970,9 +1025,9 @@ ui: heading: Nagłówek cell: Komórka file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." + text: Dołącz pliki + not_supported: "Ten typ pliku nie jest obsługiwany. Spróbuj ponownie z {{file_type}}." + max_size: "Rozmiar dołączanych plików nie może przekraczać {{size}} MB." close_modal: title: Zamykam ten post jako... btn_cancel: Anuluj @@ -1037,20 +1092,22 @@ ui: delete: title: Usuń ten tag tip_with_posts: >- -

We do not allow deleting tag with posts.

Please remove this tag from the posts first.

+

Nie można usunąć tagu, który jest używany w postach.

+

Najpierw usuń ten tag z powiązanych postów.

tip_with_synonyms: >- -

We do not allow deleting tag with synonyms.

Please remove the synonyms from this tag first.

+

Nie można usunąć tagu, który ma synonimy.

+

Najpierw usuń synonimy przypisane do tego tagu.

tip: Czy na pewno chcesz usunąć? close: Zamknij merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close + title: Scal tag + source_tag_title: Źródłowy tag + source_tag_description: Źródłowy tag i wszystkie powiązane dane zostaną przemapowane na tag docelowy. + target_tag_title: Docelowy tag + target_tag_description: Po scaleniu zostanie utworzony synonim między tymi dwoma tagami. + no_results: Brak pasujących tagów + btn_submit: Zatwierdź + btn_close: Zamknij edit_tag: title: Edytuj tag default_reason: Edytuj tag @@ -1058,20 +1115,20 @@ ui: btn_save_edits: Zapisz edycje btn_cancel: Anuluj dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [o] HH:mm" + long_date: D MMM + long_date_with_year: "YYYY MMM D" + long_date_with_time: "YYYY MMM D [o] HH:mm" now: teraz - x_seconds_ago: "{{count}} s temu" - x_minutes_ago: "{{count}} min temu" - x_hours_ago: "{{count}} h temu" + x_seconds_ago: "{{count}} sek. temu" + x_minutes_ago: "{{count}} min. temu" + x_hours_ago: "{{count}} godz. temu" hour: godzina day: dzień hours: godziny days: dni month: month months: months - year: year + year: rok reaction: heart: serce smile: uśmiech @@ -1127,7 +1184,7 @@ ui: more: Więcej wiki: Wiki ask: - title: Create Question + title: Utwórz pytanie edit_title: Edytuj pytanie default_reason: Edytuj pytanie default_first_reason: Create question @@ -1138,7 +1195,7 @@ ui: label: Rewizja title: label: Tytuł - placeholder: What's your topic? Be specific. + placeholder: Jaki jest temat? Bądź konkretny. msg: empty: Tytuł nie może być pusty. range: Tytuł do 150 znaków @@ -1147,8 +1204,8 @@ ui: msg: empty: Treść nie może być pusta. hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + optional_body: Opisz, czego dotyczy pytanie. + minimum_characters: "Opisz, czego dotyczy pytanie — wymagane jest co najmniej {{min_content_length}} znaków." tags: label: Tagi msg: @@ -1169,9 +1226,9 @@ ui: add_btn: Dodaj tag create_btn: Utwórz nowy tag search_tag: Wyszukaj tag - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + hint: Opisz, czego dotyczy Twoja treść — wymagany jest co najmniej jeden tag. + hint_zero_tags: Opisz, czego dotyczy Twoja treść. + hint_more_than_one_tag: "Opisz, czego dotyczy Twoja treść — wymagane są co najmniej {{min_tags_number}} tagi." no_result: Nie znaleziono pasujących tagów tag_required_text: Wymagany tag (co najmniej jeden) header: @@ -1179,7 +1236,7 @@ ui: question: Pytania tag: Tagi user: Użytkownicy - badges: Badges + badges: Odznaki profile: Profil setting: Ustawienia logout: Wyloguj @@ -1296,13 +1353,13 @@ ui: display_name: label: Nazwa wyświetlana msg: Wyświetlana nazwa nie może być pusta. - msg_range: Display name must be 2-30 characters in length. + msg_range: Wyświetlana nazwa musi mieć od 2 do 30 znaków długości. username: label: Nazwa użytkownika caption: Ludzie mogą oznaczać Cię jako "@nazwa_użytkownika". msg: Nazwa użytkownika nie może być pusta. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' + msg_range: Nazwa użytkownika musi mieć od 2 do 30 znaków długości. + character: 'Muszą być znaki ze zbioru "a-z", "0-9", "- . _"' avatar: label: Zdjęcie profilowe gravatar: Gravatar @@ -1391,11 +1448,11 @@ ui: search: Wyszukaj osoby question_detail: action: Akcja - created: Created + created: Utworzono Asked: Zadane asked: zadał(a) update: Zmodyfikowane - Edited: Edited + Edited: Wyedytowane edit: edytowany commented: skomentowano Views: Wyświetlone @@ -1442,7 +1499,7 @@ ui: list: confirm_btn: Lista title: Pokaż ten post - content: Are you sure you want to list? + content: Czy na pewno chcesz wyświetlić tę listę? unlist: confirm_btn: Usuń z listy title: Usuń ten post z listy @@ -1507,16 +1564,16 @@ ui: normal: Normalny closed: Zamknięty deleted: Usunięty - deleted_permanently: Deleted permanently + deleted_permanently: Usunięto trwale pending: Oczekujący more: Więcej - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites + view: Podgląd + card: Karta + compact: Kompakt + display_below: Wyświetl poniżej + always_display: Wyświetlaj zawsze + or: lub + back_sites: Powrót do stron search: title: Wyniki wyszukiwania keywords: Słowa kluczowe @@ -1524,7 +1581,7 @@ ui: follow: Obserwuj following: Obserwuje counts: "Liczba wyników: {{count}}" - counts_loading: "... Results" + counts_loading: "... Wyniki" more: Więcej sort_btns: relevance: Relewantność @@ -1547,13 +1604,13 @@ ui: via: Udostępnij post za pośrednictwem... copied: Skopiowano facebook: Udostępnij na Facebooku - twitter: Share to X + twitter: Udostępnij na X cannot_vote_for_self: Nie możesz głosować na własne posty. modal_confirm: title: Błąd... delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? + title: Usuń trwale + content: Czy na pewno chcesz usunąć to trwale? account_result: success: Twoje nowe konto zostało potwierdzone; zostaniesz przekierowany na stronę główną. link: Kontynuuj do strony głównej @@ -1582,7 +1639,7 @@ ui: newest: Najnowsze active: Aktywne hot: Gorące - frequent: Frequent + frequent: Częste recommend: Polecane score: Ocena unanswered: Bez odpowiedzi @@ -1628,7 +1685,7 @@ ui: x_votes: otrzymane głosy x_answers: odpowiedzi x_questions: pytania - recent_badges: Recent Badges + recent_badges: Ostatnie odznaki install: title: Instalacja next: Dalej @@ -1667,14 +1724,14 @@ ui: ssl_mode: label: SSL Mode ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty + placeholder: Ścieżka do pliku sslrootcert + msg: Ścieżka do pliku sslrootcert nie może być pusta ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty + placeholder: Ścieżka do pliku sslcert + msg: Ścieżka do pliku sslcert nie może być pusta ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty + placeholder: Ścieżka do pliku sslkey + msg: Ścieżka do pliku sslkey nie może być pusta config_yaml: title: Utwórz plik config.yaml label: Plik config.yaml utworzony. @@ -1717,9 +1774,9 @@ ui: msg_min_length: Hasło musi mieć co najmniej 8 znaków. msg_max_length: Hasło musi mieć maksymalnie 32 znaki. admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." + label: "Potwierdź hasło" + text: "Wprowadź ponownie swoje hasło, aby potwierdzić." + msg: "Potwierdzenie hasła nie jest zgodne." admin_email: label: Email text: Będziesz potrzebować tego adresu e-mail do logowania. @@ -1777,7 +1834,7 @@ ui: privileges: Uprawnienia plugins: Wtyczki installed_plugins: Zainstalowane wtyczki - apperance: Appearance + apperance: Wygląd website_welcome: Witamy w serwisie {{site_name}} user_center: login: Zaloguj się @@ -1786,15 +1843,15 @@ ui: badges: modal: title: Gratulacje - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned + content: Zdobyłeś nową odznakę. + close: Zamknij + confirm: Zobacz odznaki + title: Odznaki + awarded: Przyznano + earned_×: Zdobyto ×{{ number }} + ×_awarded: „{{ number }} przyznano” + can_earn_multiple: Możesz zdobyć tę odznakę wielokrotnie. + earned: Zdobyto admin: admin_header: title: Administrator @@ -1803,15 +1860,15 @@ ui: welcome: Witaj Administratorze! site_statistics: Statystyki witryny questions: "Pytania:" - resolved: "Resolved:" - unanswered: "Unanswered:" + resolved: "Rozwiązane:" + unanswered: "Bez odpowiedzi:" answers: "Odpowiedzi:" comments: "Komentarze:" votes: "Głosy:" users: "Użytkownicy:" - flags: "Flagi:" - reviews: "Reviews:" - site_health: Site health + flags: "Zgłoszenia:" + reviews: "Przeglądy:" + site_health: "Stan serwisu" version: "Wersja:" https: "HTTPS:" upload_folder: "Prześlij folder:" @@ -1876,14 +1933,14 @@ ui: form: fields: display_name: - label: Display name - msg_range: Display name must be 2-30 characters in length. + label: Wyświetlana nazwa + msg_range: Wyświetlana nazwa musi mieć od 2 do 30 znaków. username: - label: Nazwa - msg_range: Username must be 2-30 characters in length. + label: Nazwa użytkownika + msg_range: Nazwa użytkownika musi mieć od 2 do 30 znaków. email: label: Email - msg_invalid: Błędny adresy email. + msg_invalid: Błędny adres e-mail. edit_success: Edycja zakończona pomyślnie btn_cancel: Anuluj btn_submit: Prześlij @@ -1898,7 +1955,7 @@ ui: msg: "Podaj adresy e-mail użytkowników, jeden w każdej linii." display_name: label: Nazwa wyświetlana - msg: Display name must be 2-30 characters in length. + msg: Wyświetlana nazwa musi mieć od 2 do 30 znaków. email: label: E-mail msg: Email nie jest prawidłowy. @@ -1912,10 +1969,10 @@ ui: name: Imię email: E-mail reputation: Reputacja - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until + created_at: Czas utworzenia + delete_at: Czas usunięcia + suspend_at: Czas zawieszenia + suspend_until: Zawieszone do status: Status role: Rola action: Akcja @@ -1950,8 +2007,8 @@ ui: suspend_user: title: Zawieś tego użytkownika content: Zawieszony użytkownik nie może się logować. - label: How long will the user be suspended for? - forever: Forever + label: Na jak długo użytkownik zostanie zawieszony? + forever: Na zawsze questions: page_title: Pytania unlisted: Unlisted @@ -2013,11 +2070,11 @@ ui: msg: Strefa czasowa nie może być pusta. text: Wybierz miasto w tej samej strefie czasowej, co Ty. avatar: - label: Default avatar - text: For users without a custom avatar of their own. + label: Domyślny awatar + text: Dla użytkowników, którzy nie ustawili własnego awatara. gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. + label: Bazowy URL Gravatara + text: Adres bazowy API dostawcy Gravatara. Ignorowane, jeśli puste. smtp: page_title: SMTP from_email: @@ -2096,37 +2153,37 @@ ui: restrict_answer: title: Answer write label: Każdy użytkownik może napisać tylko jedną odpowiedź na każde pytanie - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + text: "Wyłącz, aby pozwolić użytkownikom pisać wiele odpowiedzi na to samo pytanie, co może powodować, że odpowiedzi będą mniej skupione." min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." + label: "Minimalna liczba tagów na pytanie" + text: "Minimalna liczba tagów wymagana w pytaniu." recommend_tags: label: Rekomendowane tagi - text: "Recommend tags will show in the dropdown list by default." + text: "Rekomendowane tagi będą domyślnie wyświetlane na liście wyboru." msg: - contain_reserved: "recommended tags cannot contain reserved tags" + contain_reserved: "Rekomendowane tagi nie mogą zawierać tagów zarezerwowanych." required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags + title: Ustaw wymagane tagi + label: Ustaw „Rekomendowane tagi” jako wymagane text: "Każde nowe pytanie musi mieć przynajmniej jeden rekomendowany tag." reserved_tags: label: Zarezerwowane tagi - text: "Reserved tags can only be used by moderator." + text: "Zarezerwowane tagi mogą być używane tylko przez moderatorów." image_size: - label: Max image size (MB) - text: "The maximum image upload size." + label: Maksymalny rozmiar obrazu (MB) + text: "Maksymalny dopuszczalny rozmiar przesyłanego obrazu." attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." + label: Maksymalny rozmiar załącznika (MB) + text: "Maksymalny dopuszczalny rozmiar przesyłanych plików." image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." + label: Maksymalna liczba megapikseli + text: "Maksymalna liczba megapikseli dopuszczona dla obrazu." image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." + label: Dozwolone rozszerzenia obrazów + text: "Lista rozszerzeń plików dozwolonych dla obrazów; oddziel po przecinkach." attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + label: Dozwolone rozszerzenia załączników + text: "Lista rozszerzeń plików dozwolonych do przesyłania; oddziel po przecinkach. UWAGA: Zezwolenie na przesyłanie plików może powodować ryzyko bezpieczeństwa." seo: page_title: SEO permalink: @@ -2190,7 +2247,7 @@ ui: text: "OSTRZEŻENIE: Jeśli wyłączone, już się nie zalogujesz, jeśli wcześniej nie skonfigurowałeś innej metody logowania." installed_plugins: title: Zainstalowane wtyczki - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + plugin_link: Wtyczki rozszerzają i rozbudowują funkcjonalność. Wtyczki znajdziesz w <1>Repozytorium Wtyczek. filter: all: Wszystkie active: Aktywne @@ -2232,25 +2289,25 @@ ui: title: Uprawnienia level: label: Wymagany poziom reputacji - text: Wybierz reputację wymaganą dla uprawnień + text: Wybierz reputację wymaganą dla tego uprawnienia msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 + should_be_number: Wartość musi być liczbą + number_larger_1: Liczba musi być równa 1 lub większa badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate + action: Akcja + active: Aktywne + activate: Aktywuj + all: Wszystkie + awards: Przyznane + deactivate: Dezaktywuj filter: - placeholder: Filter by name, badge:id + placeholder: Filtruj po nazwie, badge:id group: Grupa - inactive: Inactive - name: Name + inactive: Nieaktywne + name: Nazwa show_logs: Wyświetl dzienniki status: Status - title: Badges + title: Odznaki form: optional: (opcjonalne) empty: nie może być puste @@ -2273,11 +2330,11 @@ ui: approve_flag_tip: Czy akceptujesz tę flagę? approve_post_tip: Czy zatwierdzasz ten post? approve_user_tip: Czy zatwierdzasz tego użytkownika? - suggest_edits: Suggested edits + suggest_edits: Sugerowane edycje flag_post: Oznacz wpis flag_user: Oznacz użytkownika - queued_post: Queued post - queued_user: Queued user + queued_post: Oczekujący post + queued_user: Oczekujący użytkownik filter_label: Typ reputation: reputacja flag_post_type: Oznaczono ten wpis jako {{ type }}. @@ -2330,7 +2387,7 @@ ui: discard_confirm: Czy na pewno chcesz odrzucić swoją wersję roboczą? messages: post_deleted: Ten post został usunięty. - post_cancel_deleted: This post has been undeleted. + post_cancel_deleted: Usunięcie tego posta zostało anulowane. post_pin: Ten post został przypięty. post_unpin: Ten post został odpięty. post_hide_list: Ten post został ukryty na liście. @@ -2339,21 +2396,20 @@ ui: post_list: Ten wpis został umieszczony na liście. post_unlist: Ten wpis został usunięty z listy. post_pending: Twój wpis oczekuje na recenzje. Będzie widoczny po jej akceptacji. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - + post_closed: Ten post został zamknięty. + answer_deleted: Ta odpowiedź została usunięta. + answer_cancel_deleted: Ta odpowiedź została przywrócona. + change_user_role: Rola tego użytkownika została zmieniona. + user_inactive: Ten użytkownik jest już nieaktywny. + user_normal: Ten użytkownik jest już aktywny. + user_suspended: Ten użytkownik został zawieszony. + user_deleted: Ten użytkownik został usunięty. + badge_activated: Ta odznaka została aktywowana. + badge_inactivated: Ta odznaka została dezaktywowana. + users_deleted: Ci użytkownicy zostali usunięci. + posts_deleted: Te pytania zostały usunięte. + answers_deleted: Te odpowiedzi zostały usunięte. + copy: Skopiuj do schowka + copied: Skopiowano + external_content_warning: Zewnętrzne obrazy/media nie są wyświetlane. From 48b1de831473ed9e79fc4f453696428a43e69474 Mon Sep 17 00:00:00 2001 From: joaoback <156559121+joaoback@users.noreply.github.com> Date: Fri, 12 Sep 2025 22:21:32 -0300 Subject: [PATCH 18/92] Update pt_BR.yaml Translations of items that had not yet been translated. Adjustments to translations already made. --- i18n/pt_BR.yaml | 248 ++++++++++++++++++++++++------------------------ 1 file changed, 124 insertions(+), 124 deletions(-) diff --git a/i18n/pt_BR.yaml b/i18n/pt_BR.yaml index 42d56aaf7..45e00873c 100644 --- a/i18n/pt_BR.yaml +++ b/i18n/pt_BR.yaml @@ -288,7 +288,7 @@ ui: change_email: Modificar e-mail install: Instalação do Resposta upgrade: Atualização do Resposta - maintenance: Manutençã do Website + maintenance: Manutenção do Website users: Usuários notifications: title: Notificações @@ -327,7 +327,7 @@ ui: empty: Código não pode ser vazio. language: label: Idioma (opcional) - placeholder: Tetecção automática + placeholder: Detecção automática btn_cancel: Cancelar btn_confirm: Adicionar formula: @@ -351,7 +351,7 @@ ui: image: text: Imagem add_image: Adicionar imagem - tab_image: Enviar image, + tab_image: Enviar imagem form_image: fields: file: @@ -380,7 +380,7 @@ ui: outdent: text: Não identado italic: - text: Emphase + text: Ênfase link: text: Superlink (Hyperlink) add_link: Adicionar superlink (hyperlink) @@ -537,7 +537,7 @@ ui: title: Adicionar Pergunta edit_title: Editar Pergunta default_reason: Editar pergunta - similar_questions: Similar perguntas + similar_questions: Perguntas similares form: fields: revision: @@ -564,10 +564,10 @@ ui: label: Resumo da edição placeholder: >- Explique resumidamente suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada) - btn_post_question: Publicação a sua pergunta + btn_post_question: Publicar a sua pergunta btn_save_edits: Salvar edições answer_question: Responda a sua própria pergunta - post_question&answer: Publicação a sua pergunta e resposta + post_question&answer: Publicar a sua pergunta e resposta tag_selector: add_btn: Adicionar marcador create_btn: Criar novo marcador @@ -589,7 +589,7 @@ ui: placeholder: Procurar footer: build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
Made with love © {{cc}}. + Desenvolvido com base no <1> Answer — o software de código aberto que alimenta comunidades de perguntas e respostas.
Feito com amor © {{cc}}. upload_img: name: Mudar loading: carregando... @@ -604,13 +604,13 @@ ui: info: "Se não chegar, verifique sua pasta de spam." another: >- Enviamos outro e-mail de ativação para você em {{mail}}. Pode levar alguns minutos para chegar; certifique-se de verificar sua pasta de spam. - btn_name: Resend activation email + btn_name: Reenviar e-mail de ativação change_btn_name: Mudar email msg: empty: Não pode ser vazio. login: page_title: Bem vindo ao {{site_name}} - login_to_continue: Entre para continue + login_to_continue: Entre para continuar info_sign: Não possui uma conta? <1>Cadastrar-se info_login: Já possui uma conta? <1>Entre agreements: Ao se registrar, você concorda com as <1>políticas de privacidades e os <3>termos de serviços. @@ -776,9 +776,9 @@ ui: delete: title: Excluir esta postagem question: >- - Nós não recomendamos excluindo perguntas com respostas porque isso priva os futuros leitores desse conhecimento.

Repeated deletion of answered questions can result in a sua account being blocked from asking. Você tem certeza que deseja deletar? + Nós não recomendamos excluir perguntas com respostas porque isso priva os futuros leitores desse conhecimento.

A exclusão repetida de perguntas respondidas pode resultar no bloqueio de perguntas de sua conta. Você tem certeza que deseja excluir? answer_accepted: >- -

Nós não recomendamos deleting accepted answer porque isso priva os futuros leitores desse conhecimento.

Repeated deletion of accepted answers can result in a sua account being blocked from answering. Você tem certeza que deseja deletar? +

Não recomendamos excluir resposta aceita porque isso priva os futuros leitores desse conhecimento.

A exclusão repetida de respostas aceitas pode resultar no bloqueio de respostas de uma conta sua. Você tem certeza que deseja excluir? other: Você tem certeza que deseja deletar? tip_question_deleted: Esta postagem foi deletada tip_answer_deleted: Esta resposta foi deletada @@ -834,7 +834,7 @@ ui: link: Continuar para a página inicial. invalid: >- Desculpe, este link de confirmação não é mais válido. Talvez a sua já está ativa. - confirm_new_email: Your email has been updated. + confirm_new_email: Seu e-mail foi atualizado. confirm_new_email_invalid: >- Desculpe, este link de confirmação não é mais válido. Talvez o seu e-mail já tenha sido alterado. unsubscribe: @@ -846,7 +846,7 @@ ui: following_tags: Seguindo Marcadores edit: Editar save: Salvar - follow_tag_tip: Seguir tags to curate a sua lista de perguntas. + follow_tag_tip: Siga as tags para selecionar sua lista de perguntas. hot_questions: Perguntas quentes all_questions: Todas Perguntas x_questions: "{{ count }} perguntas" @@ -878,7 +878,7 @@ ui: score: Pontuação edit_profile: Editar Perfil visited_x_days: "Visitado {{ count }} dias" - viewed: Viewed + viewed: Visualizado joined: Ingressou last_login: Visto about_me: Sobre mim @@ -900,13 +900,13 @@ ui: x_questions: perguntas install: title: Instalação - next: Proximo + next: Próximo done: Completo config_yaml_error: Não é possível criar o arquivo config.yaml. lang: label: Por favor Escolha um Idioma db_type: - label: Database Engine + label: Mecanismo de banco de dados db_username: label: Nome de usuário placeholder: root @@ -916,68 +916,68 @@ ui: placeholder: root msg: Senha não pode ser vazio. db_host: - label: Database Host + label: Host do banco de dados placeholder: "db:3306" - msg: Database Host não pode ser vazio. + msg: Host de banco de dados não pode ficar vazio. db_name: - label: Database Nome + label: Nome do banco de dados placeholder: answer - msg: Database Nome não pode ser vazio. + msg: O nome do banco de dados não pode ficar vazio. db_file: - label: Database File + label: Arquivo de banco de dados placeholder: /data/answer.db - msg: Database File não pode ser vazio. + msg: O arquivo de banco de dados não pode ficar vazio. config_yaml: - title: Create config.yaml - label: The config.yaml file created. + title: Criar config.yaml + label: O arquivo config.yaml foi criado. desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information + Você pode criar o arquivo <1>config.yaml manualmente no diretório <1>/var/www/xxx/ e colar o seguinte texto nele. + info: Depois de fazer isso, clique no botão "Avançar". + site_information: Informações do site admin_account: Administrador Conta site_name: label: Site Nome msg: Site Nome não pode ser vazio. site_url: label: Site URL - text: The address of a sua site. + text: O endereço do seu site. msg: empty: Site URL não pode ser vazio. - incorrect: Site URL incorrect format. + incorrect: Formato incorreto da URL do site. contact_email: - label: E-mail par contato - text: Email address of key contact responsible for this site. + label: E-mail para contato + text: Endereço de e-mail do contato principal responsável por este site. msg: - empty: E-mail par contato não pode ser vazio. - incorrect: E-mail par contato incorrect format. + empty: E-mail para contato não pode ser vazio. + incorrect: E-mail para contato em formato incorreto. admin_name: label: Nome msg: Nome não pode ser vazio. admin_password: label: Senha text: >- - You will need this password to log in. Por favor store it in a secure location. - msg: Senha não pode ser vazio. + Você precisará dessa senha para efetuar login. Por favor, guarde-a em um local seguro. + msg: Senha não pode ser vazia. admin_email: label: Email - text: You will need this email to log in. + text: Você precisará deste e-mail para fazer login. msg: empty: Email não pode ser vazio. - incorrect: Email incorrect format. - ready_title: Your Resposta is Ready! + incorrect: Formato de e-mail incorreto. + ready_title: Sua resposta está pronta! ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning + Se você quiser alterar mais configurações, visite a <1>seção de administração; encontre-a no menu do site. + good_luck: "Divirta-se e boa sorte!" + warn_title: Aviso warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed + O arquivo <1>config.yaml já existe. Se precisar redefinir algum item de configuração neste arquivo, exclua-o primeiro. + install_now: Você pode tentar <1>instalar agora. + installed: Já instalado installed_desc: >- - You appear to have already installed. To reinstall please clear a sua old database tables first. - db_failed: Database connection failed + Parece que você já instalou. Para reinstalar, limpe primeiro as tabelas antigas do seu banco de dados. + db_failed: Falha na conexão do banco de dados db_failed_desc: >- - This either means that the database information in a sua <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean a sua host's database server is down. + Isso significa que as informações do banco de dados em um arquivo <1>config.yaml do SUA estão incorretas ou que o contato com o servidor do banco de dados não pôde ser estabelecido. Isso pode significar que o servidor de banco de dados de um host SUA está inativo. counts: views: visualizações Votos: votos @@ -987,7 +987,7 @@ ui: desc: "Infelizmente, esta postagem não existe mais." back_home: Voltar para a página inicial page_50X: - desc: O servidor encontrou um erro e não pôde concluir uma solicitação sua. + desc: O servidor encontrou um erro e não pôde concluir sua solicitação. back_home: Voltar para a página inicial page_maintenance: desc: "Estamos em manutenção, voltaremos em breve." @@ -1037,7 +1037,7 @@ ui: answer_links: Links das Respostas documents: Documentos feedback: Opinião - support: Supporte + support: Suporte review: Revisar config: Configurações update_to: Atualizar ao @@ -1233,7 +1233,7 @@ ui: smtp_port: label: SMTP Port msg: SMTP port must be number 1 ~ 65535. - text: The port to a sua mail server. + text: A porta para seu servidor de e-mail. smtp_username: label: SMTP Nome de usuário msg: SMTP username não pode ser vazio. @@ -1241,9 +1241,9 @@ ui: label: SMTP Senha msg: SMTP password não pode ser vazio. test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid + label: Destinatários de e-mail de teste + text: Forneça o endereço de e-mail que receberá os envios de testes. + msg: Os destinatários do e-mail de teste são inválidos smtp_authentication: label: Enable authentication title: SMTP Authentication @@ -1255,127 +1255,127 @@ ui: logo: label: Logo (opcional) msg: Logo não pode ser vazio. - text: The logo image at the top left of a sua site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + text: A imagem do logotipo no canto superior esquerdo do seu site. Use uma imagem retangular larga com altura de 56 e proporção maior que 3:1. Se deixada em branco, o texto do título do site será exibido. mobile_logo: label: Mobile Logo (opcional) - text: The logo used on mobile version of a sua site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + text: O logotipo usado na versão mobile do seu site. Use uma imagem retangular larga com altura de 56. Se deixado em branco, a imagem da configuração "logotipo" será usada. square_icon: label: Square Icon (opcional) msg: Square icon não pode ser vazio. - text: Imagem used as the base for metadata icons. Should ideally be larger than 512x512. + text: Imagem usada como base para ícones de metadados. Idealmente, deve ser maior que 512x512. favicon: label: Favicon (opcional) - text: A favicon for a sua site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + text: Um favicon para o seu site. Para funcionar corretamente em uma CDN, ele deve ser um png. Será redimensionado para 32x32. Se deixado em branco, o "ícone quadrado" será usado. legal: page_title: Legal terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + label: Termos de Serviço + text: "Você pode adicionar conteúdo dos termos de serviço aqui. Se você já possui um documento hospedado em outro lugar, informe o URL completo aqui." privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + label: Política de Privacidade + text: "Você pode adicionar o conteúdo da política de privacidade aqui. Se você já possui um documento hospedado em outro lugar, informe o URL completo aqui." write: - page_title: Write + page_title: Escrever recommend_tags: - label: Recommend Marcadores - text: "Por favor input tag slug above, one tag per line." + label: Recomendar Marcadores + text: "Por favor, insira o slug da tag acima, uma tag por linha." required_tag: - title: Required Tag - label: Set recommend tag as requirido - text: "Every new question must have ao menos one recommend tag." + title: Tag necessária + label: Definir tag recomendada como necessária + text: "Cada nova pergunta deve ter pelo menos uma tag de recomendação." reserved_tags: - label: Reserved Marcadores - text: "Reserved tags can only be added to a post by moderator." + label: Marcadores Reservados + text: "Tags reservadas só podem ser adicionadas a uma postagem pelo moderador." seo: page_title: SEO permalink: label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of a sua links. + text: Estruturas de URL personalizadas podem melhorar a usabilidade e a compatibilidade futura de seus links. robots: label: robots.txt - text: This will permanently override any related site settings. + text: Isso substituirá permanentemente todas as configurações relacionadas do site. Temas: page_title: Temas Temas: label: Temas - text: Select an existing Tema. + text: Selecione um tema existente. navbar_style: - label: Navbar Style - text: Select an existing Tema. + label: Estilo da barra de navegação + text: Selecione um tema existente. primary_color: - label: Primary Color - text: Modify the colors used by a sua Temas + label: Cor primária + text: Modifique as cores usadas por seus Temas css_and_html: - page_title: CSS and HTML + page_title: CSS e HTML custom_css: label: Custom CSS - text: This will insert as + text: Isto será inserido como head: label: Head - text: This will insert before + text: Isto será inserido antes de header: label: Header - text: This will insert after + text: Isto será inserido após footer: label: Footer - text: This will insert before . + text: Isso será inserido antes de . login: page_title: Login membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. + title: Associação + label: Permitir novos registros + text: Desative para impedir que alguém crie uma nova conta. private: - title: Private + title: Privado label: Login requirido - text: Only logged in users can access this community. + text: Somente usuários logados podem acessar esta comunidade. form: empty: não pode ser vazio - invalid: is invalid + invalid: é inválido btn_submit: Salvar - not_found_props: "Required property {{ key }} not found." + not_found_props: "Propriedade necessária {{ key }} não encontrada." page_review: review: Revisar - proposed: proposed - question_edit: Pergunta edit - answer_edit: Resposta edit - tag_edit: Tag edit - edit_summary: Editar summary - edit_question: Editar question - edit_answer: Editar answer + proposed: proposta + question_edit: Editar Pergunta + answer_edit: Editar Resposta + tag_edit: Editar Tag + edit_summary: Editar resumo + edit_question: Editar pergunta + edit_answer: Editar resposta edit_tag: Editar tag - empty: No review tasks left. + empty: Não há mais tarefas de revisão. timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented + undeleted: não excluído + deleted: apagado + downvote: voto negativo + upvote: voto positivo + accept: aceitar + cancelled: cancelado + commented: comentado rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "Histórico for" - tag_title: "Timeline for" - show_Votos: "Show Votos" + edited: editado + answered: respondido + asked: perguntado + closed: fechado + reopened: reaberto + created: criado + title: "Histórico para" + tag_title: "Linha do tempo para" + show_Votos: "Mostrar votos" n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" + title_for_question: "Linha do tempo para" + title_for_answer: "Linha do tempo para resposta a {{ title }} por {{ author }}" + title_for_tag: "Linha do tempo para tag" datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." + type: Tipo + by: Por + comment: Comentário + no_data: "Não conseguimos encontrar nada." users: title: Usuários - users_with_the_most_reputation: Usuários with the highest reputation scores - users_with_the_most_vote: Usuários who voted the most - staffs: Our community staff - reputation: reputation + users_with_the_most_reputation: Usuários com as maiores pontuações de reputação + users_with_the_most_vote: Usuários que mais votaram + staffs: Nossa equipe comunitária + reputation: reputação Votos: Votos From 57ba299543e91b9f00362bfb3b0452bf2ccf0f35 Mon Sep 17 00:00:00 2001 From: Burak Tekin Date: Thu, 11 Dec 2025 04:42:21 +0300 Subject: [PATCH 19/92] chore: turkish translation improved (#1454) turkish translations improved Co-authored-by: dashuai --- i18n/tr_TR.yaml | 56 ++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/i18n/tr_TR.yaml b/i18n/tr_TR.yaml index 92d97ebe2..86a6321c2 100644 --- a/i18n/tr_TR.yaml +++ b/i18n/tr_TR.yaml @@ -234,8 +234,8 @@ backend: other: Güncelleme izni yok. content_cannot_empty: other: İçerik boş olamaz. - content_less_than_minimum: - other: Not enough content entered. + content_less_than_minumum: + other: Yeterli içerik girilmedi. rank: fail_to_meet_the_condition: other: İtibar seviyesi koşulu karşılamıyor. @@ -266,7 +266,7 @@ backend: cannot_set_synonym_as_itself: other: Bir etiketin eş anlamlısını kendisi olarak ayarlayamazsınız. minimum_count: - other: Not enough tags were entered. + other: Yeterli sayıda etiket girilmedi. smtp: config_from_name_cannot_be_email: other: Gönderen adı bir e-posta adresi olamaz. @@ -311,13 +311,13 @@ backend: add_bulk_users_amount_error: other: "Bir kerede eklediğiniz kullanıcı sayısı 1-{{.MaxAmount}} aralığında olmalıdır." status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." + other: "Bu kullanıcı süresiz olarak askıya alındı. Bu kullanıcı topluluk kurallarını karşılamıyor." status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + other: "Bu kullanıcı {{.SuspendedUntil}} tarihine kadar askıya alındı. Bu kullanıcı topluluk kurallarını karşılamıyor." status_deleted: - other: "This user was deleted." + other: "Bu kullanıcı silindi." status_inactive: - other: "This user is inactive." + other: "Bu kullanıcı aktif değil." config: read_config_failed: other: Yapılandırma okunamadı. @@ -821,7 +821,7 @@ ui: tag_wiki: etiket wikisi create_tag: Etiket Oluştur edit_tag: Etiketi Düzenle - ask_a_question: Create Question + ask_a_question: Soru Oluştur edit_question: Soruyu Düzenle edit_answer: Cevabı Düzenle search: Ara @@ -1069,9 +1069,9 @@ ui: day: gün hours: saatler days: günler - month: month - months: months - year: year + month: ay + months: aylar + year: yıl reaction: heart: kalp smile: gülümseme @@ -1127,10 +1127,10 @@ ui: more: Daha Fazla wiki: Wiki ask: - title: Create Question + title: Soru Oluştur edit_title: Soruyu Düzenle default_reason: Soruyu düzenle - default_first_reason: Create question + default_first_reason: Soru oluştur similar_questions: Benzer sorular form: fields: @@ -1138,7 +1138,7 @@ ui: label: Revizyon title: label: Başlık - placeholder: What's your topic? Be specific. + placeholder: Konunuz nedir? Ayrıntılı belirtin. msg: empty: Başlık boş olamaz. range: Başlık en fazla 150 karakter olabilir @@ -1147,8 +1147,8 @@ ui: msg: empty: İçerik boş olamaz. hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + optional_body: Sorunun ne hakkında olduğunu açıklayın. + minimum_characters: "Sorunun ne hakkında olduğunu açıklayın, en az {{min_content_length}} karakter gereklidir." tags: label: Etiketler msg: @@ -1169,9 +1169,9 @@ ui: add_btn: Etiket ekle create_btn: Yeni etiket oluştur search_tag: Etiket ara - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + hint: İçeriğinizin ne hakkında olduğunu açıklayın, en az bir etiket gereklidir. + hint_zero_tags: İçeriğinizin ne hakkında olduğunu açıklayın. + hint_more_than_one_tag: "İçeriğinizin ne hakkında olduğunu açıklayın, en az {{min_tags_number}} etiket gereklidir." no_result: Eşleşen etiket bulunamadı tag_required_text: Gerekli etiket (en az bir tane) header: @@ -1377,12 +1377,12 @@ ui: review: Revizyonunuz incelendikten sonra görünecek. sent_success: Başarıyla gönderildi related_question: - title: Related + title: İlgili answers: cevap linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. + title: Bağlantılı + description: Bağlantılı gönderiler + no_linked_question: Bu içerikten bağlantı verilen içerik yok. invite_to_answer: title: İnsanları Davet Et desc: Cevap verebileceğini düşündüğünüz kişileri davet edin. @@ -1391,11 +1391,11 @@ ui: search: Kişi ara question_detail: action: Eylem - created: Created + created: Oluşturuldu Asked: Soruldu asked: sordu update: Değiştirildi - Edited: Edited + Edited: Düzenlendi edit: düzenledi commented: yorum yaptı Views: Görüntülendi @@ -1403,7 +1403,7 @@ ui: Following: Takip Ediliyor follow_tip: Bildirim almak için bu soruyu takip edin answered: cevapladı - closed_in: Şurada kapatıldı + closed_in: Burada kapatıldı show_exist: Var olan soruyu göster. useful: Faydalı question_useful: Faydalı ve açık @@ -2098,8 +2098,8 @@ ui: label: Her kullanıcı aynı soru için sadece bir cevap yazabilir text: "Kullanıcıların aynı soruya birden fazla cevap yazmasına izin vermek için kapatın, bu cevapların odaktan uzaklaşmasına neden olabilir." min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." + label: "Soru başına minimum etiket" + text: "Bir soruda bulunması gereken minimum etiket sayısı." recommend_tags: label: Önerilen etiketler text: "Önerilen etiketler varsayılan olarak açılır listede gösterilecektir." From d468e2ba8dee2577ff0af8e7cbcfb2b111f6abdb Mon Sep 17 00:00:00 2001 From: liruohrh <2372221537@qq.com> Date: Sun, 7 Dec 2025 00:51:15 +0800 Subject: [PATCH 20/92] feat: add env for glob load template files by gin debug render --- internal/base/server/http.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/internal/base/server/http.go b/internal/base/server/http.go index 4fbb04cb2..512f3da21 100644 --- a/internal/base/server/http.go +++ b/internal/base/server/http.go @@ -22,6 +22,7 @@ package server import ( "html/template" "io/fs" + "os" brotli "github.com/anargu/gin-brotli" "github.com/apache/answer/internal/base/middleware" @@ -53,9 +54,14 @@ func NewHTTPServer(debug bool, r.Use(brotli.Brotli(brotli.DefaultCompression), middleware.ExtractAndSetAcceptLanguage, shortIDMiddleware.SetShortIDFlag()) r.GET("/healthz", func(ctx *gin.Context) { ctx.String(200, "OK") }) - html, _ := fs.Sub(ui.Template, "template") - htmlTemplate := template.Must(template.New("").Funcs(funcMap).ParseFS(html, "*")) - r.SetHTMLTemplate(htmlTemplate) + templatePath := os.Getenv("ANSWER_TEMPLATE_PATH") + if templatePath != "" { + r.LoadHTMLGlob(templatePath) + } else { + html, _ := fs.Sub(ui.Template, "template") + htmlTemplate := template.Must(template.New("").Funcs(funcMap).ParseFS(html, "*")) + r.SetHTMLTemplate(htmlTemplate) + } r.Use(middleware.HeadersByRequestURI()) viewRouter.Register(r, uiConf.BaseURL) From fbb877ab11760b69ee17cb0d00822fead64e60c9 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Thu, 11 Dec 2025 14:23:17 +0800 Subject: [PATCH 21/92] fix(translator): enhance error reporting for invalid translator YAML files --- internal/base/translator/provider.go | 165 +++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/internal/base/translator/provider.go b/internal/base/translator/provider.go index 47212e84f..1a465b1e8 100644 --- a/internal/base/translator/provider.go +++ b/internal/base/translator/provider.go @@ -23,6 +23,8 @@ import ( "fmt" "os" "path/filepath" + "sort" + "strings" "github.com/google/wire" myTran "github.com/segmentfault/pacman/contrib/i18n" @@ -100,6 +102,7 @@ func NewTranslator(c *I18n) (tr i18n.Translator, err error) { // add translator use backend translation if err = myTran.AddTranslator(content, file.Name()); err != nil { log.Debugf("add translator failed: %s %s", file.Name(), err) + reportTranslatorFormatError(file.Name(), buf) continue } } @@ -160,3 +163,165 @@ func TrWithData(lang i18n.Language, key string, templateData any) string { } return translation } + +// reportTranslatorFormatError re-parses the YAML file to locate the invalid entry +// when go-i18n fails to add the translator. +func reportTranslatorFormatError(fileName string, content []byte) { + var raw any + if err := yaml.Unmarshal(content, &raw); err != nil { + log.Errorf("parse translator file %s failed when diagnosing format error: %s", fileName, err) + return + } + if err := inspectTranslatorNode(raw, nil, true); err != nil { + log.Errorf("translator file %s invalid: %s", fileName, err) + } +} + +func inspectTranslatorNode(node any, path []string, isRoot bool) error { + switch data := node.(type) { + case nil: + if isRoot { + return fmt.Errorf("root value is empty") + } + return fmt.Errorf("%s contains an empty value", formatTranslationPath(path)) + case string: + if isRoot { + return fmt.Errorf("root value must be an object but found string") + } + return nil + case bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64: + if isRoot { + return fmt.Errorf("root value must be an object but found %T", data) + } + return fmt.Errorf("%s expects a string translation but found %T", formatTranslationPath(path), data) + case map[string]any: + if isMessageMap(data) { + return nil + } + keys := make([]string, 0, len(data)) + for key := range data { + keys = append(keys, key) + } + sort.Strings(keys) + for _, key := range keys { + if err := inspectTranslatorNode(data[key], append(path, key), false); err != nil { + return err + } + } + return nil + case map[string]string: + mapped := make(map[string]any, len(data)) + for k, v := range data { + mapped[k] = v + } + return inspectTranslatorNode(mapped, path, isRoot) + case map[any]any: + if isMessageMap(data) { + return nil + } + type kv struct { + key string + val any + } + items := make([]kv, 0, len(data)) + for key, val := range data { + strKey, ok := key.(string) + if !ok { + return fmt.Errorf("%s uses a non-string key %#v", formatTranslationPath(path), key) + } + items = append(items, kv{key: strKey, val: val}) + } + sort.Slice(items, func(i, j int) bool { + return items[i].key < items[j].key + }) + for _, item := range items { + if err := inspectTranslatorNode(item.val, append(path, item.key), false); err != nil { + return err + } + } + return nil + case []any: + for idx, child := range data { + nextPath := append(path, fmt.Sprintf("[%d]", idx)) + if err := inspectTranslatorNode(child, nextPath, false); err != nil { + return err + } + } + return nil + case []map[string]any: + for idx, child := range data { + nextPath := append(path, fmt.Sprintf("[%d]", idx)) + if err := inspectTranslatorNode(child, nextPath, false); err != nil { + return err + } + } + return nil + default: + if isRoot { + return fmt.Errorf("root value must be an object but found %T", data) + } + return fmt.Errorf("%s contains unsupported value type %T", formatTranslationPath(path), data) + } +} + +var translatorReservedKeys = []string{ + "id", "description", "hash", "leftdelim", "rightdelim", + "zero", "one", "two", "few", "many", "other", +} + +func isMessageMap(data any) bool { + switch v := data.(type) { + case map[string]any: + for _, key := range translatorReservedKeys { + val, ok := v[key] + if !ok { + continue + } + if _, ok := val.(string); ok { + return true + } + } + case map[string]string: + for _, key := range translatorReservedKeys { + val, ok := v[key] + if !ok { + continue + } + if val != "" { + return true + } + } + case map[any]any: + for _, key := range translatorReservedKeys { + val, ok := v[key] + if !ok { + continue + } + if _, ok := val.(string); ok { + return true + } + } + } + return false +} + +func formatTranslationPath(path []string) string { + if len(path) == 0 { + return "root" + } + var b strings.Builder + for _, part := range path { + if part == "" { + continue + } + if part[0] == '[' { + b.WriteString(part) + continue + } + if b.Len() > 0 { + b.WriteByte('.') + } + b.WriteString(part) + } + return b.String() +} From e35b9551597aa5979b624b342e7e923cee814988 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Mon, 15 Dec 2025 12:34:42 +0800 Subject: [PATCH 22/92] fix(lang): enhance language retrieval from gin context --- internal/base/handler/lang.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/internal/base/handler/lang.go b/internal/base/handler/lang.go index 8886f0631..202449e9d 100644 --- a/internal/base/handler/lang.go +++ b/internal/base/handler/lang.go @@ -23,11 +23,22 @@ import ( "context" "github.com/apache/answer/internal/base/constant" + "github.com/gin-gonic/gin" "github.com/segmentfault/pacman/i18n" ) // GetLangByCtx get language from header func GetLangByCtx(ctx context.Context) i18n.Language { + if ginCtx, ok := ctx.(*gin.Context); ok { + acceptLanguage, ok := ginCtx.Get(constant.AcceptLanguageFlag) + if ok { + if acceptLanguage, ok := acceptLanguage.(i18n.Language); ok { + return acceptLanguage + } + return i18n.DefaultLanguage + } + } + acceptLanguage, ok := ctx.Value(constant.AcceptLanguageContextKey).(i18n.Language) if ok { return acceptLanguage From 59408774fba059d039846a88cf2aebd2b943c042 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Mon, 15 Dec 2025 15:08:51 +0800 Subject: [PATCH 23/92] fix(lang): correct translations in Polish and Turkish language files --- i18n/pl_PL.yaml | 3 +-- i18n/tr_TR.yaml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/i18n/pl_PL.yaml b/i18n/pl_PL.yaml index a8d7b064a..7cf88431b 100644 --- a/i18n/pl_PL.yaml +++ b/i18n/pl_PL.yaml @@ -864,8 +864,7 @@ ui:
  • twórz bloki kodu przy pomocy potrójnych odwrotnych apostrofów `

    ```
    kod tutaj
    ```
  • - - + prev: Poprzedni next: Następny page_title: diff --git a/i18n/tr_TR.yaml b/i18n/tr_TR.yaml index 970ae8cb2..802a81f69 100644 --- a/i18n/tr_TR.yaml +++ b/i18n/tr_TR.yaml @@ -235,7 +235,7 @@ backend: content_cannot_empty: other: İçerik boş olamaz. content_less_than_minimum: - other: Yeterli içerik girilmedi. + other: Not enough content entered. rank: fail_to_meet_the_condition: other: İtibar seviyesi koşulu karşılamıyor. From 9ef55ca07c66bbdd8251c7be14f583e8879afa99 Mon Sep 17 00:00:00 2001 From: robin Date: Mon, 8 Dec 2025 09:37:48 +0800 Subject: [PATCH 24/92] feat(editor): integrate TipTap WYSIWYG editor with Markdown support and enhance editor functionalities - Added TipTap extensions for image, placeholder, table, and markdown support. - Implemented WYSIWYG and Markdown editor components. - Refactored editor context and tool items to utilize the new editor interface. - Updated styles for the WYSIWYG editor. - Removed deprecated utility functions and integrated new command methods for better editor interaction. --- ui/package.json | 8 +- ui/pnpm-lock.yaml | 2165 +++++++++++++++-- ui/src/components/Editor/EditorContext.ts | 4 +- ui/src/components/Editor/MarkdownEditor.tsx | 112 + .../components/Editor/ToolBars/blockquote.tsx | 21 +- ui/src/components/Editor/ToolBars/bold.tsx | 10 +- ui/src/components/Editor/ToolBars/code.tsx | 32 +- ui/src/components/Editor/ToolBars/file.tsx | 15 +- ui/src/components/Editor/ToolBars/heading.tsx | 24 +- ui/src/components/Editor/ToolBars/hr.tsx | 11 +- ui/src/components/Editor/ToolBars/image.tsx | 99 +- ui/src/components/Editor/ToolBars/indent.tsx | 15 +- ui/src/components/Editor/ToolBars/italic.tsx | 11 +- ui/src/components/Editor/ToolBars/link.tsx | 27 +- ui/src/components/Editor/ToolBars/ol.tsx | 19 +- ui/src/components/Editor/ToolBars/outdent.tsx | 16 +- ui/src/components/Editor/ToolBars/table.tsx | 67 +- ui/src/components/Editor/ToolBars/ul.tsx | 19 +- ui/src/components/Editor/WysiwygEditor.tsx | 162 ++ ui/src/components/Editor/index.scss | 113 + ui/src/components/Editor/index.tsx | 153 +- ui/src/components/Editor/toolItem.tsx | 42 +- ui/src/components/Editor/types.ts | 54 +- .../Editor/utils/codemirror/adapter.ts | 59 + .../Editor/utils/codemirror/base.ts | 110 + .../Editor/utils/codemirror/commands.ts | 264 ++ .../Editor/utils/codemirror/events.ts | 98 + ui/src/components/Editor/utils/extension.ts | 255 -- ui/src/components/Editor/utils/index.ts | 4 +- .../components/Editor/utils/tiptap/adapter.ts | 59 + ui/src/components/Editor/utils/tiptap/base.ts | 358 +++ .../Editor/utils/tiptap/commands.ts | 718 ++++++ .../Editor/utils/tiptap/constants.ts | 48 + .../Editor/utils/tiptap/errorHandler.ts | 155 ++ .../components/Editor/utils/tiptap/events.ts | 98 + .../Editor/utils/tiptap/position.ts | 147 ++ ui/src/pages/Questions/Detail/index.scss | 9 +- 37 files changed, 4819 insertions(+), 762 deletions(-) create mode 100644 ui/src/components/Editor/MarkdownEditor.tsx create mode 100644 ui/src/components/Editor/WysiwygEditor.tsx create mode 100644 ui/src/components/Editor/utils/codemirror/adapter.ts create mode 100644 ui/src/components/Editor/utils/codemirror/base.ts create mode 100644 ui/src/components/Editor/utils/codemirror/commands.ts create mode 100644 ui/src/components/Editor/utils/codemirror/events.ts delete mode 100644 ui/src/components/Editor/utils/extension.ts create mode 100644 ui/src/components/Editor/utils/tiptap/adapter.ts create mode 100644 ui/src/components/Editor/utils/tiptap/base.ts create mode 100644 ui/src/components/Editor/utils/tiptap/commands.ts create mode 100644 ui/src/components/Editor/utils/tiptap/constants.ts create mode 100644 ui/src/components/Editor/utils/tiptap/errorHandler.ts create mode 100644 ui/src/components/Editor/utils/tiptap/events.ts create mode 100644 ui/src/components/Editor/utils/tiptap/position.ts diff --git a/ui/package.json b/ui/package.json index b88fc12da..5a6704ceb 100644 --- a/ui/package.json +++ b/ui/package.json @@ -21,6 +21,12 @@ "@codemirror/language-data": "^6.5.0", "@codemirror/state": "^6.5.0", "@codemirror/view": "^6.26.1", + "@tiptap/extension-image": "^3.11.1", + "@tiptap/extension-placeholder": "^3.11.1", + "@tiptap/extension-table": "^3.11.1", + "@tiptap/markdown": "^3.11.1", + "@tiptap/react": "^3.11.1", + "@tiptap/starter-kit": "^3.11.1", "axios": "^1.7.7", "bootstrap": "^5.3.2", "bootstrap-icons": "^1.10.5", @@ -100,4 +106,4 @@ "pnpm": ">=9" }, "license": "MIT" -} +} \ No newline at end of file diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index 842009a70..901c503de 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -20,6 +20,36 @@ importers: '@codemirror/view': specifier: ^6.26.1 version: 6.35.3 + '@tiptap/extension-image': + specifier: ^3.11.1 + version: 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) + '@tiptap/extension-list': + specifier: ^3.11.1 + version: 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-placeholder': + specifier: ^3.11.1 + version: 3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-table': + specifier: ^3.11.1 + version: 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-table-cell': + specifier: ^3.11.1 + version: 3.11.1(@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-table-header': + specifier: ^3.11.1 + version: 3.11.1(@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-table-row': + specifier: ^3.11.1 + version: 3.11.1(@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/markdown': + specifier: ^3.11.1 + version: 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/react': + specifier: ^3.11.1 + version: 3.11.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@tiptap/starter-kit': + specifier: ^3.11.1 + version: 3.11.1 axios: specifier: ^1.7.7 version: 1.7.9 @@ -97,11 +127,11 @@ importers: version: 1.3.0(react@18.3.1) zustand: specifier: ^5.0.2 - version: 5.0.2(@types/react@18.3.16)(immer@9.0.21)(react@18.3.1)(use-sync-external-store@1.2.2(react@18.3.1)) + version: 5.0.2(@types/react@18.3.16)(immer@9.0.21)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)) devDependencies: '@commitlint/cli': specifier: ^17.0.3 - version: 17.8.1 + version: 17.8.1(@swc/core@1.15.3) '@commitlint/config-conventional': specifier: ^17.2.0 version: 17.8.1 @@ -212,13 +242,13 @@ importers: version: 3.4.2 purgecss-webpack-plugin: specifier: ^4.1.3 - version: 4.1.3(webpack@5.97.1) + version: 4.1.3(webpack@5.97.1(@swc/core@1.15.3)) react-app-rewired: specifier: ^2.2.1 - version: 2.2.1(react-scripts@5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(sass@1.54.4)(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5))(type-fest@1.4.0)(typescript@4.9.5)) + version: 2.2.1(react-scripts@5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(@swc/core@1.15.3)(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(sass@1.54.4)(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5))(type-fest@1.4.0)(typescript@4.9.5)(vue-template-compiler@2.7.16)) react-scripts: specifier: 5.0.1 - version: 5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(sass@1.54.4)(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5))(type-fest@1.4.0)(typescript@4.9.5) + version: 5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(@swc/core@1.15.3)(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(sass@1.54.4)(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5))(type-fest@1.4.0)(typescript@4.9.5)(vue-template-compiler@2.7.16) sass: specifier: 1.54.4 version: 1.54.4 @@ -232,6 +262,190 @@ importers: specifier: ^0.8.0 version: 0.8.1 + src/plugins/demo-captcha: + dependencies: + react: + specifier: ^18.2.0 + version: 18.3.1 + react-bootstrap: + specifier: ^2.10.0 + version: 2.10.6(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-dom: + specifier: ^18.2.0 + version: 18.3.1(react@18.3.1) + react-i18next: + specifier: ^11.18.3 + version: 11.18.6(i18next@21.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + devDependencies: + '@modyfi/vite-plugin-yaml': + specifier: ^1.1.0 + version: 1.1.1(rollup@3.29.5)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) + '@typescript-eslint/eslint-plugin': + specifier: ^6.0.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^6.0.0 + version: 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@vitejs/plugin-react-swc': + specifier: ^3.3.2 + version: 3.11.0(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) + eslint: + specifier: ^8.45.0 + version: 8.57.1 + eslint-plugin-react-hooks: + specifier: ^4.6.0 + version: 4.6.2(eslint@8.57.1) + eslint-plugin-react-refresh: + specifier: ^0.4.3 + version: 0.4.24(eslint@8.57.1) + typescript: + specifier: ^5.0.2 + version: 5.9.3 + vite: + specifier: ^4.4.5 + version: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) + vite-plugin-dts: + specifier: ^3.9.1 + version: 3.9.1(@types/node@20.5.1)(rollup@3.29.5)(typescript@5.9.3)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) + + src/plugins/demo-editor: + dependencies: + react: + specifier: ^18.2.0 + version: 18.3.1 + react-bootstrap: + specifier: ^2.10.0 + version: 2.10.6(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-dom: + specifier: ^18.2.0 + version: 18.3.1(react@18.3.1) + react-i18next: + specifier: ^11.18.3 + version: 11.18.6(i18next@21.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + devDependencies: + '@modyfi/vite-plugin-yaml': + specifier: ^1.1.0 + version: 1.1.1(rollup@3.29.5)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) + '@typescript-eslint/eslint-plugin': + specifier: ^6.0.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^6.0.0 + version: 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@vitejs/plugin-react-swc': + specifier: ^3.3.2 + version: 3.11.0(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) + eslint: + specifier: ^8.45.0 + version: 8.57.1 + eslint-plugin-react-hooks: + specifier: ^4.6.0 + version: 4.6.2(eslint@8.57.1) + eslint-plugin-react-refresh: + specifier: ^0.4.3 + version: 0.4.24(eslint@8.57.1) + typescript: + specifier: ^5.0.2 + version: 5.9.3 + vite: + specifier: ^4.4.5 + version: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) + vite-plugin-dts: + specifier: ^3.9.1 + version: 3.9.1(@types/node@20.5.1)(rollup@3.29.5)(typescript@5.9.3)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) + + src/plugins/demo-render: + dependencies: + react: + specifier: ^18.2.0 + version: 18.3.1 + react-bootstrap: + specifier: ^2.10.0 + version: 2.10.6(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-dom: + specifier: ^18.2.0 + version: 18.3.1(react@18.3.1) + react-i18next: + specifier: ^11.18.3 + version: 11.18.6(i18next@21.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + devDependencies: + '@modyfi/vite-plugin-yaml': + specifier: ^1.1.0 + version: 1.1.1(rollup@3.29.5)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) + '@typescript-eslint/eslint-plugin': + specifier: ^6.0.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^6.0.0 + version: 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@vitejs/plugin-react-swc': + specifier: ^3.3.2 + version: 3.11.0(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) + eslint: + specifier: ^8.45.0 + version: 8.57.1 + eslint-plugin-react-hooks: + specifier: ^4.6.0 + version: 4.6.2(eslint@8.57.1) + eslint-plugin-react-refresh: + specifier: ^0.4.3 + version: 0.4.24(eslint@8.57.1) + typescript: + specifier: ^5.0.2 + version: 5.9.3 + vite: + specifier: ^4.4.5 + version: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) + vite-plugin-dts: + specifier: ^3.9.1 + version: 3.9.1(@types/node@20.5.1)(rollup@3.29.5)(typescript@5.9.3)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) + + src/plugins/demo-route: + dependencies: + react: + specifier: ^18.2.0 + version: 18.3.1 + react-bootstrap: + specifier: ^2.10.0 + version: 2.10.6(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-dom: + specifier: ^18.2.0 + version: 18.3.1(react@18.3.1) + react-i18next: + specifier: ^11.18.3 + version: 11.18.6(i18next@21.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + devDependencies: + '@modyfi/vite-plugin-yaml': + specifier: ^1.1.0 + version: 1.1.1(rollup@3.29.5)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) + '@typescript-eslint/eslint-plugin': + specifier: ^6.0.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^6.0.0 + version: 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@vitejs/plugin-react-swc': + specifier: ^3.3.2 + version: 3.11.0(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) + eslint: + specifier: ^8.45.0 + version: 8.57.1 + eslint-plugin-react-hooks: + specifier: ^4.6.0 + version: 4.6.2(eslint@8.57.1) + eslint-plugin-react-refresh: + specifier: ^0.4.3 + version: 0.4.24(eslint@8.57.1) + typescript: + specifier: ^5.0.2 + version: 5.9.3 + vite: + specifier: ^4.4.5 + version: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) + vite-plugin-dts: + specifier: ^3.9.1 + version: 3.9.1(@types/node@20.5.1)(rollup@3.29.5)(typescript@5.9.3)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) + packages: '@alloc/quick-lru@5.2.0': @@ -338,10 +552,18 @@ packages: resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.25.9': resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} @@ -359,6 +581,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9': resolution: {integrity: sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==} engines: {node: '>=6.9.0'} @@ -945,6 +1172,10 @@ packages: resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} engines: {node: '>=6.9.0'} + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -1206,6 +1437,138 @@ packages: peerDependencies: postcss-selector-parser: ^6.0.10 + '@esbuild/android-arm64@0.18.20': + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.18.20': + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.18.20': + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.18.20': + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.18.20': + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.18.20': + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.18.20': + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.18.20': + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.18.20': + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.18.20': + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.18.20': + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.18.20': + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.18.20': + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.18.20': + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.18.20': + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.18.20': + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.18.20': + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.18.20': + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.18.20': + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.18.20': + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.18.20': + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.18.20': + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.4.1': resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1224,6 +1587,15 @@ packages: resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@floating-ui/core@1.7.3': + resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + + '@floating-ui/dom@1.7.4': + resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@fullhuman/postcss-purgecss@4.1.3': resolution: {integrity: sha512-jqcsyfvq09VOsMXxJMPLRF6Fhg/NNltzWKnC9qtzva+QKTxerCO4esG6je7hbnmkpZtaDyPTwMBj9bzfWorsrw==} peerDependencies: @@ -1346,6 +1718,9 @@ packages: '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} @@ -1409,6 +1784,24 @@ packages: '@marijn/find-cluster-break@1.0.2': resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} + '@microsoft/api-extractor-model@7.28.13': + resolution: {integrity: sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==} + + '@microsoft/api-extractor@7.43.0': + resolution: {integrity: sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==} + hasBin: true + + '@microsoft/tsdoc-config@0.16.2': + resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==} + + '@microsoft/tsdoc@0.14.2': + resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} + + '@modyfi/vite-plugin-yaml@1.1.1': + resolution: {integrity: sha512-rEbfFNlMGLKpAYs2RsfLAhxCHFa6M4QKHHk0A4EYcCJAUwFtFO6qiEdLjUGUTtnRUxAC7GxxCa+ZbeUILSDvqQ==} + peerDependencies: + vite: '>=3.2.7' + '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} @@ -1467,6 +1860,9 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + '@remirror/core-constants@3.0.0': + resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} + '@restart/hooks@0.4.16': resolution: {integrity: sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==} peerDependencies: @@ -1483,6 +1879,9 @@ packages: react: '>=16.14.0' react-dom: '>=16.14.0' + '@rolldown/pluginutils@1.0.0-beta.27': + resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + '@rollup/plugin-babel@5.3.1': resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} engines: {node: '>= 10.0.0'} @@ -1511,12 +1910,52 @@ packages: peerDependencies: rollup: ^1.20.0||^2.0.0 + '@rollup/pluginutils@5.1.0': + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} '@rushstack/eslint-patch@1.10.4': resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==} + '@rushstack/node-core-library@4.0.2': + resolution: {integrity: sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + '@rushstack/rig-package@0.5.2': + resolution: {integrity: sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==} + + '@rushstack/terminal@0.10.0': + resolution: {integrity: sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + '@rushstack/ts-command-line@4.19.1': + resolution: {integrity: sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==} + '@sinclair/typebox@0.24.51': resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} @@ -1585,9 +2024,84 @@ packages: resolution: {integrity: sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==} engines: {node: '>=10'} + '@swc/core-darwin-arm64@1.15.3': + resolution: {integrity: sha512-AXfeQn0CvcQ4cndlIshETx6jrAM45oeUrK8YeEY6oUZU/qzz0Id0CyvlEywxkWVC81Ajpd8TQQ1fW5yx6zQWkQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.15.3': + resolution: {integrity: sha512-p68OeCz1ui+MZYG4wmfJGvcsAcFYb6Sl25H9TxWl+GkBgmNimIiRdnypK9nBGlqMZAcxngNPtnG3kEMNnvoJ2A==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.15.3': + resolution: {integrity: sha512-Nuj5iF4JteFgwrai97mUX+xUOl+rQRHqTvnvHMATL/l9xE6/TJfPBpd3hk/PVpClMXG3Uvk1MxUFOEzM1JrMYg==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.15.3': + resolution: {integrity: sha512-2Nc/s8jE6mW2EjXWxO/lyQuLKShcmTrym2LRf5Ayp3ICEMX6HwFqB1EzDhwoMa2DcUgmnZIalesq2lG3krrUNw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.15.3': + resolution: {integrity: sha512-j4SJniZ/qaZ5g8op+p1G9K1z22s/EYGg1UXIb3+Cg4nsxEpF5uSIGEE4mHUfA70L0BR9wKT2QF/zv3vkhfpX4g==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.15.3': + resolution: {integrity: sha512-aKttAZnz8YB1VJwPQZtyU8Uk0BfMP63iDMkvjhJzRZVgySmqt/apWSdnoIcZlUoGheBrcqbMC17GGUmur7OT5A==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.15.3': + resolution: {integrity: sha512-oe8FctPu1gnUsdtGJRO2rvOUIkkIIaHqsO9xxN0bTR7dFTlPTGi2Fhk1tnvXeyAvCPxLIcwD8phzKg6wLv9yug==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.15.3': + resolution: {integrity: sha512-L9AjzP2ZQ/Xh58e0lTRMLvEDrcJpR7GwZqAtIeNLcTK7JVE+QineSyHp0kLkO1rttCHyCy0U74kDTj0dRz6raA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.15.3': + resolution: {integrity: sha512-B8UtogMzErUPDWUoKONSVBdsgKYd58rRyv2sHJWKOIMCHfZ22FVXICR4O/VwIYtlnZ7ahERcjayBHDlBZpR0aw==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.15.3': + resolution: {integrity: sha512-SpZKMR9QBTecHeqpzJdYEfgw30Oo8b/Xl6rjSzBt1g0ZsXyy60KLXrp6IagQyfTYqNYE/caDvwtF2FPn7pomog==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.15.3': + resolution: {integrity: sha512-Qd8eBPkUFL4eAONgGjycZXj1jFCBW8Fd+xF0PzdTlBCWQIV1xnUT7B93wUANtW3KGjl3TRcOyxwSx/u/jyKw/Q==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '>=0.5.17' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + '@swc/types@0.1.25': + resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} + '@testing-library/dom@8.20.1': resolution: {integrity: sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==} engines: {node: '>=12'} @@ -1609,6 +2123,192 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' + '@tiptap/core@3.11.1': + resolution: {integrity: sha512-q7uzYrCq40JOIi6lceWe2HuA8tSr97iPwP/xtJd0bZjyL1rWhUyqxMb7y+aq4RcELrx/aNRa2JIvLtRRdy02Dg==} + peerDependencies: + '@tiptap/pm': ^3.11.1 + + '@tiptap/extension-blockquote@3.11.1': + resolution: {integrity: sha512-c3DN5c/9kl8w1wCcylH9XqW0OyCegqE3EL4rDlVYkyBD0GwCnUS30pN+jdxCUq/tl94lkkRk7XMyEUwzQmG+5g==} + peerDependencies: + '@tiptap/core': ^3.11.1 + + '@tiptap/extension-bold@3.11.1': + resolution: {integrity: sha512-ee/OoAPViUAgJb8dxF7D2YSSYUWcw8RXqhNSDx15w58rxpYbJbvOv3WDMrGNvl4M9nuwXYfXc3iPl/eYtwHx2w==} + peerDependencies: + '@tiptap/core': ^3.11.1 + + '@tiptap/extension-bubble-menu@3.11.1': + resolution: {integrity: sha512-rLgU2drvoSTpdXEmoo61ZSmtRR44vMeS36OoDpUA1dNzo/vWAiOzQeLnm8gC9cD2TmvJ+WIe7tOkpAEfw4kmiQ==} + peerDependencies: + '@tiptap/core': ^3.11.1 + '@tiptap/pm': ^3.11.1 + + '@tiptap/extension-bullet-list@3.11.1': + resolution: {integrity: sha512-6fj0b0Ynam8FMsP3NiCZ4a2uP7lCBHDFBXfcRwFDOqAgBIPvIK+r6CuHEGothGaF7EeQ9MTyj9fwlGjyHsPQcg==} + peerDependencies: + '@tiptap/extension-list': ^3.11.1 + + '@tiptap/extension-code-block@3.11.1': + resolution: {integrity: sha512-Bk7mmA+m510zzLG5AMFmywrL50NlBA5p7bR0cKfdp4ckXr8FohxH3QS0Woy1MRnFUGRtIzJkSYQTJ3O/G1lBqQ==} + peerDependencies: + '@tiptap/core': ^3.11.1 + '@tiptap/pm': ^3.11.1 + + '@tiptap/extension-code@3.11.1': + resolution: {integrity: sha512-R3HtNPAuaKqbDwK1uWO/6QFHXbbKcxbV27XVCVtTQ4gCAzIZbJElp9REEqAOp/zI6bqt774UrAekeV+5i8NQYw==} + peerDependencies: + '@tiptap/core': ^3.11.1 + + '@tiptap/extension-document@3.11.1': + resolution: {integrity: sha512-Px8T7Kv8EEiFpM/h13Rro8HoynrlK8zA3u3ekHq/FBSTXnPtqPAUYNx/DUhIrLs3eWWJ8+P0Onm+sVLZmaLMug==} + peerDependencies: + '@tiptap/core': ^3.11.1 + + '@tiptap/extension-dropcursor@3.11.1': + resolution: {integrity: sha512-+tmWD/4tg7Mt1TArrvc1Gna1FiSyru2rE6sapEerXCH3RFfaqGBeMqeRaOeZrCiqB+vIsXfthHDC/7xz5rFp/g==} + peerDependencies: + '@tiptap/extensions': ^3.11.1 + + '@tiptap/extension-floating-menu@3.11.1': + resolution: {integrity: sha512-HGF04KhDn1oAD+2/zStSWeGIgR41l/raf64h/Rwkvde5Sf2g3BPRW4M1ESS6e2Rjw74Kwa4/xNO6CzZNid6yRg==} + peerDependencies: + '@floating-ui/dom': ^1.0.0 + '@tiptap/core': ^3.11.1 + '@tiptap/pm': ^3.11.1 + + '@tiptap/extension-gapcursor@3.11.1': + resolution: {integrity: sha512-rZ4eIFOPrLPM0bAMW560v/i9WeAz6D6PPtmFJ/Rwh7F5QFbg+jSXAyGvg7V9ZwzA5OaXqsToyJBR7qtGXBXAhQ==} + peerDependencies: + '@tiptap/extensions': ^3.11.1 + + '@tiptap/extension-hard-break@3.11.1': + resolution: {integrity: sha512-JMp6CizdB7LoY2jmaZub2D+Aj6RJTkSu0EhIcN/bmBrm4MjYa/ir6nRoo4/gYGIHzHwgwGR/1KmlqTJZW/xl4g==} + peerDependencies: + '@tiptap/core': ^3.11.1 + + '@tiptap/extension-heading@3.11.1': + resolution: {integrity: sha512-b9ShCSQhWXNzdbdn9a3j33cq646nS0EpVyNBQr0BMOpIcMI4Ot8LGEvPo0BNqPPvpjMJaP2N6xp+EIdk6tunfQ==} + peerDependencies: + '@tiptap/core': ^3.11.1 + + '@tiptap/extension-horizontal-rule@3.11.1': + resolution: {integrity: sha512-9zr6dItcJvzZtFlC+dyFb5VfWGzKzldPAOuln1d/GwKrBZds53O2vBmu4Jxfy22N9LuwiGB+2PYerq0UkLnxnA==} + peerDependencies: + '@tiptap/core': ^3.11.1 + '@tiptap/pm': ^3.11.1 + + '@tiptap/extension-image@3.11.1': + resolution: {integrity: sha512-lI+FyyHavUXHmDKxvSAdqGAvaYtVesAxHckeA60ZjZu9fBkUnVWHD8uR0TStX7EdOIRBWpzYrG7dDT4EkFVjTA==} + peerDependencies: + '@tiptap/core': ^3.11.1 + + '@tiptap/extension-italic@3.11.1': + resolution: {integrity: sha512-SrjsU+gvhjoPKelc4YSeC2AQ0lhwLiDWMO7fW83CVitCF8iWXpBSeVCI5SxtPeZNKTZ1ZCc3lIQCeEHOC/gP0g==} + peerDependencies: + '@tiptap/core': ^3.11.1 + + '@tiptap/extension-link@3.11.1': + resolution: {integrity: sha512-ds5auQnWGcHwC2/c1iEvvybdLPcSDlxsii7FPaZg4LaSGdNojRB0qDRZw5dzYQZbfIf5vgYGcIVCVjNPZs1UwQ==} + peerDependencies: + '@tiptap/core': ^3.11.1 + '@tiptap/pm': ^3.11.1 + + '@tiptap/extension-list-item@3.11.1': + resolution: {integrity: sha512-KFw3TAwN6hQ+oDeE3lRqwzCRKhxU1NWf9q5SAwiUxlp/LcEjuhXcYJYX8SHPOLOlTo0P42v1i0KBeLUPKnO58g==} + peerDependencies: + '@tiptap/extension-list': ^3.11.1 + + '@tiptap/extension-list-keymap@3.11.1': + resolution: {integrity: sha512-MpeuVi+bOHulbN65bOjaeoNJstNuAAEPdLwNjW25c9y2a8b5iZFY8vdVNENDiqq+dI+F5EaFGaEq0FN0uslfiA==} + peerDependencies: + '@tiptap/extension-list': ^3.11.1 + + '@tiptap/extension-list@3.11.1': + resolution: {integrity: sha512-XJRN9pOPMi3SsaKv4qM8WBEi3YDrjXYtYlAlZutQe1JpdKykSjLwwYq7k3V8UHqR3YKxyOV8HTYOYoOaZ9TMTQ==} + peerDependencies: + '@tiptap/core': ^3.11.1 + '@tiptap/pm': ^3.11.1 + + '@tiptap/extension-ordered-list@3.11.1': + resolution: {integrity: sha512-Aphq0kfk6J/hNQennJ+bntvDzqRPT7RVpnow1s4U4dLBsR6PP7X4zEBg96uAv2OW0RjDHFK9NFqpJPbZtQTmFw==} + peerDependencies: + '@tiptap/extension-list': ^3.11.1 + + '@tiptap/extension-paragraph@3.11.1': + resolution: {integrity: sha512-a3lm1WvYewAP2IESq+qnbOtLSJ9yULY2Bj/6DvBq9fzWpb2gSlUdElYh6JLunxB1HEPECTuuRsNPdTrMsSpV4g==} + peerDependencies: + '@tiptap/core': ^3.11.1 + + '@tiptap/extension-placeholder@3.11.1': + resolution: {integrity: sha512-RCPLeZ12+20YeqjwENK8rviaCnN0mL+Rm7dS+NT8Dz1WHjv9ZWwWS7WzAHfY2w3CNlMfOKwctnaobKmJ/2++CQ==} + peerDependencies: + '@tiptap/extensions': ^3.11.1 + + '@tiptap/extension-strike@3.11.1': + resolution: {integrity: sha512-1LfkHNkrGR509cPRgcMr95+nWcAHE0JDm9LkuzdexunhCfJ2tl/h1rA14x3sic8GxQFqEnMefvBUpUbQwPydYw==} + peerDependencies: + '@tiptap/core': ^3.11.1 + + '@tiptap/extension-table-cell@3.11.1': + resolution: {integrity: sha512-loFq2aZ+nDyrgxPjOCY/73YelRHqQWMw4oIiB4D0sYiDka+bBN/cV7LGWqfP5CldF8oSBJ8u+5ViDWCilTfDeg==} + peerDependencies: + '@tiptap/extension-table': ^3.11.1 + + '@tiptap/extension-table-header@3.11.1': + resolution: {integrity: sha512-oCn71L7FYxnpzHO7hn8xbaF6jxRhPinNsqgde+5OY23BEvVBpX8QFbOJkphQDyMwvSHAw/3S+ZF+vxHZU51aRg==} + peerDependencies: + '@tiptap/extension-table': ^3.11.1 + + '@tiptap/extension-table-row@3.11.1': + resolution: {integrity: sha512-KfB9axBtfE59/xC++4SS2iYkfEv93k5EWDbjIjC6T62FpfTYlBDOQutj79Nnmn8XkS5srT4nmxrohqRc1wUSQg==} + peerDependencies: + '@tiptap/extension-table': ^3.11.1 + + '@tiptap/extension-table@3.11.1': + resolution: {integrity: sha512-ae81cJgJ3cAA1Ry0JtLKtoPpA23YvMy0WnAw1gqnOX9yTYRYgT5W6MzP0O2rIBOI6b5Xkt6xtZzChjwMzioGbQ==} + peerDependencies: + '@tiptap/core': ^3.11.1 + '@tiptap/pm': ^3.11.1 + + '@tiptap/extension-text@3.11.1': + resolution: {integrity: sha512-5E94ggkFAZ7OSFSwnofAsmxqmSStRoeCB8AnRuWrR+nnXi43Rq7yptdejQaLi13Z9fSVdnF6h+pB3ua2Exg6WQ==} + peerDependencies: + '@tiptap/core': ^3.11.1 + + '@tiptap/extension-underline@3.11.1': + resolution: {integrity: sha512-Y3EJxfE1g4XSGbUZN+74o38mp3O+BQXtlqxAQvedzXiGGrdK2kWhp2b4nj3IkxHdRdoSijf+oZzgyBrRDdgC/w==} + peerDependencies: + '@tiptap/core': ^3.11.1 + + '@tiptap/extensions@3.11.1': + resolution: {integrity: sha512-/xXJdV+EVvSQv2slvAUChb5iGVv5K0EqBqxPGAAuBHdIc4Y7Id1aaKKSiyDmqon+kjSnnQIIda9oUt+o/Z66uA==} + peerDependencies: + '@tiptap/core': ^3.11.1 + '@tiptap/pm': ^3.11.1 + + '@tiptap/markdown@3.11.1': + resolution: {integrity: sha512-cC3mKV+bBoHJ0Bsd4zstVYFBm8KGsbeAhIayVzY59G4QpvIQC78BgajqXukfUKDLcehiycRYYW/HcOAwvAysWg==} + peerDependencies: + '@tiptap/core': ^3.11.1 + '@tiptap/pm': ^3.11.1 + + '@tiptap/pm@3.11.1': + resolution: {integrity: sha512-8RIUhlEoCFGsbdNb+EUdQctG1Wnd7rl4wlMLS6giO7UcZT5dVfg625eMZVrl0/kA7JBJdKLIuqNmzzQ0MxsJEw==} + + '@tiptap/react@3.11.1': + resolution: {integrity: sha512-aPInZbpSWYzJvCFXaY6EhxD+H5ITURElUmUXBoRvlAB6QrR6NIWBt68hNe8i+aDGmuvLS18g60HWK5S6K2RjWQ==} + peerDependencies: + '@tiptap/core': ^3.11.1 + '@tiptap/pm': ^3.11.1 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + '@types/react-dom': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tiptap/starter-kit@3.11.1': + resolution: {integrity: sha512-weRrhp0p5J6cMNcybYobhbOVrgym7KYIwBblJ/1M1snykg+avZawVk2M5Y7j9gM1p2zo112MCw8z8nOa9Yrwow==} + '@tootallnate/once@1.1.2': resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} engines: {node: '>= 6'} @@ -1629,6 +2329,9 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@types/argparse@1.0.38': + resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} + '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -1728,12 +2431,21 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + '@types/lodash@4.17.13': resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==} + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + '@types/marked@4.3.2': resolution: {integrity: sha512-a79Yc3TOk6dGdituy8hmTTJXjOkZ7zsFYV10L337ttq/rec8lRMDBpV7fL3uLx6TgbFCa5DU/h8FmIBQPSbU0w==} + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} @@ -1808,6 +2520,9 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/use-sync-external-store@0.0.6': + resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} + '@types/warning@3.0.3': resolution: {integrity: sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==} @@ -1951,6 +2666,37 @@ packages: '@ungap/structured-clone@1.2.1': resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} + '@vitejs/plugin-react-swc@3.11.0': + resolution: {integrity: sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w==} + peerDependencies: + vite: ^4 || ^5 || ^6 || ^7 + + '@volar/language-core@1.11.1': + resolution: {integrity: sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==} + + '@volar/source-map@1.11.1': + resolution: {integrity: sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==} + + '@volar/typescript@1.11.1': + resolution: {integrity: sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==} + + '@vue/compiler-core@3.5.25': + resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==} + + '@vue/compiler-dom@3.5.25': + resolution: {integrity: sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==} + + '@vue/language-core@1.8.27': + resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/shared@3.5.25': + resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==} + '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -2554,6 +3300,10 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + common-tags@1.8.2: resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} engines: {node: '>=4.0.0'} @@ -2572,6 +3322,9 @@ packages: resolution: {integrity: sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==} engines: {node: '>= 0.8.0'} + computeds@0.0.1: + resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -2836,6 +3589,9 @@ packages: dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -3086,6 +3842,10 @@ packages: entities@2.2.0: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + environment@1.1.0: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} @@ -3136,6 +3896,11 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -3331,6 +4096,11 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + eslint-plugin-react-refresh@0.4.24: + resolution: {integrity: sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w==} + peerDependencies: + eslint: '>=8.40' + eslint-plugin-react@7.37.2: resolution: {integrity: sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==} engines: {node: '>=4'} @@ -3405,6 +4175,9 @@ packages: estree-walker@1.0.1: resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -3580,6 +4353,10 @@ packages: resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} engines: {node: '>=14.14'} + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} @@ -3889,6 +4666,10 @@ packages: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} + import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + import-local@3.2.0: resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} engines: {node: '>=8'} @@ -4349,6 +5130,9 @@ packages: resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} hasBin: true + jju@1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + js-sha256@0.11.0: resolution: {integrity: sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==} @@ -4404,6 +5188,9 @@ packages: engines: {node: '>=6'} hasBin: true + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} @@ -4440,6 +5227,9 @@ packages: resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} engines: {node: '>= 8'} + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -4473,6 +5263,12 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + linkifyjs@4.3.2: + resolution: {integrity: sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==} + lint-staged@15.5.0: resolution: {integrity: sha512-WyCzSbfYGhK7cU+UuDDkzUiytbfbi0ZdPy2orwtM75P3WTtQBzmG40cCxIa8Ii2+XjfxzLH6Be46tUfWS85Xfg==} engines: {node: '>=18.12.0'} @@ -4515,6 +5311,14 @@ packages: lodash.flow@3.5.0: resolution: {integrity: sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==} + lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + lodash.isfunction@3.0.9: resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} @@ -4579,6 +5383,9 @@ packages: magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -4601,6 +5408,15 @@ packages: resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} engines: {node: '>=8'} + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + + marked@15.0.12: + resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==} + engines: {node: '>= 18'} + hasBin: true + marked@4.3.0: resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} engines: {node: '>= 12'} @@ -4612,6 +5428,9 @@ packages: mdn-data@2.0.4: resolution: {integrity: sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==} + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -4684,6 +5503,9 @@ packages: minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + minimatch@3.0.8: + resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -4720,6 +5542,9 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + muggle-string@0.3.1: + resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} + multicast-dns@7.2.5: resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} hasBin: true @@ -4890,6 +5715,9 @@ packages: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} + orderedmap@2.1.1: + resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} + p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -4942,6 +5770,9 @@ packages: pascal-case@3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-exists@3.0.0: resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} engines: {node: '>=4'} @@ -4989,6 +5820,10 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} engines: {node: '>=0.10'} @@ -5502,6 +6337,64 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + prosemirror-changeset@2.3.1: + resolution: {integrity: sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==} + + prosemirror-collab@1.3.1: + resolution: {integrity: sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==} + + prosemirror-commands@1.7.1: + resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==} + + prosemirror-dropcursor@1.8.2: + resolution: {integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==} + + prosemirror-gapcursor@1.4.0: + resolution: {integrity: sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==} + + prosemirror-history@1.5.0: + resolution: {integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==} + + prosemirror-inputrules@1.5.1: + resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==} + + prosemirror-keymap@1.2.3: + resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} + + prosemirror-markdown@1.13.2: + resolution: {integrity: sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==} + + prosemirror-menu@1.2.5: + resolution: {integrity: sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==} + + prosemirror-model@1.25.4: + resolution: {integrity: sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==} + + prosemirror-schema-basic@1.2.4: + resolution: {integrity: sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==} + + prosemirror-schema-list@1.5.1: + resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} + + prosemirror-state@1.4.4: + resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==} + + prosemirror-tables@1.8.1: + resolution: {integrity: sha512-DAgDoUYHCcc6tOGpLVPSU1k84kCUWTWnfWX3UDy2Delv4ryH0KqTD6RBI6k4yi9j9I8gl3j8MkPpRD/vWPZbug==} + + prosemirror-trailing-node@3.0.0: + resolution: {integrity: sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==} + peerDependencies: + prosemirror-model: ^1.22.1 + prosemirror-state: ^1.4.2 + prosemirror-view: ^1.33.8 + + prosemirror-transform@1.10.5: + resolution: {integrity: sha512-RPDQCxIDhIBb1o36xxwsaeAvivO8VLJcgBtzmOwQ64bMtsVFh5SSuJ6dWSxO1UsHTiTXPCgQm3PDJt7p6IOLbw==} + + prosemirror-view@1.41.3: + resolution: {integrity: sha512-SqMiYMUQNNBP9kfPhLO8WXEk/fon47vc52FQsUiJzTBuyjKgEcoAwMyF04eQ4WZ2ArMn7+ReypYL60aKngbACQ==} + proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -5512,6 +6405,10 @@ packages: psl@1.15.0: resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -5813,6 +6710,9 @@ packages: resolution: {integrity: sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==} engines: {node: '>=10'} + resolve@1.19.0: + resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} + resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -5857,6 +6757,14 @@ packages: engines: {node: '>=10.0.0'} hasBin: true + rollup@3.29.5: + resolution: {integrity: sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + + rope-sequence@1.3.4: + resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -6084,6 +6992,7 @@ packages: source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} + deprecated: The work that was done in this beta branch won't be included in future versions sourcemap-codec@1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} @@ -6395,6 +7304,10 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + tosource@2.0.0-alpha.3: + resolution: {integrity: sha512-KAB2lrSS48y91MzFPFuDg4hLbvDiyTjOVgaK7Erw+5AmZXNq4sFRVn8r6yxSLuNs15PaokrDRpS61ERY9uZOug==} + engines: {node: '>=10'} + tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -6522,6 +7435,19 @@ packages: engines: {node: '>=4.2.0'} hasBin: true + typescript@5.4.2: + resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} @@ -6558,6 +7484,10 @@ packages: resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} engines: {node: '>=8'} + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + universalify@0.2.0: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} @@ -6593,10 +7523,10 @@ packages: url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - use-sync-external-store@1.2.2: - resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -6625,14 +7555,65 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + validator@13.15.23: + resolution: {integrity: sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==} + engines: {node: '>= 0.10'} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vite-plugin-dts@3.9.1: + resolution: {integrity: sha512-rVp2KM9Ue22NGWB8dNtWEr+KekN3rIgz1tWD050QnRGlriUCmaDwa7qA5zDEjbXg5lAXhYMSBJtx3q3hQIJZSg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + typescript: '*' + vite: '*' + peerDependenciesMeta: + vite: + optional: true + + vite@4.5.14: + resolution: {integrity: sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + void-elements@3.1.0: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} + vue-template-compiler@2.7.16: + resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} + + vue-tsc@1.8.27: + resolution: {integrity: sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==} + hasBin: true + peerDependencies: + typescript: '*' + w3c-hr-time@1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} deprecated: Use your platform's native performance.now() and performance.timeOrigin. @@ -6942,6 +7923,11 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + z-schema@5.0.5: + resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} + engines: {node: '>=8.0.0'} + hasBin: true + zustand@5.0.2: resolution: {integrity: sha512-8qNdnJVJlHlrKXi50LDqqUNmUbuBjoKLrYQBnoChIbVph7vni+sY+YpvdjXG9YLd/Bxr6scMcR+rm5H3aSqPaw==} engines: {node: '>=12.20.0'} @@ -7119,8 +8105,12 @@ snapshots: '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-option@7.25.9': {} '@babel/helper-wrap-function@7.25.9': @@ -7140,6 +8130,10 @@ snapshots: dependencies: '@babel/types': 7.26.3 + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -7855,6 +8849,11 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@bcoe/v8-coverage@0.2.3': {} '@codemirror/autocomplete@6.18.3(@codemirror/language@6.10.6)(@codemirror/state@6.5.0)(@codemirror/view@6.35.3)(@lezer/common@1.2.3)': @@ -8111,11 +9110,11 @@ snapshots: style-mod: 4.1.2 w3c-keyname: 2.2.8 - '@commitlint/cli@17.8.1': + '@commitlint/cli@17.8.1(@swc/core@1.15.3)': dependencies: '@commitlint/format': 17.8.1 '@commitlint/lint': 17.8.1 - '@commitlint/load': 17.8.1 + '@commitlint/load': 17.8.1(@swc/core@1.15.3) '@commitlint/read': 17.8.1 '@commitlint/types': 17.8.1 execa: 5.1.1 @@ -8164,7 +9163,7 @@ snapshots: '@commitlint/rules': 17.8.1 '@commitlint/types': 17.8.1 - '@commitlint/load@17.8.1': + '@commitlint/load@17.8.1(@swc/core@1.15.3)': dependencies: '@commitlint/config-validator': 17.8.1 '@commitlint/execute-rule': 17.8.1 @@ -8173,12 +9172,12 @@ snapshots: '@types/node': 20.5.1 chalk: 4.1.2 cosmiconfig: 8.3.6(typescript@4.9.5) - cosmiconfig-typescript-loader: 4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6(typescript@4.9.5))(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5))(typescript@4.9.5) + cosmiconfig-typescript-loader: 4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6(typescript@4.9.5))(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5))(typescript@4.9.5) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 resolve-from: 5.0.0 - ts-node: 10.9.2(@types/node@20.5.1)(typescript@4.9.5) + ts-node: 10.9.2(@swc/core@1.15.3)(@types/node@16.18.121)(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - '@swc/core' @@ -8311,6 +9310,72 @@ snapshots: dependencies: postcss-selector-parser: 6.1.2 + '@esbuild/android-arm64@0.18.20': + optional: true + + '@esbuild/android-arm@0.18.20': + optional: true + + '@esbuild/android-x64@0.18.20': + optional: true + + '@esbuild/darwin-arm64@0.18.20': + optional: true + + '@esbuild/darwin-x64@0.18.20': + optional: true + + '@esbuild/freebsd-arm64@0.18.20': + optional: true + + '@esbuild/freebsd-x64@0.18.20': + optional: true + + '@esbuild/linux-arm64@0.18.20': + optional: true + + '@esbuild/linux-arm@0.18.20': + optional: true + + '@esbuild/linux-ia32@0.18.20': + optional: true + + '@esbuild/linux-loong64@0.18.20': + optional: true + + '@esbuild/linux-mips64el@0.18.20': + optional: true + + '@esbuild/linux-ppc64@0.18.20': + optional: true + + '@esbuild/linux-riscv64@0.18.20': + optional: true + + '@esbuild/linux-s390x@0.18.20': + optional: true + + '@esbuild/linux-x64@0.18.20': + optional: true + + '@esbuild/netbsd-x64@0.18.20': + optional: true + + '@esbuild/openbsd-x64@0.18.20': + optional: true + + '@esbuild/sunos-x64@0.18.20': + optional: true + + '@esbuild/win32-arm64@0.18.20': + optional: true + + '@esbuild/win32-ia32@0.18.20': + optional: true + + '@esbuild/win32-x64@0.18.20': + optional: true + '@eslint-community/eslint-utils@4.4.1(eslint@8.57.1)': dependencies: eslint: 8.57.1 @@ -8334,6 +9399,20 @@ snapshots: '@eslint/js@8.57.1': {} + '@floating-ui/core@1.7.3': + dependencies: + '@floating-ui/utils': 0.2.10 + optional: true + + '@floating-ui/dom@1.7.4': + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/utils': 0.2.10 + optional: true + + '@floating-ui/utils@0.2.10': + optional: true + '@fullhuman/postcss-purgecss@4.1.3(postcss@8.4.49)': dependencies: postcss: 8.4.49 @@ -8388,7 +9467,7 @@ snapshots: jest-util: 28.1.3 slash: 3.0.0 - '@jest/core@27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5))': + '@jest/core@27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5))': dependencies: '@jest/console': 27.5.1 '@jest/reporters': 27.5.1 @@ -8402,7 +9481,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 27.5.1 - jest-config: 27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)) + jest-config: 27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)) jest-haste-map: 27.5.1 jest-message-util: 27.5.1 jest-regex-util: 27.5.1 @@ -8570,6 +9649,8 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -8677,6 +9758,50 @@ snapshots: '@marijn/find-cluster-break@1.0.2': {} + '@microsoft/api-extractor-model@7.28.13(@types/node@20.5.1)': + dependencies: + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + '@rushstack/node-core-library': 4.0.2(@types/node@20.5.1) + transitivePeerDependencies: + - '@types/node' + + '@microsoft/api-extractor@7.43.0(@types/node@20.5.1)': + dependencies: + '@microsoft/api-extractor-model': 7.28.13(@types/node@20.5.1) + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + '@rushstack/node-core-library': 4.0.2(@types/node@20.5.1) + '@rushstack/rig-package': 0.5.2 + '@rushstack/terminal': 0.10.0(@types/node@20.5.1) + '@rushstack/ts-command-line': 4.19.1(@types/node@20.5.1) + lodash: 4.17.21 + minimatch: 3.0.8 + resolve: 1.22.8 + semver: 7.5.4 + source-map: 0.6.1 + typescript: 5.4.2 + transitivePeerDependencies: + - '@types/node' + + '@microsoft/tsdoc-config@0.16.2': + dependencies: + '@microsoft/tsdoc': 0.14.2 + ajv: 6.12.6 + jju: 1.4.0 + resolve: 1.19.0 + + '@microsoft/tsdoc@0.14.2': {} + + '@modyfi/vite-plugin-yaml@1.1.1(rollup@3.29.5)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0))': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@3.29.5) + js-yaml: 4.1.0 + tosource: 2.0.0-alpha.3 + vite: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) + transitivePeerDependencies: + - rollup + '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': dependencies: eslint-scope: 5.1.1 @@ -8698,7 +9823,7 @@ snapshots: '@pkgr/core@0.1.1': {} - '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.11.0)(type-fest@1.4.0)(webpack-dev-server@4.15.2(webpack@5.97.1))(webpack@5.97.1)': + '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.11.0)(type-fest@1.4.0)(webpack-dev-server@4.15.2(webpack@5.97.1(@swc/core@1.15.3)))(webpack@5.97.1(@swc/core@1.15.3))': dependencies: ansi-html: 0.0.9 core-js-pure: 3.39.0 @@ -8708,10 +9833,10 @@ snapshots: react-refresh: 0.11.0 schema-utils: 4.2.0 source-map: 0.7.4 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) optionalDependencies: type-fest: 1.4.0 - webpack-dev-server: 4.15.2(webpack@5.97.1) + webpack-dev-server: 4.15.2(webpack@5.97.1(@swc/core@1.15.3)) '@popperjs/core@2.11.8': {} @@ -8720,6 +9845,8 @@ snapshots: '@swc/helpers': 0.5.15 react: 18.3.1 + '@remirror/core-constants@3.0.0': {} + '@restart/hooks@0.4.16(react@18.3.1)': dependencies: dequal: 2.0.3 @@ -8744,6 +9871,8 @@ snapshots: uncontrollable: 8.0.4(react@18.3.1) warning: 4.0.3 + '@rolldown/pluginutils@1.0.0-beta.27': {} + '@rollup/plugin-babel@5.3.1(@babel/core@7.26.0)(@types/babel__core@7.20.5)(rollup@2.79.2)': dependencies: '@babel/core': 7.26.0 @@ -8778,10 +9907,58 @@ snapshots: picomatch: 2.3.1 rollup: 2.79.2 + '@rollup/pluginutils@5.1.0(rollup@3.29.5)': + dependencies: + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: 3.29.5 + + '@rollup/pluginutils@5.3.0(rollup@3.29.5)': + dependencies: + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 3.29.5 + '@rtsao/scc@1.1.0': {} '@rushstack/eslint-patch@1.10.4': {} + '@rushstack/node-core-library@4.0.2(@types/node@20.5.1)': + dependencies: + fs-extra: 7.0.1 + import-lazy: 4.0.0 + jju: 1.4.0 + resolve: 1.22.8 + semver: 7.5.4 + z-schema: 5.0.5 + optionalDependencies: + '@types/node': 20.5.1 + + '@rushstack/rig-package@0.5.2': + dependencies: + resolve: 1.22.8 + strip-json-comments: 3.1.1 + + '@rushstack/terminal@0.10.0(@types/node@20.5.1)': + dependencies: + '@rushstack/node-core-library': 4.0.2(@types/node@20.5.1) + supports-color: 8.1.1 + optionalDependencies: + '@types/node': 20.5.1 + + '@rushstack/ts-command-line@4.19.1(@types/node@20.5.1)': + dependencies: + '@rushstack/terminal': 0.10.0(@types/node@20.5.1) + '@types/argparse': 1.0.38 + argparse: 1.0.10 + string-argv: 0.3.2 + transitivePeerDependencies: + - '@types/node' + '@sinclair/typebox@0.24.51': {} '@sinonjs/commons@1.8.6': @@ -8847,66 +10024,326 @@ snapshots: transitivePeerDependencies: - supports-color - '@svgr/plugin-svgo@5.5.0': + '@svgr/plugin-svgo@5.5.0': + dependencies: + cosmiconfig: 7.1.0 + deepmerge: 4.3.1 + svgo: 1.3.2 + + '@svgr/webpack@5.5.0': + dependencies: + '@babel/core': 7.26.0 + '@babel/plugin-transform-react-constant-elements': 7.25.9(@babel/core@7.26.0) + '@babel/preset-env': 7.26.0(@babel/core@7.26.0) + '@babel/preset-react': 7.26.3(@babel/core@7.26.0) + '@svgr/core': 5.5.0 + '@svgr/plugin-jsx': 5.5.0 + '@svgr/plugin-svgo': 5.5.0 + loader-utils: 2.0.4 + transitivePeerDependencies: + - supports-color + + '@swc/core-darwin-arm64@1.15.3': + optional: true + + '@swc/core-darwin-x64@1.15.3': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.15.3': + optional: true + + '@swc/core-linux-arm64-gnu@1.15.3': + optional: true + + '@swc/core-linux-arm64-musl@1.15.3': + optional: true + + '@swc/core-linux-x64-gnu@1.15.3': + optional: true + + '@swc/core-linux-x64-musl@1.15.3': + optional: true + + '@swc/core-win32-arm64-msvc@1.15.3': + optional: true + + '@swc/core-win32-ia32-msvc@1.15.3': + optional: true + + '@swc/core-win32-x64-msvc@1.15.3': + optional: true + + '@swc/core@1.15.3': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.25 + optionalDependencies: + '@swc/core-darwin-arm64': 1.15.3 + '@swc/core-darwin-x64': 1.15.3 + '@swc/core-linux-arm-gnueabihf': 1.15.3 + '@swc/core-linux-arm64-gnu': 1.15.3 + '@swc/core-linux-arm64-musl': 1.15.3 + '@swc/core-linux-x64-gnu': 1.15.3 + '@swc/core-linux-x64-musl': 1.15.3 + '@swc/core-win32-arm64-msvc': 1.15.3 + '@swc/core-win32-ia32-msvc': 1.15.3 + '@swc/core-win32-x64-msvc': 1.15.3 + + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@swc/types@0.1.25': + dependencies: + '@swc/counter': 0.1.3 + + '@testing-library/dom@8.20.1': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/runtime': 7.26.0 + '@types/aria-query': 5.0.4 + aria-query: 5.1.3 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + + '@testing-library/jest-dom@4.2.4': + dependencies: + '@babel/runtime': 7.26.0 + chalk: 2.4.2 + css: 2.2.4 + css.escape: 1.5.1 + jest-diff: 24.9.0 + jest-matcher-utils: 24.9.0 + lodash: 4.17.21 + pretty-format: 24.9.0 + redent: 3.0.0 + + '@testing-library/react@13.4.0(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.0 + '@testing-library/dom': 8.20.1 + '@types/react-dom': 18.3.5(@types/react@18.3.16) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + + '@testing-library/user-event@13.5.0(@testing-library/dom@8.20.1)': + dependencies: + '@babel/runtime': 7.26.0 + '@testing-library/dom': 8.20.1 + + '@tiptap/core@3.11.1(@tiptap/pm@3.11.1)': + dependencies: + '@tiptap/pm': 3.11.1 + + '@tiptap/extension-blockquote@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + + '@tiptap/extension-bold@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + + '@tiptap/extension-bubble-menu@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + dependencies: + '@floating-ui/dom': 1.7.4 + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/pm': 3.11.1 + optional: true + + '@tiptap/extension-bullet-list@3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/extension-list': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + + '@tiptap/extension-code-block@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/pm': 3.11.1 + + '@tiptap/extension-code@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + + '@tiptap/extension-document@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + + '@tiptap/extension-dropcursor@3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/extensions': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + + '@tiptap/extension-floating-menu@3.11.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + dependencies: + '@floating-ui/dom': 1.7.4 + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/pm': 3.11.1 + optional: true + + '@tiptap/extension-gapcursor@3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/extensions': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + + '@tiptap/extension-hard-break@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + + '@tiptap/extension-heading@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + + '@tiptap/extension-horizontal-rule@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/pm': 3.11.1 + + '@tiptap/extension-image@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + + '@tiptap/extension-italic@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + + '@tiptap/extension-link@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/pm': 3.11.1 + linkifyjs: 4.3.2 + + '@tiptap/extension-list-item@3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/extension-list': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + + '@tiptap/extension-list-keymap@3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/extension-list': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + + '@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/pm': 3.11.1 + + '@tiptap/extension-ordered-list@3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/extension-list': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + + '@tiptap/extension-paragraph@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + + '@tiptap/extension-placeholder@3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/extensions': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + + '@tiptap/extension-strike@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + + '@tiptap/extension-table-cell@3.11.1(@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/extension-table': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + + '@tiptap/extension-table-header@3.11.1(@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + dependencies: + '@tiptap/extension-table': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + + '@tiptap/extension-table-row@3.11.1(@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': dependencies: - cosmiconfig: 7.1.0 - deepmerge: 4.3.1 - svgo: 1.3.2 + '@tiptap/extension-table': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@svgr/webpack@5.5.0': + '@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': dependencies: - '@babel/core': 7.26.0 - '@babel/plugin-transform-react-constant-elements': 7.25.9(@babel/core@7.26.0) - '@babel/preset-env': 7.26.0(@babel/core@7.26.0) - '@babel/preset-react': 7.26.3(@babel/core@7.26.0) - '@svgr/core': 5.5.0 - '@svgr/plugin-jsx': 5.5.0 - '@svgr/plugin-svgo': 5.5.0 - loader-utils: 2.0.4 - transitivePeerDependencies: - - supports-color + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/pm': 3.11.1 - '@swc/helpers@0.5.15': + '@tiptap/extension-text@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': dependencies: - tslib: 2.8.1 + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) - '@testing-library/dom@8.20.1': + '@tiptap/extension-underline@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/runtime': 7.26.0 - '@types/aria-query': 5.0.4 - aria-query: 5.1.3 - chalk: 4.1.2 - dom-accessibility-api: 0.5.16 - lz-string: 1.5.0 - pretty-format: 27.5.1 + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) - '@testing-library/jest-dom@4.2.4': + '@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': dependencies: - '@babel/runtime': 7.26.0 - chalk: 2.4.2 - css: 2.2.4 - css.escape: 1.5.1 - jest-diff: 24.9.0 - jest-matcher-utils: 24.9.0 - lodash: 4.17.21 - pretty-format: 24.9.0 - redent: 3.0.0 + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/pm': 3.11.1 - '@testing-library/react@13.4.0(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@tiptap/markdown@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': dependencies: - '@babel/runtime': 7.26.0 - '@testing-library/dom': 8.20.1 + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/pm': 3.11.1 + marked: 15.0.12 + + '@tiptap/pm@3.11.1': + dependencies: + prosemirror-changeset: 2.3.1 + prosemirror-collab: 1.3.1 + prosemirror-commands: 1.7.1 + prosemirror-dropcursor: 1.8.2 + prosemirror-gapcursor: 1.4.0 + prosemirror-history: 1.5.0 + prosemirror-inputrules: 1.5.1 + prosemirror-keymap: 1.2.3 + prosemirror-markdown: 1.13.2 + prosemirror-menu: 1.2.5 + prosemirror-model: 1.25.4 + prosemirror-schema-basic: 1.2.4 + prosemirror-schema-list: 1.5.1 + prosemirror-state: 1.4.4 + prosemirror-tables: 1.8.1 + prosemirror-trailing-node: 3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.3) + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.3 + + '@tiptap/react@3.11.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/pm': 3.11.1 + '@types/react': 18.3.16 '@types/react-dom': 18.3.5(@types/react@18.3.16) + '@types/use-sync-external-store': 0.0.6 + fast-deep-equal: 3.1.3 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + use-sync-external-store: 1.6.0(react@18.3.1) + optionalDependencies: + '@tiptap/extension-bubble-menu': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-floating-menu': 3.11.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) transitivePeerDependencies: - - '@types/react' - - '@testing-library/user-event@13.5.0(@testing-library/dom@8.20.1)': - dependencies: - '@babel/runtime': 7.26.0 - '@testing-library/dom': 8.20.1 + - '@floating-ui/dom' + + '@tiptap/starter-kit@3.11.1': + dependencies: + '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/extension-blockquote': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) + '@tiptap/extension-bold': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) + '@tiptap/extension-bullet-list': 3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-code': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) + '@tiptap/extension-code-block': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-document': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) + '@tiptap/extension-dropcursor': 3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-gapcursor': 3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-hard-break': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) + '@tiptap/extension-heading': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) + '@tiptap/extension-horizontal-rule': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-italic': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) + '@tiptap/extension-link': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-list': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-list-item': 3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-list-keymap': 3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-ordered-list': 3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-paragraph': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) + '@tiptap/extension-strike': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) + '@tiptap/extension-text': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) + '@tiptap/extension-underline': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) + '@tiptap/extensions': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/pm': 3.11.1 '@tootallnate/once@1.1.2': {} @@ -8920,6 +10357,8 @@ snapshots: '@tsconfig/node16@1.0.4': {} + '@types/argparse@1.0.38': {} + '@types/aria-query@5.0.4': {} '@types/babel__core@7.20.5': @@ -9053,10 +10492,19 @@ snapshots: '@types/json5@0.0.29': {} + '@types/linkify-it@5.0.0': {} + '@types/lodash@4.17.13': {} + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + '@types/marked@4.3.2': {} + '@types/mdurl@2.0.0': {} + '@types/mime@1.3.5': {} '@types/minimist@1.2.5': {} @@ -9127,6 +10575,8 @@ snapshots: '@types/trusted-types@2.0.7': {} + '@types/use-sync-external-store@0.0.6': {} + '@types/warning@3.0.3': {} '@types/ws@8.5.13': @@ -9186,6 +10636,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.4.0 + eslint: 8.57.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + semver: 7.6.3 + ts-api-utils: 1.4.3(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.1)(typescript@4.9.5)': dependencies: '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) @@ -9219,6 +10689,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.4.0 + eslint: 8.57.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/scope-manager@5.62.0': dependencies: '@typescript-eslint/types': 5.62.0 @@ -9253,6 +10736,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.9.3) + debug: 4.4.0 + eslint: 8.57.1 + ts-api-utils: 1.4.3(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/types@5.62.0': {} '@typescript-eslint/types@6.21.0': {} @@ -9286,6 +10781,21 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@6.21.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.4.0 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.6.3 + ts-api-utils: 1.4.3(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@4.9.5)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) @@ -9315,6 +10825,20 @@ snapshots: - supports-color - typescript + '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) + eslint: 8.57.1 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/visitor-keys@5.62.0': dependencies: '@typescript-eslint/types': 5.62.0 @@ -9327,6 +10851,56 @@ snapshots: '@ungap/structured-clone@1.2.1': {} + '@vitejs/plugin-react-swc@3.11.0(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0))': + dependencies: + '@rolldown/pluginutils': 1.0.0-beta.27 + '@swc/core': 1.15.3 + vite: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) + transitivePeerDependencies: + - '@swc/helpers' + + '@volar/language-core@1.11.1': + dependencies: + '@volar/source-map': 1.11.1 + + '@volar/source-map@1.11.1': + dependencies: + muggle-string: 0.3.1 + + '@volar/typescript@1.11.1': + dependencies: + '@volar/language-core': 1.11.1 + path-browserify: 1.0.1 + + '@vue/compiler-core@3.5.25': + dependencies: + '@babel/parser': 7.28.5 + '@vue/shared': 3.5.25 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.25': + dependencies: + '@vue/compiler-core': 3.5.25 + '@vue/shared': 3.5.25 + + '@vue/language-core@1.8.27(typescript@5.9.3)': + dependencies: + '@volar/language-core': 1.11.1 + '@volar/source-map': 1.11.1 + '@vue/compiler-dom': 3.5.25 + '@vue/shared': 3.5.25 + computeds: 0.0.1 + minimatch: 9.0.5 + muggle-string: 0.3.1 + path-browserify: 1.0.1 + vue-template-compiler: 2.7.16 + optionalDependencies: + typescript: 5.9.3 + + '@vue/shared@3.5.25': {} + '@webassemblyjs/ast@1.14.1': dependencies: '@webassemblyjs/helper-numbers': 1.13.2 @@ -9666,14 +11240,14 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@8.4.1(@babel/core@7.26.0)(webpack@5.97.1): + babel-loader@8.4.1(@babel/core@7.26.0)(webpack@5.97.1(@swc/core@1.15.3)): dependencies: '@babel/core': 7.26.0 find-cache-dir: 3.3.2 loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) babel-plugin-istanbul@6.1.1: dependencies: @@ -10042,6 +11616,9 @@ snapshots: commander@8.3.0: {} + commander@9.5.0: + optional: true + common-tags@1.8.2: {} commondir@1.0.1: {} @@ -10067,6 +11644,8 @@ snapshots: transitivePeerDependencies: - supports-color + computeds@0.0.1: {} + concat-map@0.0.1: {} confusing-browser-globals@1.0.11: {} @@ -10118,11 +11697,11 @@ snapshots: core-util-is@1.0.3: {} - cosmiconfig-typescript-loader@4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6(typescript@4.9.5))(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5))(typescript@4.9.5): + cosmiconfig-typescript-loader@4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6(typescript@4.9.5))(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5))(typescript@4.9.5): dependencies: '@types/node': 20.5.1 cosmiconfig: 8.3.6(typescript@4.9.5) - ts-node: 10.9.2(@types/node@20.5.1)(typescript@4.9.5) + ts-node: 10.9.2(@swc/core@1.15.3)(@types/node@16.18.121)(typescript@4.9.5) typescript: 4.9.5 cosmiconfig@6.0.0: @@ -10176,7 +11755,7 @@ snapshots: postcss: 8.4.49 postcss-selector-parser: 6.1.2 - css-loader@6.11.0(webpack@5.97.1): + css-loader@6.11.0(webpack@5.97.1(@swc/core@1.15.3)): dependencies: icss-utils: 5.1.0(postcss@8.4.49) postcss: 8.4.49 @@ -10187,9 +11766,9 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) - css-minimizer-webpack-plugin@3.4.1(webpack@5.97.1): + css-minimizer-webpack-plugin@3.4.1(webpack@5.97.1(@swc/core@1.15.3)): dependencies: cssnano: 5.1.15(postcss@8.4.49) jest-worker: 27.5.1 @@ -10197,7 +11776,7 @@ snapshots: schema-utils: 4.2.0 serialize-javascript: 6.0.2 source-map: 0.6.1 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) css-prefers-color-scheme@6.0.3(postcss@8.4.49): dependencies: @@ -10339,6 +11918,8 @@ snapshots: dayjs@1.11.13: {} + de-indent@1.0.2: {} + debug@2.6.9: dependencies: ms: 2.0.0 @@ -10557,6 +12138,8 @@ snapshots: entities@2.2.0: {} + entities@4.5.0: {} + environment@1.1.0: {} error-ex@1.3.2: @@ -10674,6 +12257,31 @@ snapshots: is-date-object: 1.0.5 is-symbol: 1.1.0 + esbuild@0.18.20: + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -10738,7 +12346,7 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)))(typescript@4.9.5): + eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)))(typescript@4.9.5): dependencies: '@babel/core': 7.26.0 '@babel/eslint-parser': 7.25.9(@babel/core@7.26.0)(eslint@8.57.1) @@ -10750,7 +12358,7 @@ snapshots: eslint: 8.57.1 eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(eslint@8.57.1) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) - eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)))(typescript@4.9.5) + eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)))(typescript@4.9.5) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.2(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -10886,13 +12494,13 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)))(typescript@4.9.5): + eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)))(typescript@4.9.5): dependencies: '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) eslint: 8.57.1 optionalDependencies: '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) - jest: 27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)) + jest: 27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)) transitivePeerDependencies: - supports-color - typescript @@ -10949,6 +12557,10 @@ snapshots: dependencies: eslint: 8.57.1 + eslint-plugin-react-refresh@0.4.24(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-plugin-react@7.37.2(eslint@8.57.1): dependencies: array-includes: 3.1.8 @@ -10993,7 +12605,7 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint-webpack-plugin@3.2.0(eslint@8.57.1)(webpack@5.97.1): + eslint-webpack-plugin@3.2.0(eslint@8.57.1)(webpack@5.97.1(@swc/core@1.15.3)): dependencies: '@types/eslint': 8.56.12 eslint: 8.57.1 @@ -11001,7 +12613,7 @@ snapshots: micromatch: 4.0.8 normalize-path: 3.0.0 schema-utils: 4.2.0 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) eslint@8.57.1: dependencies: @@ -11070,6 +12682,8 @@ snapshots: estree-walker@1.0.1: {} + estree-walker@2.0.2: {} + esutils@2.0.3: {} etag@1.8.1: {} @@ -11183,11 +12797,11 @@ snapshots: dependencies: flat-cache: 3.2.0 - file-loader@6.2.0(webpack@5.97.1): + file-loader@6.2.0(webpack@5.97.1(@swc/core@1.15.3)): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) filelist@1.0.4: dependencies: @@ -11250,7 +12864,7 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@4.9.5)(webpack@5.97.1): + fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@4.9.5)(vue-template-compiler@2.7.16)(webpack@5.97.1(@swc/core@1.15.3)): dependencies: '@babel/code-frame': 7.26.2 '@types/json-schema': 7.0.15 @@ -11266,9 +12880,10 @@ snapshots: semver: 7.6.3 tapable: 1.1.3 typescript: 4.9.5 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) optionalDependencies: eslint: 8.57.1 + vue-template-compiler: 2.7.16 form-data@3.0.2: dependencies: @@ -11304,6 +12919,12 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + fs-extra@9.1.0: dependencies: at-least-node: 1.0.0 @@ -11513,7 +13134,7 @@ snapshots: dependencies: void-elements: 3.1.0 - html-webpack-plugin@5.6.3(webpack@5.97.1): + html-webpack-plugin@5.6.3(webpack@5.97.1(@swc/core@1.15.3)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -11521,7 +13142,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.2.1 optionalDependencies: - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) htmlparser2@6.1.0: dependencies: @@ -11625,6 +13246,8 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 + import-lazy@4.0.0: {} + import-local@3.2.0: dependencies: pkg-dir: 4.2.0 @@ -11906,16 +13529,16 @@ snapshots: transitivePeerDependencies: - supports-color - jest-cli@27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)): + jest-cli@27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)): dependencies: - '@jest/core': 27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)) + '@jest/core': 27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)) '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 import-local: 3.2.0 - jest-config: 27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)) + jest-config: 27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)) jest-util: 27.5.1 jest-validate: 27.5.1 prompts: 2.4.2 @@ -11927,7 +13550,7 @@ snapshots: - ts-node - utf-8-validate - jest-config@27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)): + jest-config@27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)): dependencies: '@babel/core': 7.26.0 '@jest/test-sequencer': 27.5.1 @@ -11954,7 +13577,7 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - ts-node: 10.9.2(@types/node@20.5.1)(typescript@4.9.5) + ts-node: 10.9.2(@swc/core@1.15.3)(@types/node@16.18.121)(typescript@4.9.5) transitivePeerDependencies: - bufferutil - canvas @@ -12246,11 +13869,11 @@ snapshots: leven: 3.1.0 pretty-format: 27.5.1 - jest-watch-typeahead@1.1.0(jest@27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5))): + jest-watch-typeahead@1.1.0(jest@27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5))): dependencies: ansi-escapes: 4.3.2 chalk: 4.1.2 - jest: 27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)) + jest: 27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)) jest-regex-util: 28.0.2 jest-watcher: 28.1.3 slash: 4.0.0 @@ -12296,11 +13919,11 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)): + jest@27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)): dependencies: - '@jest/core': 27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)) + '@jest/core': 27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)) import-local: 3.2.0 - jest-cli: 27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)) + jest-cli: 27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)) transitivePeerDependencies: - bufferutil - canvas @@ -12310,6 +13933,8 @@ snapshots: jiti@1.21.6: {} + jju@1.4.0: {} + js-sha256@0.11.0: {} js-tokens@4.0.0: {} @@ -12377,6 +14002,10 @@ snapshots: json5@2.2.3: {} + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + jsonfile@6.1.0: dependencies: universalify: 2.0.1 @@ -12416,6 +14045,8 @@ snapshots: klona@2.0.6: {} + kolorist@1.8.0: {} + language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -12445,6 +14076,12 @@ snapshots: lines-and-columns@1.2.4: {} + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + linkifyjs@4.3.2: {} + lint-staged@15.5.0: dependencies: chalk: 5.4.1 @@ -12498,6 +14135,10 @@ snapshots: lodash.flow@3.5.0: {} + lodash.get@4.4.2: {} + + lodash.isequal@4.5.0: {} + lodash.isfunction@3.0.9: {} lodash.isplainobject@4.0.6: {} @@ -12554,6 +14195,10 @@ snapshots: dependencies: sourcemap-codec: 1.4.8 + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + make-dir@3.1.0: dependencies: semver: 6.3.1 @@ -12572,12 +14217,25 @@ snapshots: map-obj@4.3.0: {} + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + marked@15.0.12: {} + marked@4.3.0: {} mdn-data@2.0.14: {} mdn-data@2.0.4: {} + mdurl@2.0.0: {} + media-typer@0.3.0: {} memfs@3.5.3: @@ -12629,14 +14287,18 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.2(webpack@5.97.1): + mini-css-extract-plugin@2.9.2(webpack@5.97.1(@swc/core@1.15.3)): dependencies: schema-utils: 4.2.0 tapable: 2.2.1 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) minimalistic-assert@1.0.1: {} + minimatch@3.0.8: + dependencies: + brace-expansion: 1.1.11 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -12671,6 +14333,8 @@ snapshots: ms@2.1.3: {} + muggle-string@0.3.1: {} + multicast-dns@7.2.5: dependencies: dns-packet: 5.6.1 @@ -12858,6 +14522,8 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 + orderedmap@2.1.1: {} + p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -12912,6 +14578,8 @@ snapshots: no-case: 3.0.4 tslib: 2.8.1 + path-browserify@1.0.1: {} + path-exists@3.0.0: {} path-exists@4.0.0: {} @@ -12941,6 +14609,8 @@ snapshots: picomatch@2.3.1: {} + picomatch@4.0.3: {} + pidtree@0.6.0: {} pify@2.3.0: {} @@ -13105,21 +14775,21 @@ snapshots: postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)): + postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)): dependencies: lilconfig: 3.1.3 yaml: 2.7.0 optionalDependencies: postcss: 8.4.49 - ts-node: 10.9.2(@types/node@20.5.1)(typescript@4.9.5) + ts-node: 10.9.2(@swc/core@1.15.3)(@types/node@16.18.121)(typescript@4.9.5) - postcss-loader@6.2.1(postcss@8.4.49)(webpack@5.97.1): + postcss-loader@6.2.1(postcss@8.4.49)(webpack@5.97.1(@swc/core@1.15.3)): dependencies: cosmiconfig: 7.1.0 klona: 2.0.6 postcss: 8.4.49 semver: 7.6.3 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) postcss-logical@5.0.4(postcss@8.4.49): dependencies: @@ -13449,6 +15119,109 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + prosemirror-changeset@2.3.1: + dependencies: + prosemirror-transform: 1.10.5 + + prosemirror-collab@1.3.1: + dependencies: + prosemirror-state: 1.4.4 + + prosemirror-commands@1.7.1: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + + prosemirror-dropcursor@1.8.2: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.3 + + prosemirror-gapcursor@1.4.0: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-view: 1.41.3 + + prosemirror-history@1.5.0: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.3 + rope-sequence: 1.3.4 + + prosemirror-inputrules@1.5.1: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + + prosemirror-keymap@1.2.3: + dependencies: + prosemirror-state: 1.4.4 + w3c-keyname: 2.2.8 + + prosemirror-markdown@1.13.2: + dependencies: + '@types/markdown-it': 14.1.2 + markdown-it: 14.1.0 + prosemirror-model: 1.25.4 + + prosemirror-menu@1.2.5: + dependencies: + crelt: 1.0.6 + prosemirror-commands: 1.7.1 + prosemirror-history: 1.5.0 + prosemirror-state: 1.4.4 + + prosemirror-model@1.25.4: + dependencies: + orderedmap: 2.1.1 + + prosemirror-schema-basic@1.2.4: + dependencies: + prosemirror-model: 1.25.4 + + prosemirror-schema-list@1.5.1: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + + prosemirror-state@1.4.4: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.3 + + prosemirror-tables@1.8.1: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.3 + + prosemirror-trailing-node@3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.3): + dependencies: + '@remirror/core-constants': 3.0.0 + escape-string-regexp: 4.0.0 + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-view: 1.41.3 + + prosemirror-transform@1.10.5: + dependencies: + prosemirror-model: 1.25.4 + + prosemirror-view@1.41.3: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 @@ -13460,12 +15233,14 @@ snapshots: dependencies: punycode: 2.3.1 + punycode.js@2.3.1: {} + punycode@2.3.1: {} - purgecss-webpack-plugin@4.1.3(webpack@5.97.1): + purgecss-webpack-plugin@4.1.3(webpack@5.97.1(@swc/core@1.15.3)): dependencies: purgecss: 4.1.3 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) webpack-sources: 3.2.3 purgecss@4.1.3: @@ -13523,9 +15298,9 @@ snapshots: regenerator-runtime: 0.13.11 whatwg-fetch: 3.6.20 - react-app-rewired@2.2.1(react-scripts@5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(sass@1.54.4)(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5))(type-fest@1.4.0)(typescript@4.9.5)): + react-app-rewired@2.2.1(react-scripts@5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(@swc/core@1.15.3)(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(sass@1.54.4)(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5))(type-fest@1.4.0)(typescript@4.9.5)(vue-template-compiler@2.7.16)): dependencies: - react-scripts: 5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(sass@1.54.4)(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5))(type-fest@1.4.0)(typescript@4.9.5) + react-scripts: 5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(@swc/core@1.15.3)(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(sass@1.54.4)(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5))(type-fest@1.4.0)(typescript@4.9.5)(vue-template-compiler@2.7.16) semver: 5.7.2 react-bootstrap@2.10.6(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): @@ -13547,7 +15322,7 @@ snapshots: optionalDependencies: '@types/react': 18.3.16 - react-dev-utils@12.0.1(eslint@8.57.1)(typescript@4.9.5)(webpack@5.97.1): + react-dev-utils@12.0.1(eslint@8.57.1)(typescript@4.9.5)(vue-template-compiler@2.7.16)(webpack@5.97.1(@swc/core@1.15.3)): dependencies: '@babel/code-frame': 7.26.2 address: 1.2.2 @@ -13558,7 +15333,7 @@ snapshots: escape-string-regexp: 4.0.0 filesize: 8.0.7 find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@4.9.5)(webpack@5.97.1) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@4.9.5)(vue-template-compiler@2.7.16)(webpack@5.97.1(@swc/core@1.15.3)) global-modules: 2.0.0 globby: 11.1.0 gzip-size: 6.0.0 @@ -13573,7 +15348,7 @@ snapshots: shell-quote: 1.8.2 strip-ansi: 6.0.1 text-table: 0.2.0 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) optionalDependencies: typescript: 4.9.5 transitivePeerDependencies: @@ -13636,56 +15411,56 @@ snapshots: optionalDependencies: react-dom: 18.3.1(react@18.3.1) - react-scripts@5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(sass@1.54.4)(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5))(type-fest@1.4.0)(typescript@4.9.5): + react-scripts@5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(@swc/core@1.15.3)(@types/babel__core@7.20.5)(eslint@8.57.1)(react@18.3.1)(sass@1.54.4)(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5))(type-fest@1.4.0)(typescript@4.9.5)(vue-template-compiler@2.7.16): dependencies: '@babel/core': 7.26.0 - '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.11.0)(type-fest@1.4.0)(webpack-dev-server@4.15.2(webpack@5.97.1))(webpack@5.97.1) + '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.11.0)(type-fest@1.4.0)(webpack-dev-server@4.15.2(webpack@5.97.1(@swc/core@1.15.3)))(webpack@5.97.1(@swc/core@1.15.3)) '@svgr/webpack': 5.5.0 babel-jest: 27.5.1(@babel/core@7.26.0) - babel-loader: 8.4.1(@babel/core@7.26.0)(webpack@5.97.1) + babel-loader: 8.4.1(@babel/core@7.26.0)(webpack@5.97.1(@swc/core@1.15.3)) babel-plugin-named-asset-import: 0.3.8(@babel/core@7.26.0) babel-preset-react-app: 10.0.1 bfj: 7.1.0 browserslist: 4.24.2 camelcase: 6.3.0 case-sensitive-paths-webpack-plugin: 2.4.0 - css-loader: 6.11.0(webpack@5.97.1) - css-minimizer-webpack-plugin: 3.4.1(webpack@5.97.1) + css-loader: 6.11.0(webpack@5.97.1(@swc/core@1.15.3)) + css-minimizer-webpack-plugin: 3.4.1(webpack@5.97.1(@swc/core@1.15.3)) dotenv: 10.0.0 dotenv-expand: 5.1.0 eslint: 8.57.1 - eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)))(typescript@4.9.5) - eslint-webpack-plugin: 3.2.0(eslint@8.57.1)(webpack@5.97.1) - file-loader: 6.2.0(webpack@5.97.1) + eslint-config-react-app: 7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(eslint@8.57.1)(jest@27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)))(typescript@4.9.5) + eslint-webpack-plugin: 3.2.0(eslint@8.57.1)(webpack@5.97.1(@swc/core@1.15.3)) + file-loader: 6.2.0(webpack@5.97.1(@swc/core@1.15.3)) fs-extra: 10.1.0 - html-webpack-plugin: 5.6.3(webpack@5.97.1) + html-webpack-plugin: 5.6.3(webpack@5.97.1(@swc/core@1.15.3)) identity-obj-proxy: 3.0.0 - jest: 27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)) + jest: 27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)) jest-resolve: 27.5.1 - jest-watch-typeahead: 1.1.0(jest@27.5.1(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5))) - mini-css-extract-plugin: 2.9.2(webpack@5.97.1) + jest-watch-typeahead: 1.1.0(jest@27.5.1(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5))) + mini-css-extract-plugin: 2.9.2(webpack@5.97.1(@swc/core@1.15.3)) postcss: 8.4.49 postcss-flexbugs-fixes: 5.0.2(postcss@8.4.49) - postcss-loader: 6.2.1(postcss@8.4.49)(webpack@5.97.1) + postcss-loader: 6.2.1(postcss@8.4.49)(webpack@5.97.1(@swc/core@1.15.3)) postcss-normalize: 10.0.1(browserslist@4.24.2)(postcss@8.4.49) postcss-preset-env: 7.8.3(postcss@8.4.49) prompts: 2.4.2 react: 18.3.1 react-app-polyfill: 3.0.0 - react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@4.9.5)(webpack@5.97.1) + react-dev-utils: 12.0.1(eslint@8.57.1)(typescript@4.9.5)(vue-template-compiler@2.7.16)(webpack@5.97.1(@swc/core@1.15.3)) react-refresh: 0.11.0 resolve: 1.22.8 resolve-url-loader: 4.0.0 - sass-loader: 12.6.0(sass@1.54.4)(webpack@5.97.1) + sass-loader: 12.6.0(sass@1.54.4)(webpack@5.97.1(@swc/core@1.15.3)) semver: 7.6.3 - source-map-loader: 3.0.2(webpack@5.97.1) - style-loader: 3.3.4(webpack@5.97.1) - tailwindcss: 3.4.16(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)) - terser-webpack-plugin: 5.3.10(webpack@5.97.1) - webpack: 5.97.1 - webpack-dev-server: 4.15.2(webpack@5.97.1) - webpack-manifest-plugin: 4.1.1(webpack@5.97.1) - workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.97.1) + source-map-loader: 3.0.2(webpack@5.97.1(@swc/core@1.15.3)) + style-loader: 3.3.4(webpack@5.97.1(@swc/core@1.15.3)) + tailwindcss: 3.4.16(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)) + terser-webpack-plugin: 5.3.10(@swc/core@1.15.3)(webpack@5.97.1(@swc/core@1.15.3)) + webpack: 5.97.1(@swc/core@1.15.3) + webpack-dev-server: 4.15.2(webpack@5.97.1(@swc/core@1.15.3)) + webpack-manifest-plugin: 4.1.1(webpack@5.97.1(@swc/core@1.15.3)) + workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.97.1(@swc/core@1.15.3)) optionalDependencies: fsevents: 2.3.3 typescript: 4.9.5 @@ -13875,6 +15650,11 @@ snapshots: resolve.exports@1.1.1: {} + resolve@1.19.0: + dependencies: + is-core-module: 2.15.1 + path-parse: 1.0.7 + resolve@1.22.8: dependencies: is-core-module: 2.15.1 @@ -13918,6 +15698,12 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + rollup@3.29.5: + optionalDependencies: + fsevents: 2.3.3 + + rope-sequence@1.3.4: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -13943,11 +15729,11 @@ snapshots: sanitize.css@13.0.0: {} - sass-loader@12.6.0(sass@1.54.4)(webpack@5.97.1): + sass-loader@12.6.0(sass@1.54.4)(webpack@5.97.1(@swc/core@1.15.3)): dependencies: klona: 2.0.6 neo-async: 2.6.2 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) optionalDependencies: sass: 1.54.4 @@ -14146,12 +15932,12 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@3.0.2(webpack@5.97.1): + source-map-loader@3.0.2(webpack@5.97.1(@swc/core@1.15.3)): dependencies: abab: 2.0.6 iconv-lite: 0.6.3 source-map-js: 1.2.1 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) source-map-resolve@0.5.3: dependencies: @@ -14354,9 +16140,9 @@ snapshots: strip-json-comments@3.1.1: {} - style-loader@3.3.4(webpack@5.97.1): + style-loader@3.3.4(webpack@5.97.1(@swc/core@1.15.3)): dependencies: - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) style-mod@4.1.2: {} @@ -14434,7 +16220,7 @@ snapshots: '@pkgr/core': 0.1.1 tslib: 2.8.1 - tailwindcss@3.4.16(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)): + tailwindcss@3.4.16(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -14453,7 +16239,7 @@ snapshots: postcss: 8.4.49 postcss-import: 15.1.0(postcss@8.4.49) postcss-js: 4.0.1(postcss@8.4.49) - postcss-load-config: 4.0.2(postcss@8.4.49)(ts-node@10.9.2(@types/node@16.18.121)(typescript@4.9.5)) + postcss-load-config: 4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.15.3)(@types/node@20.5.1)(typescript@4.9.5)) postcss-nested: 6.2.0(postcss@8.4.49) postcss-selector-parser: 6.1.2 resolve: 1.22.8 @@ -14484,14 +16270,16 @@ snapshots: ansi-escapes: 4.3.2 supports-hyperlinks: 2.3.0 - terser-webpack-plugin@5.3.10(webpack@5.97.1): + terser-webpack-plugin@5.3.10(@swc/core@1.15.3)(webpack@5.97.1(@swc/core@1.15.3)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.37.0 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) + optionalDependencies: + '@swc/core': 1.15.3 terser@5.37.0: dependencies: @@ -14538,6 +16326,8 @@ snapshots: toidentifier@1.0.1: {} + tosource@2.0.0-alpha.3: {} + tough-cookie@4.1.4: dependencies: psl: 1.15.0 @@ -14561,16 +16351,20 @@ snapshots: dependencies: typescript: 4.9.5 + ts-api-utils@1.4.3(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5): + ts-node@10.9.2(@swc/core@1.15.3)(@types/node@16.18.121)(typescript@4.9.5): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.5.1 + '@types/node': 16.18.121 acorn: 8.14.0 acorn-walk: 8.3.4 arg: 4.1.3 @@ -14580,6 +16374,8 @@ snapshots: typescript: 4.9.5 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + optionalDependencies: + '@swc/core': 1.15.3 tsconfig-paths@3.15.0: dependencies: @@ -14668,6 +16464,12 @@ snapshots: typescript@4.9.5: {} + typescript@5.4.2: {} + + typescript@5.9.3: {} + + uc.micro@2.1.0: {} + unbox-primitive@1.0.2: dependencies: call-bind: 1.0.8 @@ -14704,6 +16506,8 @@ snapshots: dependencies: crypto-random-string: 2.0.0 + universalify@0.1.2: {} + universalify@0.2.0: {} universalify@2.0.1: {} @@ -14731,10 +16535,9 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 - use-sync-external-store@1.2.2(react@18.3.1): + use-sync-external-store@1.6.0(react@18.3.1): dependencies: react: 18.3.1 - optional: true util-deprecate@1.0.2: {} @@ -14764,10 +16567,52 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + validator@13.15.23: {} + vary@1.1.2: {} + vite-plugin-dts@3.9.1(@types/node@20.5.1)(rollup@3.29.5)(typescript@5.9.3)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)): + dependencies: + '@microsoft/api-extractor': 7.43.0(@types/node@20.5.1) + '@rollup/pluginutils': 5.3.0(rollup@3.29.5) + '@vue/language-core': 1.8.27(typescript@5.9.3) + debug: 4.4.0 + kolorist: 1.8.0 + magic-string: 0.30.21 + typescript: 5.9.3 + vue-tsc: 1.8.27(typescript@5.9.3) + optionalDependencies: + vite: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) + transitivePeerDependencies: + - '@types/node' + - rollup + - supports-color + + vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0): + dependencies: + esbuild: 0.18.20 + postcss: 8.4.49 + rollup: 3.29.5 + optionalDependencies: + '@types/node': 20.5.1 + fsevents: 2.3.3 + sass: 1.54.4 + terser: 5.37.0 + void-elements@3.1.0: {} + vue-template-compiler@2.7.16: + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + vue-tsc@1.8.27(typescript@5.9.3): + dependencies: + '@volar/typescript': 1.11.1 + '@vue/language-core': 1.8.27(typescript@5.9.3) + semver: 7.6.3 + typescript: 5.9.3 + w3c-hr-time@1.0.2: dependencies: browser-process-hrtime: 1.0.0 @@ -14801,16 +16646,16 @@ snapshots: webidl-conversions@6.1.0: {} - webpack-dev-middleware@5.3.4(webpack@5.97.1): + webpack-dev-middleware@5.3.4(webpack@5.97.1(@swc/core@1.15.3)): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) - webpack-dev-server@4.15.2(webpack@5.97.1): + webpack-dev-server@4.15.2(webpack@5.97.1(@swc/core@1.15.3)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -14840,20 +16685,20 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.97.1) + webpack-dev-middleware: 5.3.4(webpack@5.97.1(@swc/core@1.15.3)) ws: 8.18.0 optionalDependencies: - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate - webpack-manifest-plugin@4.1.1(webpack@5.97.1): + webpack-manifest-plugin@4.1.1(webpack@5.97.1(@swc/core@1.15.3)): dependencies: tapable: 2.2.1 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) webpack-sources: 2.3.1 webpack-sources@1.4.3: @@ -14868,7 +16713,7 @@ snapshots: webpack-sources@3.2.3: {} - webpack@5.97.1: + webpack@5.97.1(@swc/core@1.15.3): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.6 @@ -14890,7 +16735,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(webpack@5.97.1) + terser-webpack-plugin: 5.3.10(@swc/core@1.15.3)(webpack@5.97.1(@swc/core@1.15.3)) watchpack: 2.4.2 webpack-sources: 3.2.3 transitivePeerDependencies: @@ -15085,12 +16930,12 @@ snapshots: workbox-sw@6.6.0: {} - workbox-webpack-plugin@6.6.0(@types/babel__core@7.20.5)(webpack@5.97.1): + workbox-webpack-plugin@6.6.0(@types/babel__core@7.20.5)(webpack@5.97.1(@swc/core@1.15.3)): dependencies: fast-json-stable-stringify: 2.1.0 pretty-bytes: 5.6.0 upath: 1.2.0 - webpack: 5.97.1 + webpack: 5.97.1(@swc/core@1.15.3) webpack-sources: 1.4.3 workbox-build: 6.6.0(@types/babel__core@7.20.5) transitivePeerDependencies: @@ -15210,9 +17055,17 @@ snapshots: yocto-queue@0.1.0: {} - zustand@5.0.2(@types/react@18.3.16)(immer@9.0.21)(react@18.3.1)(use-sync-external-store@1.2.2(react@18.3.1)): + z-schema@5.0.5: + dependencies: + lodash.get: 4.4.2 + lodash.isequal: 4.5.0 + validator: 13.15.23 + optionalDependencies: + commander: 9.5.0 + + zustand@5.0.2(@types/react@18.3.16)(immer@9.0.21)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)): optionalDependencies: '@types/react': 18.3.16 immer: 9.0.21 react: 18.3.1 - use-sync-external-store: 1.2.2(react@18.3.1) + use-sync-external-store: 1.6.0(react@18.3.1) diff --git a/ui/src/components/Editor/EditorContext.ts b/ui/src/components/Editor/EditorContext.ts index 9cfaffe2d..c5c584579 100644 --- a/ui/src/components/Editor/EditorContext.ts +++ b/ui/src/components/Editor/EditorContext.ts @@ -19,6 +19,6 @@ import React from 'react'; -import { IEditorContext } from './types'; +import { Editor } from './types'; -export const EditorContext = React.createContext({}); +export const EditorContext = React.createContext(null); diff --git a/ui/src/components/Editor/MarkdownEditor.tsx b/ui/src/components/Editor/MarkdownEditor.tsx new file mode 100644 index 000000000..10145a228 --- /dev/null +++ b/ui/src/components/Editor/MarkdownEditor.tsx @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { useEffect, useRef } from 'react'; + +import { EditorView } from '@codemirror/view'; + +import { Editor } from './types'; +import { useEditor } from './utils'; + +interface MarkdownEditorProps { + value: string; + onChange?: (value: string) => void; + onFocus?: () => void; + onBlur?: () => void; + placeholder?: string; + autoFocus?: boolean; + onEditorReady?: (editor: Editor) => void; +} + +const MarkdownEditor: React.FC = ({ + value, + onChange, + onFocus, + onBlur, + placeholder, + autoFocus, + onEditorReady, +}) => { + const editorRef = useRef(null); + const lastSyncedValueRef = useRef(value); + + const editor = useEditor({ + editorRef, + onChange, + onFocus, + onBlur, + placeholder, + autoFocus, + }); + + // 初始化内容(只在编辑器创建时执行) + useEffect(() => { + if (!editor) { + return; + } + + // 初始化编辑器内容 + editor.setValue(value || ''); + lastSyncedValueRef.current = value || ''; + onEditorReady?.(editor); + }, [editor]); // 只在编辑器创建时执行 + + // 当外部 value 变化时更新(但不是用户输入导致的) + useEffect(() => { + if (!editor) { + return; + } + + // 如果 value 和 lastSyncedValueRef 相同,说明是用户输入导致的更新,跳过 + if (value === lastSyncedValueRef.current) { + return; + } + + // 外部 value 真正变化,更新编辑器 + const currentValue = editor.getValue(); + if (currentValue !== value) { + editor.setValue(value || ''); + lastSyncedValueRef.current = value || ''; + } + }, [editor, value]); + + // 清理:组件卸载时销毁编辑器 + useEffect(() => { + return () => { + if (editor) { + // CodeMirror EditorView 有 destroy 方法 + const view = editor as unknown as EditorView; + if (view.destroy) { + view.destroy(); + } + } + }; + }, [editor]); + + return ( +
    +
    +
    + ); +}; + +export default MarkdownEditor; diff --git a/ui/src/components/Editor/ToolBars/blockquote.tsx b/ui/src/components/Editor/ToolBars/blockquote.tsx index fac2fc5a7..27147ed29 100644 --- a/ui/src/components/Editor/ToolBars/blockquote.tsx +++ b/ui/src/components/Editor/ToolBars/blockquote.tsx @@ -21,9 +21,8 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import ToolItem from '../toolItem'; -import { IEditorContext } from '../types'; +import { Editor } from '../types'; -let context: IEditorContext; const BlockQuote = () => { const { t } = useTranslation('translation', { keyPrefix: 'editor' }); @@ -33,21 +32,9 @@ const BlockQuote = () => { tip: `${t('blockquote.text')} (Ctrl+Q)`, }; - const handleClick = (ctx) => { - context = ctx; - context.replaceLines((line) => { - const FIND_BLOCKQUOTE_RX = /^>\s+?/g; - - if (line === `> ${t('blockquote.text')}`) { - line = ''; - } else if (line.match(FIND_BLOCKQUOTE_RX)) { - line = line.replace(FIND_BLOCKQUOTE_RX, ''); - } else { - line = `> ${line || t('blockquote.text')}`; - } - return line; - }, 2); - context.editor?.focus(); + const handleClick = (editor: Editor) => { + editor.insertBlockquote(t('blockquote.text')); + editor.focus(); }; return ; diff --git a/ui/src/components/Editor/ToolBars/bold.tsx b/ui/src/components/Editor/ToolBars/bold.tsx index 8efe69c5b..2a9a292ef 100644 --- a/ui/src/components/Editor/ToolBars/bold.tsx +++ b/ui/src/components/Editor/ToolBars/bold.tsx @@ -21,9 +21,8 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import ToolItem from '../toolItem'; -import { IEditorContext } from '../types'; +import { Editor } from '../types'; -let context: IEditorContext; const Bold = () => { const { t } = useTranslation('translation', { keyPrefix: 'editor' }); const item = { @@ -33,10 +32,9 @@ const Bold = () => { }; const DEFAULTTEXT = t('bold.text'); - const handleClick = (ctx) => { - context = ctx; - context.wrapText('**', '**', DEFAULTTEXT); - context.editor?.focus(); + const handleClick = (editor: Editor) => { + editor.insertBold(DEFAULTTEXT); + editor.focus(); }; return ; diff --git a/ui/src/components/Editor/ToolBars/code.tsx b/ui/src/components/Editor/ToolBars/code.tsx index afbd7dde9..599ffaea5 100644 --- a/ui/src/components/Editor/ToolBars/code.tsx +++ b/ui/src/components/Editor/ToolBars/code.tsx @@ -23,7 +23,7 @@ import { useTranslation } from 'react-i18next'; import Select from '../Select'; import ToolItem from '../toolItem'; -import { IEditorContext } from '../types'; +import { Editor } from '../types'; const codeLanguageType = [ 'bash', @@ -150,7 +150,6 @@ const codeLanguageType = [ 'yml', ]; -let context: IEditorContext; const Code = () => { const { t } = useTranslation('translation', { keyPrefix: 'editor' }); @@ -170,22 +169,20 @@ const Code = () => { const inputRef = useRef(null); const SINGLELINEMAXLENGTH = 40; - const addCode = (ctx) => { - context = ctx; + const [currentEditor, setCurrentEditor] = useState(null); - const { wrapText, editor } = context; - - const text = context.editor.getSelection(); + const addCode = (editor: Editor) => { + setCurrentEditor(editor); + const text = editor.getSelection(); if (!text) { setVisible(true); - return; } if (text.length > SINGLELINEMAXLENGTH) { - context.wrapText('```\n', '\n```'); + editor.insertCodeBlock('', text); } else { - wrapText('`', '`'); + editor.insertCode(text); } editor.focus(); }; @@ -197,6 +194,10 @@ const Code = () => { }, [visible]); const handleClick = () => { + if (!currentEditor) { + return; + } + if (!code.value.trim()) { setCode({ ...code, @@ -206,17 +207,15 @@ const Code = () => { return; } - let value; - if ( code.value.split('\n').length > 1 || code.value.length >= SINGLELINEMAXLENGTH ) { - value = `\n\`\`\`${lang}\n${code.value}\n\`\`\`\n`; + currentEditor.insertCodeBlock(lang || undefined, code.value); } else { - value = `\`${code.value}\``; + currentEditor.insertCode(code.value); } - context.editor.replaceSelection(value); + setCode({ value: '', isInvalid: false, @@ -224,9 +223,10 @@ const Code = () => { }); setLang(''); setVisible(false); + currentEditor.focus(); }; const onHide = () => setVisible(false); - const onExited = () => context.editor?.focus(); + const onExited = () => currentEditor?.focus(); return ( diff --git a/ui/src/components/Editor/ToolBars/file.tsx b/ui/src/components/Editor/ToolBars/file.tsx index 9e6e7399c..d48c0e6ac 100644 --- a/ui/src/components/Editor/ToolBars/file.tsx +++ b/ui/src/components/Editor/ToolBars/file.tsx @@ -17,31 +17,28 @@ * under the License. */ -import { useState, memo, useRef } from 'react'; +import { memo, useRef, useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { Modal as AnswerModal } from '@/components'; import ToolItem from '../toolItem'; -import { IEditorContext, Editor } from '../types'; +import { EditorContext } from '../EditorContext'; import { uploadImage } from '@/services'; import { writeSettingStore } from '@/stores'; -let context: IEditorContext; -const Image = ({ editorInstance }) => { +const File = () => { const { t } = useTranslation('translation', { keyPrefix: 'editor' }); const { max_attachment_size = 8, authorized_attachment_extensions = [] } = writeSettingStore((state) => state.write); const fileInputRef = useRef(null); - const [editor, setEditor] = useState(editorInstance); + const editor = useContext(EditorContext); const item = { label: 'paperclip', tip: `${t('file.text')}`, }; - const addLink = (ctx) => { - context = ctx; - setEditor(context.editor); + const addLink = () => { fileInputRef.current?.click?.(); }; @@ -132,4 +129,4 @@ const Image = ({ editorInstance }) => { ); }; -export default memo(Image); +export default memo(File); diff --git a/ui/src/components/Editor/ToolBars/heading.tsx b/ui/src/components/Editor/ToolBars/heading.tsx index 8b0cb6043..4b49212cb 100644 --- a/ui/src/components/Editor/ToolBars/heading.tsx +++ b/ui/src/components/Editor/ToolBars/heading.tsx @@ -22,9 +22,8 @@ import { Dropdown } from 'react-bootstrap'; import { useTranslation } from 'react-i18next'; import ToolItem from '../toolItem'; -import { IEditorContext } from '../types'; +import { Editor, Level } from '../types'; -let context: IEditorContext; const Heading = () => { const { t } = useTranslation('translation', { keyPrefix: 'editor' }); const headerList = [ @@ -61,19 +60,18 @@ const Heading = () => { }; const [isShow, setShowState] = useState(false); const [isLocked, setLockState] = useState(false); + const [currentEditor, setCurrentEditor] = useState(null); - const handleClick = (level = 2, label = '大标题') => { - const { replaceLines } = context; - - replaceLines((line) => { - line = line.trim().replace(/^#*/, '').trim(); - line = `${'#'.repeat(level)} ${line || label}`; - return line; - }, level + 1); + const handleClick = (level: Level = 2, label = '大标题') => { + if (!currentEditor) { + return; + } + currentEditor.insertHeading(level, label); + currentEditor.focus(); setShowState(false); }; - const onAddHeader = (ctx) => { - context = ctx; + const onAddHeader = (editor: Editor) => { + setCurrentEditor(editor); if (isLocked) { return; } @@ -104,7 +102,7 @@ const Heading = () => { onClick={(e) => { e.preventDefault(); e.stopPropagation(); - handleClick(header.level, header.label); + handleClick(header.level as Level, header.label); }} dangerouslySetInnerHTML={{ __html: header.text }} /> diff --git a/ui/src/components/Editor/ToolBars/hr.tsx b/ui/src/components/Editor/ToolBars/hr.tsx index ac988a877..6919eb3bd 100644 --- a/ui/src/components/Editor/ToolBars/hr.tsx +++ b/ui/src/components/Editor/ToolBars/hr.tsx @@ -21,9 +21,8 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import ToolItem from '../toolItem'; -import { IEditorContext } from '../types'; +import { Editor } from '../types'; -let context: IEditorContext; const Hr = () => { const { t } = useTranslation('translation', { keyPrefix: 'editor' }); const item = { @@ -31,11 +30,9 @@ const Hr = () => { keyMap: ['Ctrl-r'], tip: `${t('hr.text')} (Ctrl+r)`, }; - const handleClick = (ctx) => { - context = ctx; - const { appendBlock, editor } = context; - appendBlock('----------\n'); - editor?.focus(); + const handleClick = (editor: Editor) => { + editor.insertHorizontalRule(); + editor.focus(); }; return ; diff --git a/ui/src/components/Editor/ToolBars/image.tsx b/ui/src/components/Editor/ToolBars/image.tsx index c9950b069..67a79b3ca 100644 --- a/ui/src/components/Editor/ToolBars/image.tsx +++ b/ui/src/components/Editor/ToolBars/image.tsx @@ -17,19 +17,28 @@ * under the License. */ -import { useEffect, useState, memo } from 'react'; +import { useEffect, useState, memo, useContext } from 'react'; import { Button, Form, Modal, Tab, Tabs } from 'react-bootstrap'; import { useTranslation } from 'react-i18next'; import { Modal as AnswerModal } from '@/components'; import ToolItem from '../toolItem'; -import { IEditorContext, Editor } from '../types'; +import { EditorContext } from '../EditorContext'; +import { Editor } from '../types'; import { uploadImage } from '@/services'; import { writeSettingStore } from '@/stores'; -let context: IEditorContext; -const Image = ({ editorInstance }) => { - const [editor, setEditor] = useState(editorInstance); +const Image = () => { + const editor = useContext(EditorContext); + const [editorState, setEditorState] = useState(editor); + + // 当 editor 改变时,更新 editor state + // 这样切换编辑器模式时,事件监听器会重新绑定 + useEffect(() => { + if (editor) { + setEditorState(editor); + } + }, [editor]); const { t } = useTranslation('translation', { keyPrefix: 'editor' }); const { max_image_size = 4, @@ -160,19 +169,22 @@ const Image = ({ editorInstance }) => { return; } - const startPos = editor.getCursor(); + if (!editorState) { + return; + } + const startPos = editorState.getCursor(); const endPos = { ...startPos, ch: startPos.ch + loadingText.length }; - editor.replaceSelection(loadingText); - editor.setReadOnly(true); + editorState.replaceSelection(loadingText); + editorState.setReadOnly(true); const urls = await upload(fileList) .catch(() => { - editor.replaceRange('', startPos, endPos); + editorState.replaceRange('', startPos, endPos); }) .finally(() => { - editor.setReadOnly(false); - editor.focus(); + editorState?.setReadOnly(false); + editorState?.focus(); }); const text: string[] = []; @@ -184,9 +196,9 @@ const Image = ({ editorInstance }) => { }); } if (text.length) { - editor.replaceRange(text.join('\n'), startPos, endPos); + editorState.replaceRange(text.join('\n'), startPos, endPos); } else { - editor.replaceRange('', startPos, endPos); + editorState?.replaceRange('', startPos, endPos); } }; @@ -197,25 +209,28 @@ const Image = ({ editorInstance }) => { if (bool) { event.preventDefault(); - const startPos = editor.getCursor(); + if (!editorState) { + return; + } + const startPos = editorState.getCursor(); const endPos = { ...startPos, ch: startPos.ch + loadingText.length }; - editor.replaceSelection(loadingText); - editor.setReadOnly(true); + editorState?.replaceSelection(loadingText); + editorState?.setReadOnly(true); upload(clipboard.files) .then((urls) => { const text = urls.map(({ name, url, type }) => { return `${type === 'post' ? '!' : ''}[${name}](${url})`; }); - editor.replaceRange(text.join('\n'), startPos, endPos); + editorState.replaceRange(text.join('\n'), startPos, endPos); }) .catch(() => { - editor.replaceRange('', startPos, endPos); + editorState.replaceRange('', startPos, endPos); }) .finally(() => { - editor.setReadOnly(false); - editor.focus(); + editorState?.setReadOnly(false); + editorState?.focus(); }); return; @@ -289,7 +304,9 @@ const Image = ({ editorInstance }) => { return match.length > 1 ? '\n\n' : match; }); - editor.replaceSelection(markdownText); + if (editorState) { + editorState.replaceSelection(markdownText); + } }; const handleClick = () => { if (!link.value) { @@ -298,28 +315,35 @@ const Image = ({ editorInstance }) => { } setLink({ ...link, type: '' }); - const text = `![${imageName.value}](${link.value})`; - - editor.replaceSelection(text); + if (editorState) { + editorState.insertImage(link.value, imageName.value || undefined); + } setVisible(false); - editor.focus(); + editorState?.focus(); setLink({ ...link, value: '' }); setImageName({ ...imageName, value: '' }); }; useEffect(() => { - editor?.on('dragenter', dragenter); - editor?.on('dragover', dragover); - editor?.on('drop', drop); - editor?.on('paste', paste); + if (!editorState) { + return undefined; + } + // 绑定事件监听器 + editorState.on('dragenter', dragenter); + editorState.on('dragover', dragover); + editorState.on('drop', drop); + editorState.on('paste', paste); return () => { - editor?.off('dragenter', dragenter); - editor?.off('dragover', dragover); - editor?.off('drop', drop); - editor?.off('paste', paste); + // 清理事件监听器 + editorState.off('dragenter', dragenter); + editorState.off('dragover', dragover); + editorState.off('drop', drop); + editorState.off('paste', paste); }; - }, [editor]); + // 注意:dragenter, dragover, drop, paste 函数在组件生命周期内是稳定的 + // 它们不依赖任何会变化的值,所以不需要加入依赖项 + }, [editorState]); useEffect(() => { if (link.value && link.type === 'drop') { @@ -327,10 +351,9 @@ const Image = ({ editorInstance }) => { } }, [link.value]); - const addLink = (ctx) => { - context = ctx; - setEditor(context.editor); - const text = context.editor?.getSelection(); + const addLink = (editorInstance: Editor) => { + setEditorState(editorInstance); + const text = editorInstance?.getSelection(); setImageName({ ...imageName, value: text }); diff --git a/ui/src/components/Editor/ToolBars/indent.tsx b/ui/src/components/Editor/ToolBars/indent.tsx index 6ec01dcea..7099fbcb1 100644 --- a/ui/src/components/Editor/ToolBars/indent.tsx +++ b/ui/src/components/Editor/ToolBars/indent.tsx @@ -21,24 +21,17 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import ToolItem from '../toolItem'; -import { IEditorContext } from '../types'; +import { Editor } from '../types'; -let context: IEditorContext; const Indent = () => { const { t } = useTranslation('translation', { keyPrefix: 'editor' }); const item = { label: 'text-indent-left', tip: t('indent.text'), }; - const handleClick = (ctx) => { - context = ctx; - const { editor, replaceLines } = context; - - replaceLines((line) => { - line = ` ${line}`; - return line; - }); - editor?.focus(); + const handleClick = (editor: Editor) => { + editor.indent(); + editor.focus(); }; return ; diff --git a/ui/src/components/Editor/ToolBars/italic.tsx b/ui/src/components/Editor/ToolBars/italic.tsx index cb585893f..4b359d2aa 100644 --- a/ui/src/components/Editor/ToolBars/italic.tsx +++ b/ui/src/components/Editor/ToolBars/italic.tsx @@ -21,9 +21,8 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import ToolItem from '../toolItem'; -import { IEditorContext } from '../types'; +import { Editor } from '../types'; -let context: IEditorContext; const Italic = () => { const { t } = useTranslation('translation', { keyPrefix: 'editor' }); const item = { @@ -33,11 +32,9 @@ const Italic = () => { }; const DEFAULTTEXT = t('italic.text'); - const handleClick = (ctx) => { - context = ctx; - const { editor, wrapText } = context; - wrapText('*', '*', DEFAULTTEXT); - editor?.focus(); + const handleClick = (editor: Editor) => { + editor.insertItalic(DEFAULTTEXT); + editor.focus(); }; return ; diff --git a/ui/src/components/Editor/ToolBars/link.tsx b/ui/src/components/Editor/ToolBars/link.tsx index e761ef3d1..be84c1b37 100644 --- a/ui/src/components/Editor/ToolBars/link.tsx +++ b/ui/src/components/Editor/ToolBars/link.tsx @@ -22,9 +22,8 @@ import { Button, Form, Modal } from 'react-bootstrap'; import { useTranslation } from 'react-i18next'; import ToolItem from '../toolItem'; -import { IEditorContext } from '../types'; +import { Editor } from '../types'; -let context: IEditorContext; const Link = () => { const { t } = useTranslation('translation', { keyPrefix: 'editor' }); const item = { @@ -33,6 +32,7 @@ const Link = () => { tip: `${t('link.text')} (Ctrl+l)`, }; const [visible, setVisible] = useState(false); + const [currentEditor, setCurrentEditor] = useState(null); const [link, setLink] = useState({ value: 'https://', isInvalid: false, @@ -52,39 +52,32 @@ const Link = () => { } }, [visible]); - const addLink = (ctx) => { - context = ctx; - const { editor } = context; - + const addLink = (editor: Editor) => { + setCurrentEditor(editor); const text = editor.getSelection(); - setName({ ...name, value: text }); - setVisible(true); }; const handleClick = () => { - const { editor } = context; + if (!currentEditor) { + return; + } if (!link.value) { setLink({ ...link, isInvalid: true }); return; } - const newStr = name.value - ? `[${name.value}](${link.value})` - : `<${link.value}>`; - editor.replaceSelection(newStr); + currentEditor.insertLink(link.value, name.value || undefined); setVisible(false); - - editor.focus(); + currentEditor.focus(); setLink({ ...link, value: '' }); setName({ ...name, value: '' }); }; const onHide = () => setVisible(false); const onExited = () => { - const { editor } = context; - editor.focus(); + currentEditor?.focus(); }; return ( diff --git a/ui/src/components/Editor/ToolBars/ol.tsx b/ui/src/components/Editor/ToolBars/ol.tsx index 011c35a3c..a42523487 100644 --- a/ui/src/components/Editor/ToolBars/ol.tsx +++ b/ui/src/components/Editor/ToolBars/ol.tsx @@ -21,9 +21,8 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import ToolItem from '../toolItem'; -import { IEditorContext } from '../types'; +import { Editor } from '../types'; -let context: IEditorContext; const OL = () => { const { t } = useTranslation('translation', { keyPrefix: 'editor' }); const item = { @@ -32,20 +31,8 @@ const OL = () => { tip: `${t('ordered_list.text')} (Ctrl+o)`, }; - const handleClick = (ctx) => { - context = ctx; - const { editor, replaceLines } = context; - - replaceLines((line, i) => { - const FIND_OL_RX = /^(\s{0,})(\d+)\.\s/; - - if (line.match(FIND_OL_RX)) { - line = line.replace(FIND_OL_RX, ''); - } else { - line = `${i + 1}. ${line}`; - } - return line; - }); + const handleClick = (editor: Editor) => { + editor.insertOrderedList(); editor.focus(); }; diff --git a/ui/src/components/Editor/ToolBars/outdent.tsx b/ui/src/components/Editor/ToolBars/outdent.tsx index b80670371..484e434cf 100644 --- a/ui/src/components/Editor/ToolBars/outdent.tsx +++ b/ui/src/components/Editor/ToolBars/outdent.tsx @@ -21,9 +21,8 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import ToolItem from '../toolItem'; -import { IEditorContext } from '../types'; +import { Editor } from '../types'; -let context: IEditorContext; const Outdent = () => { const { t } = useTranslation('translation', { keyPrefix: 'editor' }); const item = { @@ -31,16 +30,9 @@ const Outdent = () => { keyMap: ['Shift-Tab'], tip: t('outdent.text'), }; - const handleClick = (ctx) => { - context = ctx; - const { editor, replaceLines } = context; - replaceLines((line) => { - line = line.replace(/^(\s{0,})/, (_1, $1) => { - return $1.length > 4 ? $1.substring(4) : ''; - }); - return line; - }); - editor?.focus(); + const handleClick = (editor: Editor) => { + editor.outdent(); + editor.focus(); }; return ; diff --git a/ui/src/components/Editor/ToolBars/table.tsx b/ui/src/components/Editor/ToolBars/table.tsx index 30ca101d1..6381f4ccd 100644 --- a/ui/src/components/Editor/ToolBars/table.tsx +++ b/ui/src/components/Editor/ToolBars/table.tsx @@ -21,77 +21,18 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import ToolItem from '../toolItem'; -import { IEditorContext } from '../types'; +import { Editor } from '../types'; -let context: IEditorContext; const Table = () => { const { t } = useTranslation('translation', { keyPrefix: 'editor' }); const item = { label: 'table', tip: t('table.text'), }; - const tableData = [ - [`${t('table.heading')} A`], - [`${t('table.heading')} B`], - [`${t('table.cell')} 1`], - [`${t('table.cell')} 2`], - [`${t('table.cell')} 3`], - [`${t('table.cell')} 4`], - ]; - const makeHeader = (col, data) => { - let header = '|'; - let border = '|'; - let index = 0; - - while (col) { - if (data) { - header += ` ${data[index]} |`; - index += 1; - } else { - header += ' |'; - } - - border += ' ----- |'; - - col -= 1; - } - - return `${header}\n${border}\n`; - }; - - const makeBody = (col, row, data) => { - let body = ''; - let index = col; - - for (let irow = 0; irow < row; irow += 1) { - body += '|'; - - for (let icol = 0; icol < col; icol += 1) { - if (data) { - body += ` ${data[index]} |`; - index += 1; - } else { - body += ' |'; - } - } - - body += '\n'; - } - - body = body.replace(/\n$/g, ''); - - return body; - }; - const handleClick = (ctx) => { - context = ctx; - const { editor } = context; - let table = '\n'; - - table += makeHeader(2, tableData); - table += makeBody(2, 2, tableData); - editor?.replaceSelection(table); - editor?.focus(); + const handleClick = (editor: Editor) => { + editor.insertTable(3, 3); + editor.focus(); }; return ; diff --git a/ui/src/components/Editor/ToolBars/ul.tsx b/ui/src/components/Editor/ToolBars/ul.tsx index b906a346b..9651f5a42 100644 --- a/ui/src/components/Editor/ToolBars/ul.tsx +++ b/ui/src/components/Editor/ToolBars/ul.tsx @@ -21,9 +21,8 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import ToolItem from '../toolItem'; -import { IEditorContext } from '../types'; +import { Editor } from '../types'; -let context: IEditorContext; const UL = () => { const { t } = useTranslation('translation', { keyPrefix: 'editor' }); const item = { @@ -32,20 +31,8 @@ const UL = () => { tip: `${t('unordered_list.text')} (Ctrl+u)`, }; - const handleClick = (ctx) => { - context = ctx; - const { editor, replaceLines } = context; - - replaceLines((line) => { - const FIND_UL_RX = /^(\s{0,})(-|\*)\s/; - - if (line.match(FIND_UL_RX)) { - line = line.replace(FIND_UL_RX, ''); - } else { - line = `* ${line}`; - } - return line; - }); + const handleClick = (editor: Editor) => { + editor.insertUnorderedList(); editor.focus(); }; diff --git a/ui/src/components/Editor/WysiwygEditor.tsx b/ui/src/components/Editor/WysiwygEditor.tsx new file mode 100644 index 000000000..7ddb28368 --- /dev/null +++ b/ui/src/components/Editor/WysiwygEditor.tsx @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { useEffect, useRef, useCallback } from 'react'; + +import { + useEditor, + EditorContent, + Editor as TipTapEditor, +} from '@tiptap/react'; +import StarterKit from '@tiptap/starter-kit'; +import Placeholder from '@tiptap/extension-placeholder'; +import { Markdown } from '@tiptap/markdown'; +import Image from '@tiptap/extension-image'; +import { TableKit } from '@tiptap/extension-table'; + +import { Editor } from './types'; +import { createTipTapAdapter } from './utils/tiptap/adapter'; + +interface WysiwygEditorProps { + value: string; + onChange?: (value: string) => void; + onFocus?: () => void; + onBlur?: () => void; + placeholder?: string; + autoFocus?: boolean; + onEditorReady?: (editor: Editor) => void; +} + +const WysiwygEditor: React.FC = ({ + value, + onChange, + onFocus, + onBlur, + placeholder = '', + autoFocus = false, + onEditorReady, +}) => { + const lastSyncedValueRef = useRef(value); + + const adaptedEditorRef = useRef(null); + + const handleUpdate = useCallback( + ({ editor: editorInstance }: { editor: TipTapEditor }) => { + if (onChange) { + const markdown = editorInstance.getMarkdown(); + onChange(markdown); + } + }, + [onChange], + ); + + const handleFocus = useCallback(() => { + onFocus?.(); + }, [onFocus]); + + const handleBlur = useCallback(() => { + onBlur?.(); + }, [onBlur]); + + const editor = useEditor({ + extensions: [ + StarterKit, + Markdown, + Image, + TableKit, + Placeholder.configure({ + placeholder, + }), + ], + content: value || '', + onUpdate: handleUpdate, + onFocus: handleFocus, + onBlur: handleBlur, + editorProps: { + attributes: { + class: 'tiptap-editor', + }, + }, + }); + + useEffect(() => { + if (!editor) { + return; + } + + const checkEditorReady = () => { + if (editor.view && editor.view.dom) { + if (value && value.trim() !== '') { + editor.commands.setContent(value, { contentType: 'markdown' }); + } else { + editor.commands.clearContent(); + } + lastSyncedValueRef.current = value || ''; + if (!adaptedEditorRef.current) { + adaptedEditorRef.current = createTipTapAdapter(editor); + } + onEditorReady?.(adaptedEditorRef.current); + } else { + setTimeout(checkEditorReady, 10); + } + }; + + checkEditorReady(); + }, [editor]); + + useEffect(() => { + if (!editor) { + return; + } + + if (value === lastSyncedValueRef.current) { + return; + } + + const currentMarkdown = editor.getMarkdown(); + if (currentMarkdown !== value) { + if (value && value.trim() !== '') { + editor.commands.setContent(value, { contentType: 'markdown' }); + } else { + editor.commands.clearContent(); + } + lastSyncedValueRef.current = value || ''; + } + }, [editor, value]); + + useEffect(() => { + if (editor && autoFocus) { + setTimeout(() => { + editor.commands.focus(); + }, 100); + } + }, [editor, autoFocus]); + + if (!editor) { + return
    Loading editor...
    ; + } + + return ( +
    + +
    + ); +}; + +export default WysiwygEditor; diff --git a/ui/src/components/Editor/index.scss b/ui/src/components/Editor/index.scss index afd158715..20ab5bab4 100644 --- a/ui/src/components/Editor/index.scss +++ b/ui/src/components/Editor/index.scss @@ -114,6 +114,119 @@ height: 264px; } + // WYSIWYG 编辑器样式 + .wysiwyg-editor-wrap { + height: 264px; + overflow-y: auto; + padding: 0.375rem 0.75rem; + + .tiptap-editor { + outline: none; + min-height: 100%; + + &:focus { + outline: none; + } + + p { + margin: 0.5rem 0; + line-height: 1.6; + + &.is-editor-empty:first-child::before { + content: attr(data-placeholder); + float: left; + color: var(--an-editor-placeholder-color); + pointer-events: none; + height: 0; + } + } + + h1, + h2, + h3, + h4, + h5, + h6 { + margin: 1rem 0 0.5rem; + font-weight: 600; + line-height: 1.4; + } + + ul, + ol { + padding-left: 1.5rem; + margin: 0.5rem 0; + } + + li { + margin: 0.25rem 0; + } + + code { + background-color: var(--an-code-bg, #f4f4f4); + color: var(--an-code-color, #e83e8c); + padding: 0.2em 0.4em; + border-radius: 3px; + font-size: 0.9em; + } + + pre { + background-color: var(--an-code-block-bg, #f8f9fa); + border: 1px solid var(--an-ced4da); + border-radius: 4px; + padding: 1rem; + margin: 0.5rem 0; + overflow-x: auto; + + code { + background-color: transparent; + color: inherit; + padding: 0; + } + } + + blockquote { + border-left: 4px solid var(--an-primary, #0d6efd); + padding-left: 1rem; + margin: 0.5rem 0; + color: var(--an-text-secondary, #6c757d); + } + + a { + color: var(--an-link-color, #0d6efd); + text-decoration: underline; + + &:hover { + text-decoration: none; + } + } + + img { + max-width: 100%; + height: auto; + border-radius: 4px; + } + + hr { + border: none; + border-top: 1px solid var(--an-ced4da); + margin: 1rem 0; + } + + ::selection { + background-color: var(--an-selection-bg, rgba(0, 123, 255, 0.2)); + } + } + + .editor-loading { + display: flex; + align-items: center; + justify-content: center; + height: 100%; + color: var(--an-text-secondary, #6c757d); + } + } + .CodeMirror { height: auto; font-family: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', diff --git a/ui/src/components/Editor/index.tsx b/ui/src/components/Editor/index.tsx index 45919b2c9..a914d912c 100644 --- a/ui/src/components/Editor/index.tsx +++ b/ui/src/components/Editor/index.tsx @@ -18,11 +18,12 @@ */ import { - useEffect, useRef, + useState, ForwardRefRenderFunction, forwardRef, useImperativeHandle, + useCallback, } from 'react'; import classNames from 'classnames'; @@ -47,9 +48,12 @@ import { UL, File, } from './ToolBars'; -import { htmlRender, useEditor } from './utils'; +import { htmlRender } from './utils'; import Viewer from './Viewer'; import { EditorContext } from './EditorContext'; +import WysiwygEditor from './WysiwygEditor'; +import MarkdownEditor from './MarkdownEditor'; +import { Editor } from './types'; import './index.scss'; @@ -82,75 +86,106 @@ const MDEditor: ForwardRefRenderFunction = ( }, ref, ) => { - const editorRef = useRef(null); + const [mode, setMode] = useState<'markdown' | 'wysiwyg'>('markdown'); + const [currentEditor, setCurrentEditor] = useState(null); const previewRef = useRef<{ getHtml; element } | null>(null); useRenderPlugin(previewRef.current?.element); - const editor = useEditor({ - editorRef, - onChange, - onFocus, - onBlur, - placeholder: editorPlaceholder, - autoFocus, - }); + const handleModeChange = useCallback( + (newMode: 'markdown' | 'wysiwyg') => { + if (newMode === mode) { + return; + } - const getHtml = () => { - return previewRef.current?.getHtml(); - }; + setMode(newMode); + setCurrentEditor(null); + }, + [mode, currentEditor], + ); - useImperativeHandle(ref, () => ({ - getHtml, - })); + const getHtml = useCallback(() => { + return previewRef.current?.getHtml(); + }, []); + + useImperativeHandle( + ref, + () => ({ + getHtml, + }), + [getHtml], + ); - useEffect(() => { - if (!editor) { - return; - } - if (editor.getValue() !== value) { - editor.setValue(value || ''); - } - }, [editor, value]); + const EditorComponent = mode === 'markdown' ? MarkdownEditor : WysiwygEditor; return ( <>
    - - {editor && ( - - - - -
    - - -
    - - - -
    -
      -
        - - -
        -
        - - - )} - - -
        -
        +
        + + {currentEditor && ( + + + + +
        + + +
        + + +
    +
    +
      +
        + + +
        +
        + + + )} + + +
        + + +
        + + { + onChange?.(markdown); + }} + onFocus={onFocus} + onBlur={onBlur} + placeholder={editorPlaceholder} + autoFocus={autoFocus} + onEditorReady={(editor) => { + setCurrentEditor(editor); + }} + />
    diff --git a/ui/src/components/Editor/toolItem.tsx b/ui/src/components/Editor/toolItem.tsx index 0c4ca2f10..c0fdf1757 100644 --- a/ui/src/components/Editor/toolItem.tsx +++ b/ui/src/components/Editor/toolItem.tsx @@ -21,16 +21,11 @@ import { FC, useContext, useEffect } from 'react'; import { Dropdown, Button } from 'react-bootstrap'; import { EditorContext } from './EditorContext'; -import { IEditorContext } from './types'; +import { Editor } from './types'; interface IProps { keyMap?: string[]; - onClick?: ({ - editor, - wrapText, - replaceLines, - appendBlock, - }: IEditorContext) => void; + onClick?: (editor: Editor) => void; tip?: string; className?: string; as?: any; @@ -38,12 +33,7 @@ interface IProps { label?: string; disable?: boolean; isShow?: boolean; - onBlur?: ({ - editor, - wrapText, - replaceLines, - appendBlock, - }: IEditorContext) => void; + onBlur?: (editor: Editor) => void; } const ToolItem: FC = (props) => { const editor = useContext(EditorContext); @@ -72,12 +62,8 @@ const ToolItem: FC = (props) => { keyMap.forEach((key) => { editor?.addKeyMap({ [key]: () => { - onClick?.({ - editor, - wrapText: editor?.wrapText, - replaceLines: editor?.replaceLines, - appendBlock: editor?.appendBlock, - }); + onClick?.(editor); + return true; // Command 类型要求返回 boolean }, }); }); @@ -94,21 +80,15 @@ const ToolItem: FC = (props) => { tabIndex={-1} onClick={(e) => { e.preventDefault(); - onClick?.({ - editor, - wrapText: editor?.wrapText, - replaceLines: editor?.replaceLines, - appendBlock: editor?.appendBlock, - }); + if (editor) { + onClick?.(editor); + } }} onBlur={(e) => { e.preventDefault(); - onBlur?.({ - editor, - wrapText: editor?.wrapText, - replaceLines: editor?.replaceLines, - appendBlock: editor?.appendBlock, - }); + if (editor) { + onBlur?.(editor); + } }}> diff --git a/ui/src/components/Editor/types.ts b/ui/src/components/Editor/types.ts index ce33833fe..926d3c203 100644 --- a/ui/src/components/Editor/types.ts +++ b/ui/src/components/Editor/types.ts @@ -24,6 +24,9 @@ export interface Position { line: number; sticky?: string | undefined; } + +export type Level = 1 | 2 | 3 | 4 | 5 | 6; + export interface ExtendEditor { addKeyMap: (keyMap: Record) => void; on: ( @@ -53,16 +56,57 @@ export interface ExtendEditor { getSelection: () => string; replaceSelection: (value: string) => void; focus: () => void; + getCursor: () => Position; + replaceRange: (value: string, from: Position, to: Position) => void; + setSelection: (anchor: Position, head?: Position) => void; + setReadOnly: (readOnly: boolean) => void; + + // 底层方法(供编辑器内部使用,不推荐工具栏直接使用) wrapText: (before: string, after?: string, defaultText?: string) => void; replaceLines: ( replace: Parameters['map']>[0], symbolLen?: number, ) => void; appendBlock: (content: string) => void; - getCursor: () => Position; - replaceRange: (value: string, from: Position, to: Position) => void; - setSelection: (anchor: Position, head?: Position) => void; - setReadOnly: (readOnly: boolean) => void; + + // 语义化高级方法(工具栏推荐使用) + // 文本格式 + insertBold: (text?: string) => void; + insertItalic: (text?: string) => void; + insertCode: (text?: string) => void; + insertStrikethrough: (text?: string) => void; + + // 块级元素 + insertHeading: (level: Level, text?: string) => void; + insertBlockquote: (text?: string) => void; + insertCodeBlock: (language?: string, code?: string) => void; + insertHorizontalRule: () => void; + + // 列表 + insertOrderedList: () => void; + insertUnorderedList: () => void; + toggleOrderedList: () => void; + toggleUnorderedList: () => void; + + // 链接和媒体 + insertLink: (url: string, text?: string) => void; + insertImage: (url: string, alt?: string) => void; + + // 表格 + insertTable: (rows?: number, cols?: number) => void; + + // 缩进 + indent: () => void; + outdent: () => void; + + // 状态查询 + isBold: () => boolean; + isItalic: () => boolean; + isHeading: (level?: number) => boolean; + isBlockquote: () => boolean; + isCodeBlock: () => boolean; + isOrderedList: () => boolean; + isUnorderedList: () => boolean; } export type Editor = EditorView & ExtendEditor; @@ -72,6 +116,8 @@ export interface CodeMirrorEditor extends Editor { moduleType; } +// @deprecated 已废弃,请直接使用 Editor 接口 +// 保留此接口仅用于向后兼容,新代码不应使用 export interface IEditorContext { editor: Editor; wrapText?; diff --git a/ui/src/components/Editor/utils/codemirror/adapter.ts b/ui/src/components/Editor/utils/codemirror/adapter.ts new file mode 100644 index 000000000..7e3f681ba --- /dev/null +++ b/ui/src/components/Editor/utils/codemirror/adapter.ts @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Editor, ExtendEditor } from '../../types'; + +import { createBaseMethods } from './base'; +import { createEventMethods } from './events'; +import { createCommandMethods } from './commands'; + +/** + * Adapts CodeMirror editor to unified editor interface + * + * This adapter function extends CodeMirror editor with additional methods, + * enabling toolbar components to work properly in Markdown mode. The adapter + * implements the complete `ExtendEditor` interface, including base methods, + * event handling, and command methods. + * + * @param editor - CodeMirror editor instance + * @returns Extended editor instance that implements the unified Editor interface + * + * @example + * ```typescript + * const cmEditor = new EditorView({ ... }); + * const adaptedEditor = createCodeMirrorAdapter(cmEditor as Editor); + * // Now you can use the unified API + * adaptedEditor.insertBold('text'); + * adaptedEditor.insertHeading(1, 'Title'); + * ``` + */ +export function createCodeMirrorAdapter(editor: Editor): Editor { + const baseMethods = createBaseMethods(editor); + const eventMethods = createEventMethods(editor); + const commandMethods = createCommandMethods(editor); + + const editorAdapter: ExtendEditor = { + ...editor, + ...baseMethods, + ...eventMethods, + ...commandMethods, + }; + + return editorAdapter as unknown as Editor; +} diff --git a/ui/src/components/Editor/utils/codemirror/base.ts b/ui/src/components/Editor/utils/codemirror/base.ts new file mode 100644 index 000000000..4a257f043 --- /dev/null +++ b/ui/src/components/Editor/utils/codemirror/base.ts @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { EditorSelection, StateEffect } from '@codemirror/state'; +import { keymap, KeyBinding, Command } from '@codemirror/view'; + +import { Editor, Position } from '../../types'; + +/** + * Creates base methods module + * + * Provides core base methods for the editor, including: + * - Content getter and setter (getValue, setValue) + * - Selection operations (getSelection, replaceSelection) + * - Cursor and selection position (getCursor, setSelection) + * - Focus and keyboard mapping (focus, addKeyMap) + * + * @param editor - CodeMirror editor instance + * @returns Object containing base methods + */ +export function createBaseMethods(editor: Editor) { + return { + focus: () => { + editor.contentDOM.focus(); + }, + + getCursor: () => { + const range = editor.state.selection.ranges[0]; + const line = editor.state.doc.lineAt(range.from).number; + const { from, to } = editor.state.doc.line(line); + return { from, to, ch: range.from - from, line }; + }, + + addKeyMap: (keyMap: Record) => { + const array = Object.entries(keyMap).map(([key, value]) => { + const keyBinding: KeyBinding = { + key, + preventDefault: true, + run: value, + }; + return keyBinding; + }); + + editor.dispatch({ + effects: StateEffect.appendConfig.of(keymap.of(array)), + }); + }, + + getSelection: () => { + return editor.state.sliceDoc( + editor.state.selection.main.from, + editor.state.selection.main.to, + ); + }, + + replaceSelection: (value: string) => { + editor.dispatch({ + changes: [ + { + from: editor.state.selection.main.from, + to: editor.state.selection.main.to, + insert: value, + }, + ], + selection: EditorSelection.cursor( + editor.state.selection.main.from + value.length, + ), + }); + }, + + setSelection: (anchor: Position, head?: Position) => { + editor.dispatch({ + selection: EditorSelection.create([ + EditorSelection.range( + editor.state.doc.line(anchor.line).from + anchor.ch, + head + ? editor.state.doc.line(head.line).from + head.ch + : editor.state.doc.line(anchor.line).from + anchor.ch, + ), + ]), + }); + }, + + getValue: () => { + return editor.state.doc.toString(); + }, + + setValue: (value: string) => { + editor.dispatch({ + changes: { from: 0, to: editor.state.doc.length, insert: value }, + }); + }, + }; +} diff --git a/ui/src/components/Editor/utils/codemirror/commands.ts b/ui/src/components/Editor/utils/codemirror/commands.ts new file mode 100644 index 000000000..59ab064ec --- /dev/null +++ b/ui/src/components/Editor/utils/codemirror/commands.ts @@ -0,0 +1,264 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { EditorSelection } from '@codemirror/state'; + +import { Editor, Level } from '../../types'; + +/** + * Creates command methods module + * + * Provides semantic command methods and low-level text manipulation methods: + * - Semantic methods: insertBold, insertHeading, insertImage, etc. (for toolbar use) + * - Low-level methods: wrapText, replaceLines, appendBlock (for internal use) + * - State query methods: isBold, isHeading, etc. + * + * @param editor - CodeMirror editor instance + * @returns Object containing all command methods + */ +export function createCommandMethods(editor: Editor) { + return { + wrapText: (before: string, after = before, defaultText) => { + const range = editor.state.selection.ranges[0]; + const selectedText = editor.state.sliceDoc(range.from, range.to); + const text = selectedText || defaultText || ''; + const wrappedText = before + text + after; + const insertFrom = range.from; + const insertTo = range.to; + + editor.dispatch({ + changes: [ + { + from: insertFrom, + to: insertTo, + insert: wrappedText, + }, + ], + selection: selectedText + ? EditorSelection.cursor(insertFrom + before.length + text.length) + : EditorSelection.range( + insertFrom + before.length, + insertFrom + before.length + text.length, + ), + }); + }, + + replaceLines: (replace: Parameters['map']>[0]) => { + const { doc } = editor.state; + const lines: string[] = []; + for (let i = 1; i <= doc.lines; i += 1) { + lines.push(doc.line(i).text); + } + + const newLines = lines.map(replace) as string[]; + const newText = newLines.join('\n'); + editor.setValue(newText); + }, + + appendBlock: (content: string) => { + const { doc } = editor.state; + const currentText = doc.toString(); + const newText = currentText ? `${currentText}\n\n${content}` : content; + editor.setValue(newText); + }, + + insertBold: (text?: string) => { + editor.wrapText('**', '**', text || 'bold text'); + }, + + insertItalic: (text?: string) => { + editor.wrapText('*', '*', text || 'italic text'); + }, + + insertCode: (text?: string) => { + editor.wrapText('`', '`', text || 'code'); + }, + + insertStrikethrough: (text?: string) => { + editor.wrapText('~~', '~~', text || 'strikethrough text'); + }, + + insertHeading: (level: Level, text?: string) => { + const headingText = '#'.repeat(level); + editor.wrapText(`${headingText} `, '', text || 'heading'); + }, + + insertBlockquote: (text?: string) => { + editor.wrapText('> ', '', text || 'quote'); + }, + + insertCodeBlock: (language?: string, code?: string) => { + const lang = language || ''; + const codeText = code || ''; + const block = `\`\`\`${lang}\n${codeText}\n\`\`\``; + editor.appendBlock(block); + }, + + insertHorizontalRule: () => { + editor.appendBlock('---'); + }, + + insertOrderedList: () => { + const cursor = editor.getCursor(); + const line = editor.state.doc.line(cursor.line); + const lineText = line.text.trim(); + if (/^\d+\.\s/.test(lineText)) { + return; + } + editor.replaceLines((lineItem) => { + if (lineItem.trim() === '') { + return lineItem; + } + return `1. ${lineItem}`; + }); + }, + + insertUnorderedList: () => { + const cursor = editor.getCursor(); + const line = editor.state.doc.line(cursor.line); + const lineText = line.text.trim(); + if (/^[-*+]\s/.test(lineText)) { + return; + } + editor.replaceLines((lineItem) => { + if (lineItem.trim() === '') { + return lineItem; + } + return `- ${lineItem}`; + }); + }, + + toggleOrderedList: () => { + const cursor = editor.getCursor(); + const line = editor.state.doc.line(cursor.line); + const lineText = line.text.trim(); + if (/^\d+\.\s/.test(lineText)) { + editor.replaceLines((lineItem) => { + return lineItem.replace(/^\d+\.\s/, ''); + }); + } else { + editor.insertOrderedList(); + } + }, + + toggleUnorderedList: () => { + const cursor = editor.getCursor(); + const line = editor.state.doc.line(cursor.line); + const lineText = line.text.trim(); + if (/^[-*+]\s/.test(lineText)) { + editor.replaceLines((lineItem) => { + return lineItem.replace(/^[-*+]\s/, ''); + }); + } else { + editor.insertUnorderedList(); + } + }, + + insertLink: (url: string, text?: string) => { + const linkText = text || url; + editor.wrapText('[', `](${url})`, linkText); + }, + + insertImage: (url: string, alt?: string) => { + const altText = alt || ''; + editor.wrapText('![', `](${url})`, altText); + }, + + insertTable: (rows = 3, cols = 3) => { + const table: string[] = []; + for (let i = 0; i < rows; i += 1) { + const row: string[] = []; + for (let j = 0; j < cols; j += 1) { + row.push(i === 0 ? 'Header' : 'Cell'); + } + table.push(`| ${row.join(' | ')} |`); + if (i === 0) { + table.push(`| ${'---'.repeat(cols).split('').join(' | ')} |`); + } + } + editor.appendBlock(table.join('\n')); + }, + + indent: () => { + editor.replaceLines((line) => { + if (line.trim() === '') { + return line; + } + return ` ${line}`; + }); + }, + + outdent: () => { + editor.replaceLines((line) => { + if (line.trim() === '') { + return line; + } + return line.replace(/^ {2}/, ''); + }); + }, + + isBold: () => { + const selection = editor.getSelection(); + return /^\*\*.*\*\*$/.test(selection) || /^__.*__$/.test(selection); + }, + + isItalic: () => { + const selection = editor.getSelection(); + return /^\*.*\*$/.test(selection) || /^_.*_$/.test(selection); + }, + + isHeading: (level?: number) => { + const cursor = editor.getCursor(); + const line = editor.state.doc.line(cursor.line); + const lineText = line.text.trim(); + if (level) { + return new RegExp(`^#{${level}}\\s`).test(lineText); + } + return /^#{1,6}\s/.test(lineText); + }, + + isBlockquote: () => { + const cursor = editor.getCursor(); + const line = editor.state.doc.line(cursor.line); + const lineText = line.text.trim(); + return /^>\s/.test(lineText); + }, + + isCodeBlock: () => { + const cursor = editor.getCursor(); + const line = editor.state.doc.line(cursor.line); + const lineText = line.text.trim(); + return /^```/.test(lineText); + }, + + isOrderedList: () => { + const cursor = editor.getCursor(); + const line = editor.state.doc.line(cursor.line); + const lineText = line.text.trim(); + return /^\d+\.\s/.test(lineText); + }, + + isUnorderedList: () => { + const cursor = editor.getCursor(); + const line = editor.state.doc.line(cursor.line); + const lineText = line.text.trim(); + return /^[-*+]\s/.test(lineText); + }, + }; +} diff --git a/ui/src/components/Editor/utils/codemirror/events.ts b/ui/src/components/Editor/utils/codemirror/events.ts new file mode 100644 index 000000000..dea832c64 --- /dev/null +++ b/ui/src/components/Editor/utils/codemirror/events.ts @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { StateEffect } from '@codemirror/state'; +import { EditorView } from '@codemirror/view'; + +import { Editor } from '../../types'; + +/** + * Creates event methods module + * + * Provides event listener registration and removal for the editor. + * Handles various DOM events including focus, blur, drag, drop, and paste. + * + * @param editor - CodeMirror editor instance + * @returns Object containing event methods (on, off) + */ +export function createEventMethods(editor: Editor) { + return { + on: (event, callback) => { + if (event === 'change') { + const change = EditorView.updateListener.of((update) => { + if (update.docChanged) { + callback(); + } + }); + + editor.dispatch({ + effects: StateEffect.appendConfig.of(change), + }); + } + if (event === 'focus') { + editor.contentDOM.addEventListener('focus', callback); + } + if (event === 'blur') { + editor.contentDOM.addEventListener('blur', callback); + } + + if (event === 'dragenter') { + editor.contentDOM.addEventListener('dragenter', callback); + } + + if (event === 'dragover') { + editor.contentDOM.addEventListener('dragover', callback); + } + + if (event === 'drop') { + editor.contentDOM.addEventListener('drop', callback); + } + + if (event === 'paste') { + editor.contentDOM.addEventListener('paste', callback); + } + }, + + off: (event, callback) => { + if (event === 'focus') { + editor.contentDOM.removeEventListener('focus', callback); + } + + if (event === 'blur') { + editor.contentDOM.removeEventListener('blur', callback); + } + + if (event === 'dragenter') { + editor.contentDOM.removeEventListener('dragenter', callback); + } + + if (event === 'dragover') { + editor.contentDOM.removeEventListener('dragover', callback); + } + + if (event === 'drop') { + editor.contentDOM.removeEventListener('drop', callback); + } + + if (event === 'paste') { + editor.contentDOM.removeEventListener('paste', callback); + } + }, + }; +} diff --git a/ui/src/components/Editor/utils/extension.ts b/ui/src/components/Editor/utils/extension.ts deleted file mode 100644 index 4118fed46..000000000 --- a/ui/src/components/Editor/utils/extension.ts +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { EditorSelection, StateEffect } from '@codemirror/state'; -import { EditorView, keymap, KeyBinding } from '@codemirror/view'; - -import { Editor, Position } from '../types'; - -const createEditorUtils = (editor: Editor) => { - editor.focus = () => { - editor.contentDOM.focus(); - }; - - editor.getCursor = () => { - const range = editor.state.selection.ranges[0]; - const line = editor.state.doc.lineAt(range.from).number; - const { from, to } = editor.state.doc.line(line); - return { from, to, ch: range.from - from, line }; - }; - - editor.addKeyMap = (keyMap) => { - const array = Object.entries(keyMap).map(([key, value]) => { - const keyBinding: KeyBinding = { - key, - preventDefault: true, - run: value, - }; - return keyBinding; - }); - - editor.dispatch({ - effects: StateEffect.appendConfig.of(keymap.of(array)), - }); - }; - - editor.getSelection = () => { - return editor.state.sliceDoc( - editor.state.selection.main.from, - editor.state.selection.main.to, - ); - }; - - editor.replaceSelection = (value: string) => { - editor.dispatch({ - changes: [ - { - from: editor.state.selection.main.from, - to: editor.state.selection.main.to, - insert: value, - }, - ], - selection: EditorSelection.cursor( - editor.state.selection.main.from + value.length, - ), - }); - }; - - editor.setSelection = (anchor: Position, head?: Position) => { - editor.dispatch({ - selection: EditorSelection.create([ - EditorSelection.range( - editor.state.doc.line(anchor.line).from + anchor.ch, - head - ? editor.state.doc.line(head.line).from + head.ch - : editor.state.doc.line(anchor.line).from + anchor.ch, - ), - ]), - }); - }; - - editor.on = (event, callback) => { - if (event === 'change') { - const change = EditorView.updateListener.of((update) => { - if (update.docChanged) { - callback(); - } - }); - - editor.dispatch({ - effects: StateEffect.appendConfig.of(change), - }); - } - if (event === 'focus') { - editor.contentDOM.addEventListener('focus', callback); - } - if (event === 'blur') { - editor.contentDOM.addEventListener('blur', callback); - } - - if (event === 'dragenter') { - editor.contentDOM.addEventListener('dragenter', callback); - } - - if (event === 'dragover') { - editor.contentDOM.addEventListener('dragover', callback); - } - - if (event === 'drop') { - editor.contentDOM.addEventListener('drop', callback); - } - - if (event === 'paste') { - editor.contentDOM.addEventListener('paste', callback); - } - }; - - editor.off = (event, callback) => { - if (event === 'focus') { - editor.contentDOM.removeEventListener('focus', callback); - } - - if (event === 'blur') { - editor.contentDOM.removeEventListener('blur', callback); - } - - if (event === 'dragenter') { - editor.contentDOM.removeEventListener('dragenter', callback); - } - - if (event === 'dragover') { - editor.contentDOM.removeEventListener('dragover', callback); - } - - if (event === 'drop') { - editor.contentDOM.removeEventListener('drop', callback); - } - - if (event === 'paste') { - editor.contentDOM.removeEventListener('paste', callback); - } - }; - - editor.getValue = () => { - return editor.state.doc.toString(); - }; - - editor.setValue = (value: string) => { - editor.dispatch({ - changes: { from: 0, to: editor.state.doc.length, insert: value }, - }); - }; - - editor.wrapText = (before: string, after = before, defaultText) => { - const range = editor.state.selection.ranges[0]; - const selection = editor.state.sliceDoc(range.from, range.to); - const text = `${before}${selection || defaultText}${after}`; - - editor.dispatch({ - changes: [ - { - from: range.from, - to: range.to, - insert: text, - }, - ], - selection: EditorSelection.range( - range.from + before.length, - range.to + before.length, - ), - }); - }; - - editor.replaceLines = ( - replace: Parameters['map']>[0], - symbolLen = 0, - ) => { - const range = editor.state.selection.ranges[0]; - const line = editor.state.doc.lineAt(range.from).number; - const { from, to } = editor.state.doc.line(line); - const lines = editor.state.sliceDoc(from, to).split('\n'); - - const insert = lines.map(replace).join('\n'); - const selectionStart = from; - const selectionEnd = from + insert.length; - - editor.dispatch({ - changes: [ - { - from, - to, - insert, - }, - ], - selection: EditorSelection.create([ - EditorSelection.range(selectionStart + symbolLen, selectionEnd), - ]), - }); - }; - - editor.appendBlock = (content: string) => { - const range = editor.state.selection.ranges[0]; - const line = editor.state.doc.lineAt(range.from).number; - const { from, to } = editor.state.doc.line(line); - - let insert = `\n\n${content}`; - - let selection = EditorSelection.single(to, to + content.length); - if (from === to) { - insert = `${content}\n`; - selection = EditorSelection.create([ - EditorSelection.cursor(to + content.length), - ]); - } - - editor.dispatch({ - changes: [ - { - from: to, - insert, - }, - ], - selection, - }); - }; - - editor.replaceRange = ( - value: string, - selectionStart: Position, - selectionEnd: Position, - ) => { - const from = - editor.state.doc.line(selectionStart.line).from + selectionStart.ch; - const to = editor.state.doc.line(selectionEnd.line).from + selectionEnd.ch; - editor.dispatch({ - changes: [ - { - from, - to, - insert: value, - }, - ], - selection: EditorSelection.cursor(from + value.length), - }); - }; - - return editor; -}; - -export default createEditorUtils; diff --git a/ui/src/components/Editor/utils/index.ts b/ui/src/components/Editor/utils/index.ts index 61e95fbb8..938b37613 100644 --- a/ui/src/components/Editor/utils/index.ts +++ b/ui/src/components/Editor/utils/index.ts @@ -30,7 +30,7 @@ import Tooltip from 'bootstrap/js/dist/tooltip'; import { Editor } from '../types'; import { isDarkTheme } from '@/utils/common'; -import createEditorUtils from './extension'; +import { createCodeMirrorAdapter } from './codemirror/adapter'; const editableCompartment = new Compartment(); interface htmlRenderConfig { @@ -190,7 +190,7 @@ export const useEditor = ({ state: startState, }); - const cm = createEditorUtils(view as Editor); + const cm = createCodeMirrorAdapter(view as Editor); cm.setReadOnly = (readOnly: boolean) => { cm.dispatch({ diff --git a/ui/src/components/Editor/utils/tiptap/adapter.ts b/ui/src/components/Editor/utils/tiptap/adapter.ts new file mode 100644 index 000000000..862cbf6c2 --- /dev/null +++ b/ui/src/components/Editor/utils/tiptap/adapter.ts @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Editor as TipTapEditor } from '@tiptap/react'; + +import { Editor, ExtendEditor } from '../../types'; + +import { createBaseMethods } from './base'; +import { createEventMethods } from './events'; +import { createCommandMethods } from './commands'; + +/** + * Adapts TipTap editor to CodeMirror editor interface + * + * This adapter function converts TipTap editor's API to a CodeMirror-compatible interface, + * enabling toolbar components to work properly in WYSIWYG mode. The adapter implements + * the complete `ExtendEditor` interface, including base methods, event handling, and command methods. + * + * @param editor - TipTap editor instance + * @returns Adapted editor instance that implements the unified Editor interface + * + * @example + * ```typescript + * const tipTapEditor = useEditor({ ... }); + * const adaptedEditor = createTipTapAdapter(tipTapEditor); + * // Now you can use the unified API + * adaptedEditor.insertBold('text'); + * adaptedEditor.insertHeading(1, 'Title'); + * ``` + */ +export function createTipTapAdapter(editor: TipTapEditor): Editor { + const baseMethods = createBaseMethods(editor); + const eventMethods = createEventMethods(editor); + const commandMethods = createCommandMethods(editor); + + const editorAdapter: ExtendEditor = { + ...baseMethods, + ...eventMethods, + ...commandMethods, + }; + + return editorAdapter as unknown as Editor; +} diff --git a/ui/src/components/Editor/utils/tiptap/base.ts b/ui/src/components/Editor/utils/tiptap/base.ts new file mode 100644 index 000000000..e088a9f5d --- /dev/null +++ b/ui/src/components/Editor/utils/tiptap/base.ts @@ -0,0 +1,358 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Editor as TipTapEditor } from '@tiptap/react'; + +import { Position } from '../../types'; + +import { + safeExecuteCommand, + EditorErrorType, + handleEditorError, +} from './errorHandler'; +import { + convertTipTapPositionToCodeMirror, + convertCodeMirrorPositionToTipTap, +} from './position'; +import { MARKDOWN_PATTERNS } from './constants'; + +/** + * Creates base methods module + * + * Provides core base methods for the editor, including: + * - Content getter and setter (getValue, setValue) + * - Selection operations (getSelection, replaceSelection) + * - Cursor and selection position (getCursor, setSelection) + * - Read-only state control (setReadOnly) + * + * @param editor - TipTap editor instance + * @returns Object containing base methods + */ +export function createBaseMethods(editor: TipTapEditor) { + return { + getValue: () => { + return ( + safeExecuteCommand( + () => editor.getMarkdown(), + () => '', + EditorErrorType.COMMAND_EXECUTION_FAILED, + { function: 'getValue' }, + ) || '' + ); + }, + + setValue: (value: string) => { + safeExecuteCommand( + () => { + editor.commands.setContent(value, { contentType: 'markdown' }); + }, + undefined, + EditorErrorType.COMMAND_EXECUTION_FAILED, + { function: 'setValue', valueLength: value.length }, + ); + }, + + getSelection: () => { + const { from, to } = editor.state.selection; + return editor.state.doc.textBetween(from, to); + }, + + replaceSelection: (value: string) => { + const inlineCodeMatch = value.match(MARKDOWN_PATTERNS.INLINE_CODE); + if (inlineCodeMatch && value.length > 2) { + const codeText = inlineCodeMatch[1]; + safeExecuteCommand( + () => { + editor.commands.insertContent({ + type: 'text', + text: codeText, + marks: [{ type: 'code' }], + }); + }, + () => { + editor.commands.insertContent(value, { contentType: 'markdown' }); + }, + ); + return; + } + + const codeBlockMatch = value.match(MARKDOWN_PATTERNS.CODE_BLOCK); + if (codeBlockMatch) { + const [, , lang, codeText] = codeBlockMatch; + safeExecuteCommand( + () => { + editor.commands.insertContent({ + type: 'codeBlock', + attrs: lang ? { language: lang } : {}, + content: [ + { + type: 'text', + text: codeText, + }, + ], + }); + }, + () => { + editor.commands.insertContent(value, { contentType: 'markdown' }); + }, + ); + return; + } + + const imageMatch = value.match(MARKDOWN_PATTERNS.IMAGE); + if (imageMatch) { + const [, alt, url] = imageMatch; + safeExecuteCommand( + () => { + editor.commands.insertContent({ + type: 'image', + attrs: { + src: url, + alt: alt || '', + }, + }); + }, + () => { + editor.commands.insertContent(value, { contentType: 'markdown' }); + }, + ); + return; + } + + const linkMatch = value.match(MARKDOWN_PATTERNS.LINK); + if (linkMatch) { + const [, text, url] = linkMatch; + safeExecuteCommand( + () => { + editor.commands.insertContent({ + type: 'text', + text: text || url, + marks: [ + { + type: 'link', + attrs: { + href: url, + }, + }, + ], + }); + }, + () => { + editor.commands.insertContent(value, { contentType: 'markdown' }); + }, + ); + return; + } + + const autoLinkMatch = value.match(MARKDOWN_PATTERNS.AUTO_LINK); + if (autoLinkMatch && value.length > 2) { + const url = autoLinkMatch[1]; + safeExecuteCommand( + () => { + editor.commands.insertContent({ + type: 'text', + text: url, + marks: [ + { + type: 'link', + attrs: { + href: url, + }, + }, + ], + }); + }, + () => { + editor.commands.insertContent(value, { contentType: 'markdown' }); + }, + ); + return; + } + + if (MARKDOWN_PATTERNS.HORIZONTAL_RULE.test(value.trim())) { + safeExecuteCommand( + () => { + editor.commands.insertContent({ + type: 'horizontalRule', + }); + }, + () => { + editor.commands.insertContent(value, { contentType: 'markdown' }); + }, + ); + return; + } + + safeExecuteCommand(() => { + editor.commands.insertContent(value, { contentType: 'markdown' }); + }); + }, + + focus: () => { + editor.commands.focus(); + }, + + getCursor: () => { + try { + const { from } = editor.state.selection; + return convertTipTapPositionToCodeMirror(editor, from); + } catch (error) { + handleEditorError( + error as Error, + EditorErrorType.POSITION_CONVERSION_FAILED, + { + function: 'getCursor', + }, + ); + return { line: 0, ch: 0 }; + } + }, + + setSelection: (anchor?: unknown, head?: unknown) => { + try { + if ( + anchor && + typeof anchor === 'object' && + 'line' in anchor && + 'ch' in anchor + ) { + const anchorPos = convertCodeMirrorPositionToTipTap( + editor, + anchor as Position, + ); + let headPos = anchorPos; + + if ( + head && + typeof head === 'object' && + 'line' in head && + 'ch' in head + ) { + headPos = convertCodeMirrorPositionToTipTap( + editor, + head as Position, + ); + } + + safeExecuteCommand( + () => { + editor.commands.setTextSelection({ + from: anchorPos, + to: headPos, + }); + }, + undefined, + EditorErrorType.COMMAND_EXECUTION_FAILED, + { function: 'setSelection', anchorPos, headPos }, + ); + } else { + editor.commands.focus(); + } + } catch (error) { + handleEditorError( + error as Error, + EditorErrorType.COMMAND_EXECUTION_FAILED, + { + function: 'setSelection', + anchor, + head, + }, + ); + safeExecuteCommand( + () => { + editor.commands.focus(); + }, + undefined, + EditorErrorType.COMMAND_EXECUTION_FAILED, + { function: 'setSelection', isFallback: true }, + ); + } + }, + + setReadOnly: (readOnly: boolean) => { + editor.setEditable(!readOnly); + }, + + replaceRange: (value: string, from?: unknown, to?: unknown) => { + if (from && to && typeof from === 'object' && typeof to === 'object') { + const { from: currentFrom, to: currentTo } = editor.state.selection; + const imageMatch = value.match(MARKDOWN_PATTERNS.IMAGE); + if (imageMatch) { + const [, alt, url] = imageMatch; + safeExecuteCommand( + () => { + editor.commands.insertContentAt( + { from: currentFrom, to: currentTo }, + { + type: 'image', + attrs: { + src: url, + alt: alt || '', + }, + }, + ); + }, + () => { + editor.commands.insertContentAt( + { from: currentFrom, to: currentTo }, + value, + { contentType: 'markdown' }, + ); + }, + ); + return; + } + + safeExecuteCommand(() => { + editor.commands.insertContentAt( + { from: currentFrom, to: currentTo }, + value, + { contentType: 'markdown' }, + ); + }); + } else { + const imageMatch = value.match(MARKDOWN_PATTERNS.IMAGE); + if (imageMatch) { + const [, alt, url] = imageMatch; + safeExecuteCommand( + () => { + editor.commands.insertContent({ + type: 'image', + attrs: { + src: url, + alt: alt || '', + }, + }); + }, + () => { + editor.commands.insertContent(value, { + contentType: 'markdown', + }); + }, + ); + return; + } + + safeExecuteCommand(() => { + editor.commands.insertContent(value, { contentType: 'markdown' }); + }); + } + }, + }; +} diff --git a/ui/src/components/Editor/utils/tiptap/commands.ts b/ui/src/components/Editor/utils/tiptap/commands.ts new file mode 100644 index 000000000..ee32a4a3b --- /dev/null +++ b/ui/src/components/Editor/utils/tiptap/commands.ts @@ -0,0 +1,718 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Editor as TipTapEditor } from '@tiptap/react'; +import { Command } from '@codemirror/view'; + +import { Level } from '../../types'; + +import { safeExecuteCommand, logWarning } from './errorHandler'; +import { MARKDOWN_PATTERNS } from './constants'; + +/** + * Creates command methods module + * + * Provides command methods for the editor, including: + * - Low-level methods: wrapText, replaceLines, appendBlock (for internal editor use) + * - Semantic methods: insertBold, insertHeading, insertImage, etc. (for toolbar use) + * - State query methods: isBold, isHeading, etc. + * + * @param editor - TipTap editor instance + * @returns Object containing all command methods + */ +export function createCommandMethods(editor: TipTapEditor) { + return { + wrapText: (before: string, after?: string, defaultText?: string) => { + const { from, to } = editor.state.selection; + const actualAfter = after || before; + + if (before === '**' && actualAfter === '**') { + if (from === to) { + if (defaultText) { + const insertPos = from; + editor.commands.insertContent(defaultText); + editor.commands.setTextSelection({ + from: insertPos, + to: insertPos + defaultText.length, + }); + editor.commands.toggleBold(); + } else { + editor.commands.toggleBold(); + } + } else { + editor.commands.toggleBold(); + } + return; + } + + if (before === '*' && actualAfter === '*') { + if (from === to) { + if (defaultText) { + const insertPos = from; + editor.commands.insertContent(defaultText); + editor.commands.setTextSelection({ + from: insertPos, + to: insertPos + defaultText.length, + }); + editor.commands.toggleItalic(); + } else { + editor.commands.toggleItalic(); + } + } else { + editor.commands.toggleItalic(); + } + return; + } + + if (before === '`' && actualAfter === '`') { + if (from === to) { + if (defaultText) { + const insertPos = from; + editor.commands.insertContent(defaultText); + editor.commands.setTextSelection({ + from: insertPos, + to: insertPos + defaultText.length, + }); + editor.commands.toggleCode(); + } else { + editor.commands.toggleCode(); + } + } else { + editor.commands.toggleCode(); + } + return; + } + + if (before === '```\n' && actualAfter === '\n```') { + if (from === to) { + const codeBlockText = defaultText + ? `\`\`\`\n${defaultText}\n\`\`\`` + : '```\n\n```'; + safeExecuteCommand( + () => { + editor.commands.insertContent(codeBlockText, { + contentType: 'markdown', + }); + }, + () => { + editor.commands.insertContent({ + type: 'codeBlock', + content: defaultText + ? [ + { + type: 'text', + text: defaultText, + }, + ] + : [], + }); + }, + ); + } else { + const selectedText = editor.state.doc.textBetween(from, to); + safeExecuteCommand( + () => { + editor.commands.insertContentAt( + { from, to }, + { + type: 'codeBlock', + content: [ + { + type: 'text', + text: selectedText, + }, + ], + }, + ); + }, + () => { + const codeBlockText = `\`\`\`\n${selectedText}\n\`\`\``; + editor.commands.insertContentAt({ from, to }, codeBlockText, { + contentType: 'markdown', + }); + }, + ); + } + return; + } + + if (from === to) { + const text = before + (defaultText || '') + actualAfter; + editor.commands.insertContent(text, { contentType: 'markdown' }); + } else { + const selectedText = editor.state.doc.textBetween(from, to); + const wrappedText = before + selectedText + actualAfter; + editor.commands.insertContentAt({ from, to }, wrappedText, { + contentType: 'markdown', + }); + } + }, + + replaceLines: (replace: Parameters['map']>[0]) => { + const { from } = editor.state.selection; + const $pos = editor.state.doc.resolve(from); + const block = $pos.parent; + const lineText = block.textContent; + const newText = replace(lineText, 0, [lineText]) as string; + + const finalText = newText || ' '; + const headingMatch = finalText.match(MARKDOWN_PATTERNS.HEADING); + if (headingMatch) { + const [, hashes, text] = headingMatch; + const level = hashes.length; + const start = $pos.start($pos.depth); + const end = $pos.end($pos.depth); + + if (start < 0 || end < 0 || start > end) { + logWarning('Invalid position range for heading', { start, end }); + return; + } + + const headingText = text.trim() || 'Heading'; + safeExecuteCommand( + () => { + if (start === end) { + editor.commands.insertContent({ + type: 'heading', + attrs: { level }, + content: [ + { + type: 'text', + text: headingText, + }, + ], + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + { + type: 'heading', + attrs: { level }, + content: [ + { + type: 'text', + text: headingText, + }, + ], + }, + ); + } + }, + () => { + const markdownText = finalText.trim() || `# Heading`; + if (start === end) { + editor.commands.insertContent(markdownText, { + contentType: 'markdown', + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + markdownText, + { contentType: 'markdown' }, + ); + } + }, + ); + return; + } + + if (finalText.startsWith('> ')) { + const quoteText = finalText.slice(2).trim(); + const start = $pos.start($pos.depth); + const end = $pos.end($pos.depth); + + if (start < 0 || end < 0 || start > end) { + logWarning('Invalid position range for heading', { start, end }); + return; + } + + const quoteMarkdown = quoteText ? `> ${quoteText}` : '> '; + safeExecuteCommand( + () => { + if (start === end) { + editor.commands.insertContent(quoteMarkdown, { + contentType: 'markdown', + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + quoteMarkdown, + { contentType: 'markdown' }, + ); + } + }, + () => { + if (start === end) { + editor.commands.insertContent({ + type: 'paragraph', + content: quoteText ? [{ type: 'text', text: quoteText }] : [], + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + { + type: 'paragraph', + content: quoteText ? [{ type: 'text', text: quoteText }] : [], + }, + ); + } + }, + ); + return; + } + + const olMatchOriginal = lineText.match( + MARKDOWN_PATTERNS.ORDERED_LIST_ORIGINAL, + ); + const olMatchNew = finalText.match(MARKDOWN_PATTERNS.ORDERED_LIST_NEW); + + if (olMatchOriginal || olMatchNew) { + const isInOrderedList = editor.isActive('orderedList'); + const start = $pos.start($pos.depth); + const end = $pos.end($pos.depth); + + if (start < 0 || end < 0 || start > end) { + logWarning('Invalid position range for ordered list', { + start, + end, + }); + return; + } + + if (olMatchOriginal && !olMatchNew) { + const textContent = finalText.trim(); + const contentToInsert = textContent || 'Paragraph'; + + safeExecuteCommand( + () => { + if (start === end) { + editor.commands.insertContent(contentToInsert, { + contentType: 'markdown', + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + contentToInsert, + { contentType: 'markdown' }, + ); + } + }, + () => { + if (start === end) { + editor.commands.insertContent({ + type: 'paragraph', + content: [{ type: 'text', text: contentToInsert }], + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + { + type: 'paragraph', + content: [{ type: 'text', text: contentToInsert }], + }, + ); + } + }, + ); + if (isInOrderedList) { + safeExecuteCommand(() => { + editor.chain().focus().toggleOrderedList().run(); + }); + } + } else if (!olMatchOriginal && olMatchNew) { + const [, , text] = olMatchNew; + const textContent = text.trim(); + const contentToInsert = textContent || 'List item'; + + safeExecuteCommand( + () => { + if (start === end) { + editor.commands.insertContent(contentToInsert, { + contentType: 'markdown', + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + contentToInsert, + { contentType: 'markdown' }, + ); + } + }, + () => { + if (start === end) { + editor.commands.insertContent({ + type: 'paragraph', + content: [{ type: 'text', text: contentToInsert }], + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + { + type: 'paragraph', + content: [{ type: 'text', text: contentToInsert }], + }, + ); + } + }, + ); + if (!isInOrderedList) { + safeExecuteCommand(() => { + editor.chain().focus().toggleOrderedList().run(); + }); + } + } + return; + } + const ulMatchOriginal = lineText.match( + MARKDOWN_PATTERNS.UNORDERED_LIST_ORIGINAL, + ); + const ulMatchNew = finalText.match(MARKDOWN_PATTERNS.UNORDERED_LIST_NEW); + + if (ulMatchOriginal || ulMatchNew) { + const isInBulletList = editor.isActive('bulletList'); + const start = $pos.start($pos.depth); + const end = $pos.end($pos.depth); + + if (start < 0 || end < 0 || start > end) { + logWarning('Invalid position range for unordered list', { + start, + end, + }); + return; + } + + if (ulMatchOriginal && !ulMatchNew) { + const textContent = finalText.trim(); + const contentToInsert = textContent || 'Paragraph'; + + safeExecuteCommand( + () => { + if (start === end) { + editor.commands.insertContent(contentToInsert, { + contentType: 'markdown', + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + contentToInsert, + { contentType: 'markdown' }, + ); + } + }, + () => { + if (start === end) { + editor.commands.insertContent({ + type: 'paragraph', + content: [{ type: 'text', text: contentToInsert }], + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + { + type: 'paragraph', + content: [{ type: 'text', text: contentToInsert }], + }, + ); + } + }, + ); + if (isInBulletList) { + safeExecuteCommand(() => { + editor.chain().focus().toggleBulletList().run(); + }); + } + } else if (!ulMatchOriginal && ulMatchNew) { + const [, text] = ulMatchNew; + const textContent = text.trim(); + const contentToInsert = textContent || 'List item'; + + safeExecuteCommand( + () => { + if (start === end) { + editor.commands.insertContent(contentToInsert, { + contentType: 'markdown', + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + contentToInsert, + { contentType: 'markdown' }, + ); + } + }, + () => { + if (start === end) { + editor.commands.insertContent({ + type: 'paragraph', + content: [{ type: 'text', text: contentToInsert }], + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + { + type: 'paragraph', + content: [{ type: 'text', text: contentToInsert }], + }, + ); + } + }, + ); + if (!isInBulletList) { + safeExecuteCommand(() => { + editor.chain().focus().toggleBulletList().run(); + }); + } + } + return; + } + + const start = $pos.start($pos.depth); + const end = $pos.end($pos.depth); + + if (start < 0 || end < 0 || start > end) { + logWarning('Invalid position range', { + start, + end, + function: 'replaceLines', + }); + return; + } + + const contentToInsert = finalText.trim() || ' '; + + safeExecuteCommand( + () => { + if (start === end) { + editor.commands.insertContent(contentToInsert, { + contentType: 'markdown', + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + contentToInsert, + { contentType: 'markdown' }, + ); + } + }, + () => { + if (start === end) { + editor.commands.insertContent({ + type: 'paragraph', + content: [{ type: 'text', text: contentToInsert }], + }); + } else { + editor.commands.insertContentAt( + { from: start, to: end }, + { + type: 'paragraph', + content: [{ type: 'text', text: contentToInsert }], + }, + ); + } + }, + ); + }, + + appendBlock: (content: string) => { + if (MARKDOWN_PATTERNS.HORIZONTAL_RULE.test(content.trim())) { + safeExecuteCommand( + () => { + editor.commands.insertContent({ + type: 'horizontalRule', + }); + }, + () => { + editor.commands.insertContent(content, { + contentType: 'markdown', + }); + }, + ); + return; + } + + safeExecuteCommand(() => { + editor.commands.insertContent(`\n\n${content}`, { + contentType: 'markdown', + }); + }); + }, + + addKeyMap: (keyMap: Record) => { + Object.keys(keyMap).forEach(() => {}); + }, + insertBold: (text?: string) => { + if (text) { + const { from } = editor.state.selection; + editor.commands.insertContent(text); + editor.commands.setTextSelection({ from, to: from + text.length }); + } + editor.commands.toggleBold(); + }, + + insertItalic: (text?: string) => { + if (text) { + const { from } = editor.state.selection; + editor.commands.insertContent(text); + editor.commands.setTextSelection({ from, to: from + text.length }); + } + editor.commands.toggleItalic(); + }, + + insertCode: (text?: string) => { + if (text) { + const { from } = editor.state.selection; + editor.commands.insertContent(text); + editor.commands.setTextSelection({ from, to: from + text.length }); + } + editor.commands.toggleCode(); + }, + + insertStrikethrough: (text?: string) => { + if (text) { + const { from } = editor.state.selection; + editor.commands.insertContent(text); + editor.commands.setTextSelection({ from, to: from + text.length }); + } + editor.commands.toggleStrike(); + }, + + insertHeading: (level: Level, text?: string) => { + if (text) { + // Insert heading using TipTap's native API to ensure proper structure + safeExecuteCommand( + () => { + editor.commands.insertContent({ + type: 'heading', + attrs: { level }, + content: [ + { + type: 'text', + text, + }, + ], + }); + // Select only the text part (excluding the heading node structure) + // After insertion, the cursor is at the end of the heading + // We need to select backwards from the current position + const { to } = editor.state.selection; + editor.commands.setTextSelection({ + from: to - text.length, + to, + }); + }, + () => { + // Fallback: use markdown format + const headingText = `${'#'.repeat(level)} ${text}`; + editor.commands.insertContent(headingText, { + contentType: 'markdown', + }); + }, + ); + } else { + editor.commands.toggleHeading({ level }); + } + }, + + insertBlockquote: (text?: string) => { + if (text) { + const { from } = editor.state.selection; + const blockquoteText = `> ${text}`; + editor.commands.insertContent(blockquoteText, { + contentType: 'markdown', + }); + // Select the text part (excluding the '> ' marker) + const textStart = from + 2; // 2 for '> ' + editor.commands.setTextSelection({ + from: textStart, + to: textStart + text.length, + }); + } else { + editor.commands.toggleBlockquote(); + } + }, + + insertCodeBlock: (language?: string, code?: string) => { + const lang = language || ''; + const codeText = code || 'code here'; + editor.commands.insertContent(`\`\`\`${lang}\n${codeText}\n\`\`\``, { + contentType: 'markdown', + }); + }, + + insertHorizontalRule: () => { + editor.commands.setHorizontalRule(); + }, + + insertOrderedList: () => { + editor.commands.toggleOrderedList(); + }, + + insertUnorderedList: () => { + editor.commands.toggleBulletList(); + }, + + toggleOrderedList: () => { + editor.commands.toggleOrderedList(); + }, + + toggleUnorderedList: () => { + editor.commands.toggleBulletList(); + }, + + insertLink: (url: string, text?: string) => { + const linkText = text || url; + editor.commands.insertContent(`[${linkText}](${url})`, { + contentType: 'markdown', + }); + }, + + insertImage: (url: string, alt?: string) => { + editor.commands.setImage({ src: url, alt: alt || 'image' }); + }, + + insertTable: (rows = 3, cols = 3) => { + editor.commands.insertTable({ + rows, + cols, + withHeaderRow: true, + }); + }, + + indent: () => { + editor.commands.sinkListItem('listItem'); + }, + + outdent: () => { + editor.commands.liftListItem('listItem'); + }, + + isBold: () => editor.isActive('bold'), + isItalic: () => editor.isActive('italic'), + isHeading: (level?: number) => { + if (level) { + return editor.isActive('heading', { level }); + } + return editor.isActive('heading'); + }, + isBlockquote: () => editor.isActive('blockquote'), + isCodeBlock: () => editor.isActive('codeBlock'), + isOrderedList: () => editor.isActive('orderedList'), + isUnorderedList: () => editor.isActive('bulletList'), + }; +} diff --git a/ui/src/components/Editor/utils/tiptap/constants.ts b/ui/src/components/Editor/utils/tiptap/constants.ts new file mode 100644 index 000000000..a4ff7de42 --- /dev/null +++ b/ui/src/components/Editor/utils/tiptap/constants.ts @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Markdown pattern matching regular expression constants + * + * Defines regular expression patterns for parsing and matching Markdown syntax. + * These patterns are used to convert Markdown syntax to TipTap nodes, or from TipTap nodes + * to Markdown format. + * + * @example + * ```typescript + * const headingMatch = text.match(MARKDOWN_PATTERNS.HEADING); + * if (headingMatch) { + * const level = headingMatch[1].length; // Number of # + * const text = headingMatch[2]; // Heading text + * } + * ``` + */ +export const MARKDOWN_PATTERNS = { + HEADING: /^(#{1,6})\s+(.+)$/, + ORDERED_LIST_ORIGINAL: /^(\s{0,})(\d+)\.\s/, + ORDERED_LIST_NEW: /^(\d+)\.\s*(.*)$/, + UNORDERED_LIST_ORIGINAL: /^(\s{0,})(-|\*)\s/, + UNORDERED_LIST_NEW: /^[-*]\s*(.*)$/, + INLINE_CODE: /^`(.+?)`$/, + CODE_BLOCK: /^(\n)?```(\w+)?\n([\s\S]*?)\n```(\n)?$/, + IMAGE: /^!\[([^\]]*)\]\(([^)]+)\)$/, + LINK: /^\[([^\]]*)\]\(([^)]+)\)$/, + AUTO_LINK: /^<(.+?)>$/, + HORIZONTAL_RULE: /^-{3,}$/, +} as const; diff --git a/ui/src/components/Editor/utils/tiptap/errorHandler.ts b/ui/src/components/Editor/utils/tiptap/errorHandler.ts new file mode 100644 index 000000000..c8f4e7a3b --- /dev/null +++ b/ui/src/components/Editor/utils/tiptap/errorHandler.ts @@ -0,0 +1,155 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Editor error type enumeration + * + * Defines various error types that may occur in the editor, used for error classification and handling. + */ +export enum EditorErrorType { + COMMAND_EXECUTION_FAILED = 'COMMAND_EXECUTION_FAILED', + POSITION_CONVERSION_FAILED = 'POSITION_CONVERSION_FAILED', + CONTENT_PARSING_FAILED = 'CONTENT_PARSING_FAILED', + EVENT_LISTENER_FAILED = 'EVENT_LISTENER_FAILED', +} + +/** + * Editor error interface + */ +export interface EditorError { + type: EditorErrorType; + message: string; + originalError?: Error; + context?: Record; + timestamp: number; +} + +/** + * Handles editor errors with unified log format + * + * Unified error handling for the editor, recording error information, context, and stack traces + * for easier problem identification and debugging. + * + * @param error - Original error object + * @param type - Error type + * @param context - Optional context information (function name, parameters, etc.) + * @returns Processed error object + * + * @example + * ```typescript + * try { + * editor.commands.insertContent(content); + * } catch (error) { + * handleEditorError(error, EditorErrorType.COMMAND_EXECUTION_FAILED, { + * function: 'insertContent', + * content: content.substring(0, 50), + * }); + * } + * ``` + */ +export function handleEditorError( + error: Error, + type: EditorErrorType, + context?: Record, +): EditorError { + const editorError: EditorError = { + type, + message: error.message, + originalError: error, + context, + timestamp: Date.now(), + }; + + console.error(`[Editor Error] ${type}:`, { + message: editorError.message, + context: editorError.context, + stack: error.stack, + }); + + return editorError; +} + +/** + * Safely executes TipTap command with error handling and fallback strategy + * + * Automatically catches errors when executing TipTap commands. If a fallback function is provided, + * it attempts to execute the fallback operation when the main command fails. All errors are uniformly recorded. + * + * @param command - Main command function to execute + * @param fallback - Optional fallback function to execute when main command fails + * @param errorType - Error type, defaults to COMMAND_EXECUTION_FAILED + * @param context - Optional context information + * @returns Command execution result, returns undefined if failed and no fallback + * + * @example + * ```typescript + * const result = safeExecuteCommand( + * () => editor.commands.insertContent(content), + * () => editor.commands.insertContent(content, { contentType: 'markdown' }), + * EditorErrorType.COMMAND_EXECUTION_FAILED, + * { function: 'insertContent', contentLength: content.length } + * ); + * ``` + */ +export function safeExecuteCommand( + command: () => T, + fallback?: () => T, + errorType: EditorErrorType = EditorErrorType.COMMAND_EXECUTION_FAILED, + context?: Record, +): T | undefined { + try { + return command(); + } catch (error) { + handleEditorError(error as Error, errorType, context); + if (fallback) { + try { + return fallback(); + } catch (fallbackError) { + handleEditorError(fallbackError as Error, errorType, { + ...context, + isFallback: true, + }); + } + } + return undefined; + } +} + +/** + * Logs warning information (for non-fatal errors) + * + * Records non-fatal warning information to alert potential issues without affecting functionality. + * + * @param message - Warning message + * @param context - Optional context information + * + * @example + * ```typescript + * if (start < 0 || end < 0) { + * logWarning('Invalid position range', { start, end, function: 'setSelection' }); + * return; + * } + * ``` + */ +export function logWarning( + message: string, + context?: Record, +): void { + console.warn(`[Editor Warning] ${message}`, context || {}); +} diff --git a/ui/src/components/Editor/utils/tiptap/events.ts b/ui/src/components/Editor/utils/tiptap/events.ts new file mode 100644 index 000000000..495ee6e57 --- /dev/null +++ b/ui/src/components/Editor/utils/tiptap/events.ts @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Editor as TipTapEditor } from '@tiptap/react'; + +import { logWarning } from './errorHandler'; + +/** + * Checks if editor view is available + */ +function isViewAvailable(editor: TipTapEditor): boolean { + return !!(editor.view && editor.view.dom); +} + +/** + * Creates event handling methods module + * + * Provides event handling methods for the editor, including: + * - on: Register event listeners (change, focus, blur, dragenter, dragover, drop, paste) + * - off: Remove event listeners + * + * Note: For DOM events (dragenter, dragover, drop, paste), + * the editor view must be mounted before binding events. + * + * @param editor - TipTap editor instance + * @returns Object containing event handling methods + */ +export function createEventMethods(editor: TipTapEditor) { + return { + on: (event: string, callback: (e?: unknown) => void) => { + if (event === 'change') { + editor.on('update', callback); + } else if (event === 'focus') { + editor.on('focus', callback); + } else if (event === 'blur') { + editor.on('blur', callback); + } else if ( + event === 'dragenter' || + event === 'dragover' || + event === 'drop' || + event === 'paste' + ) { + if (!isViewAvailable(editor)) { + logWarning( + 'TipTap editor view is not available yet. Event listener not attached.', + { + event, + }, + ); + return; + } + editor.view.dom.addEventListener(event, callback as EventListener); + } + }, + + off: (event: string, callback: (e?: unknown) => void) => { + if ( + (event === 'dragenter' || + event === 'dragover' || + event === 'drop' || + event === 'paste') && + !isViewAvailable(editor) + ) { + return; + } + if (event === 'change') { + editor.off('update', callback); + } else if (event === 'focus') { + editor.off('focus', callback); + } else if (event === 'blur') { + editor.off('blur', callback); + } else if ( + event === 'dragenter' || + event === 'dragover' || + event === 'drop' || + event === 'paste' + ) { + editor.view.dom.removeEventListener(event, callback as EventListener); + } + }, + }; +} diff --git a/ui/src/components/Editor/utils/tiptap/position.ts b/ui/src/components/Editor/utils/tiptap/position.ts new file mode 100644 index 000000000..378908b88 --- /dev/null +++ b/ui/src/components/Editor/utils/tiptap/position.ts @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Editor as TipTapEditor } from '@tiptap/react'; + +import { Position } from '../../types'; + +import { handleEditorError, EditorErrorType } from './errorHandler'; + +/** + * Converts TipTap position to CodeMirror Position + * + * TipTap uses document tree-based node positions (character index), while CodeMirror uses + * line-based positions (line number and column number). This function converts between them. + * + * @param editor - TipTap editor instance + * @param pos - TipTap position index (character position) + * @returns CodeMirror position object with line and ch properties + * + * @example + * ```typescript + * const tipTapPos = 100; // Character position + * const codeMirrorPos = convertTipTapPositionToCodeMirror(editor, tipTapPos); + * // { line: 5, ch: 10 } + * ``` + */ +export function convertTipTapPositionToCodeMirror( + editor: TipTapEditor, + pos: number, +): Position { + try { + const { doc } = editor.state; + let line = 0; + let ch = 0; + let currentPos = 0; + + for (let i = 0; i < doc.content.childCount; i += 1) { + const child = doc.content.child(i); + const childSize = child.nodeSize; + + if (currentPos + childSize > pos) { + const text = child.textContent; + const relativePos = pos - currentPos; + + const textBeforePos = text.substring(0, relativePos); + const newlineMatches = textBeforePos.match(/\n/g); + line += newlineMatches ? newlineMatches.length : 0; + ch = relativePos - textBeforePos.lastIndexOf('\n') - 1; + break; + } + + const text = child.textContent; + const newlineMatches = text.match(/\n/g); + line += newlineMatches ? newlineMatches.length : 0; + currentPos += childSize; + } + + return { line, ch }; + } catch (error) { + handleEditorError( + error as Error, + EditorErrorType.POSITION_CONVERSION_FAILED, + { + function: 'convertTipTapPositionToCodeMirror', + position: pos, + }, + ); + return { line: 0, ch: 0 }; + } +} + +/** + * Converts CodeMirror Position to TipTap position index + * + * Converts CodeMirror's line-based position to TipTap's character index position. + * + * @param editor - TipTap editor instance + * @param position - CodeMirror position object with line and ch properties + * @returns TipTap position index (character position) + * + * @example + * ```typescript + * const codeMirrorPos = { line: 5, ch: 10 }; + * const tipTapPos = convertCodeMirrorPositionToTipTap(editor, codeMirrorPos); + * // 100 (character position) + * ``` + */ +export function convertCodeMirrorPositionToTipTap( + editor: TipTapEditor, + position: Position, +): number { + try { + const { doc } = editor.state; + let currentLine = 0; + let currentPos = 0; + + for (let i = 0; i < doc.content.childCount; i += 1) { + const child = doc.content.child(i); + const text = child.textContent; + const lines = text.split('\n'); + + if (currentLine + lines.length - 1 >= position.line) { + const lineInNode = position.line - currentLine; + const { ch: posInLine } = position; + + let pos = 0; + for (let j = 0; j < lineInNode; j += 1) { + pos += lines[j].length + 1; // +1 for newline + } + pos += posInLine; + + return currentPos + pos; + } + + currentLine += lines.length - 1; + currentPos += child.nodeSize; + } + + return doc.content.size; + } catch (error) { + handleEditorError( + error as Error, + EditorErrorType.POSITION_CONVERSION_FAILED, + { + function: 'convertCodeMirrorPositionToTipTap', + position, + }, + ); + return editor.state.doc.content.size; + } +} diff --git a/ui/src/pages/Questions/Detail/index.scss b/ui/src/pages/Questions/Detail/index.scss index a5726b6a5..da379ba91 100644 --- a/ui/src/pages/Questions/Detail/index.scss +++ b/ui/src/pages/Questions/Detail/index.scss @@ -47,11 +47,12 @@ [data-bs-theme='dark'] & { color: var(--bs-gray-400) !important; background-color: var(--bs-gray-800); - &:active, &.active { - background-color: #626E79 !important; + &:active, + &.active { + background-color: #626e79 !important; } &:hover { - background-color: #57616B !important; + background-color: #57616b !important; } } } @@ -78,4 +79,4 @@ font-size: calc(1.275rem + 0.3vw) !important; } } -} \ No newline at end of file +} From c2a62804b0dcf31048eeb145e569ce0605d007ea Mon Sep 17 00:00:00 2001 From: Gregorius Bima Kharisma Wicaksana <51526537+bimakw@users.noreply.github.com> Date: Tue, 16 Dec 2025 13:43:21 +0700 Subject: [PATCH 25/92] fix: add feedback after successfully adding a user in admin panel (#1462) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Show success toast notification after user is added - Refresh user list and navigate to 'normal' filter on page 1 to display the newly added user ## Problem When adding a user in Admin -> Users, the page had no feedback after submission (as reported in #1457). **Root cause:** The code only refreshed the user list if the current filter was "all" or "staff", but the default filter is "normal". Additionally, there was no success toast notification. ## Solution 1. Added toast notification to confirm successful user creation 2. After adding user, navigate to "normal" filter page 1 and refresh the list so the new user is visible ## Test plan 1. Go to Admin -> Users 2. Click "Add User" 3. Submit user information 4. ✅ Success toast should appear 5. ✅ Page should navigate to "normal" filter 6. ✅ Newly added user should be visible in the list Fixes #1457 --------- Co-authored-by: LinkinStars --- i18n/en_US.yaml | 1 + ui/src/pages/Admin/Users/index.tsx | 11 ++++++++--- ui/src/pages/SideNavLayout/index.tsx | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/i18n/en_US.yaml b/i18n/en_US.yaml index eac322dac..705db9c25 100644 --- a/i18n/en_US.yaml +++ b/i18n/en_US.yaml @@ -2383,6 +2383,7 @@ ui: user_normal: This user is already normal. user_suspended: This user has been suspended. user_deleted: This user has been deleted. + user_added: User has been added successfully. badge_activated: This badge has been activated. badge_inactivated: This badge has been inactivated. users_deleted: These users have been deleted. diff --git a/ui/src/pages/Admin/Users/index.tsx b/ui/src/pages/Admin/Users/index.tsx index 7e8e4fd61..220429007 100644 --- a/ui/src/pages/Admin/Users/index.tsx +++ b/ui/src/pages/Admin/Users/index.tsx @@ -109,9 +109,14 @@ const Users: FC = () => { return new Promise((resolve, reject) => { addUsers(userModel) .then(() => { - if (/all|staff/.test(curFilter) && curPage === 1) { - refreshUsers(); - } + toastStore.getState().show({ + msg: t('user_added', { keyPrefix: 'messages' }), + variant: 'success', + }); + urlSearchParams.set('filter', 'normal'); + urlSearchParams.delete('page'); + setUrlSearchParams(urlSearchParams); + refreshUsers(); resolve(true); }) .catch((e) => { diff --git a/ui/src/pages/SideNavLayout/index.tsx b/ui/src/pages/SideNavLayout/index.tsx index 907b9b281..b9bc38b9c 100644 --- a/ui/src/pages/SideNavLayout/index.tsx +++ b/ui/src/pages/SideNavLayout/index.tsx @@ -38,7 +38,7 @@ const Index: FC = () => { -
    +
    From 762773cedbcc44c91ce41e5375e40d63f9600b4f Mon Sep 17 00:00:00 2001 From: robin Date: Tue, 16 Dec 2025 14:50:19 +0800 Subject: [PATCH 26/92] chore: clean up pnpm-lock.yaml by removing unused dependencies and updating existing ones --- ui/pnpm-lock.yaml | 1058 +-------------------------------------------- 1 file changed, 8 insertions(+), 1050 deletions(-) diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index 901c503de..83c706312 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -23,24 +23,12 @@ importers: '@tiptap/extension-image': specifier: ^3.11.1 version: 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) - '@tiptap/extension-list': - specifier: ^3.11.1 - version: 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) '@tiptap/extension-placeholder': specifier: ^3.11.1 version: 3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) '@tiptap/extension-table': specifier: ^3.11.1 version: 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-table-cell': - specifier: ^3.11.1 - version: 3.11.1(@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) - '@tiptap/extension-table-header': - specifier: ^3.11.1 - version: 3.11.1(@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) - '@tiptap/extension-table-row': - specifier: ^3.11.1 - version: 3.11.1(@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) '@tiptap/markdown': specifier: ^3.11.1 version: 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) @@ -262,190 +250,6 @@ importers: specifier: ^0.8.0 version: 0.8.1 - src/plugins/demo-captcha: - dependencies: - react: - specifier: ^18.2.0 - version: 18.3.1 - react-bootstrap: - specifier: ^2.10.0 - version: 2.10.6(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react-dom: - specifier: ^18.2.0 - version: 18.3.1(react@18.3.1) - react-i18next: - specifier: ^11.18.3 - version: 11.18.6(i18next@21.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - devDependencies: - '@modyfi/vite-plugin-yaml': - specifier: ^1.1.0 - version: 1.1.1(rollup@3.29.5)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) - '@typescript-eslint/eslint-plugin': - specifier: ^6.0.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/parser': - specifier: ^6.0.0 - version: 6.21.0(eslint@8.57.1)(typescript@5.9.3) - '@vitejs/plugin-react-swc': - specifier: ^3.3.2 - version: 3.11.0(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) - eslint: - specifier: ^8.45.0 - version: 8.57.1 - eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.2(eslint@8.57.1) - eslint-plugin-react-refresh: - specifier: ^0.4.3 - version: 0.4.24(eslint@8.57.1) - typescript: - specifier: ^5.0.2 - version: 5.9.3 - vite: - specifier: ^4.4.5 - version: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) - vite-plugin-dts: - specifier: ^3.9.1 - version: 3.9.1(@types/node@20.5.1)(rollup@3.29.5)(typescript@5.9.3)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) - - src/plugins/demo-editor: - dependencies: - react: - specifier: ^18.2.0 - version: 18.3.1 - react-bootstrap: - specifier: ^2.10.0 - version: 2.10.6(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react-dom: - specifier: ^18.2.0 - version: 18.3.1(react@18.3.1) - react-i18next: - specifier: ^11.18.3 - version: 11.18.6(i18next@21.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - devDependencies: - '@modyfi/vite-plugin-yaml': - specifier: ^1.1.0 - version: 1.1.1(rollup@3.29.5)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) - '@typescript-eslint/eslint-plugin': - specifier: ^6.0.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/parser': - specifier: ^6.0.0 - version: 6.21.0(eslint@8.57.1)(typescript@5.9.3) - '@vitejs/plugin-react-swc': - specifier: ^3.3.2 - version: 3.11.0(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) - eslint: - specifier: ^8.45.0 - version: 8.57.1 - eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.2(eslint@8.57.1) - eslint-plugin-react-refresh: - specifier: ^0.4.3 - version: 0.4.24(eslint@8.57.1) - typescript: - specifier: ^5.0.2 - version: 5.9.3 - vite: - specifier: ^4.4.5 - version: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) - vite-plugin-dts: - specifier: ^3.9.1 - version: 3.9.1(@types/node@20.5.1)(rollup@3.29.5)(typescript@5.9.3)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) - - src/plugins/demo-render: - dependencies: - react: - specifier: ^18.2.0 - version: 18.3.1 - react-bootstrap: - specifier: ^2.10.0 - version: 2.10.6(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react-dom: - specifier: ^18.2.0 - version: 18.3.1(react@18.3.1) - react-i18next: - specifier: ^11.18.3 - version: 11.18.6(i18next@21.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - devDependencies: - '@modyfi/vite-plugin-yaml': - specifier: ^1.1.0 - version: 1.1.1(rollup@3.29.5)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) - '@typescript-eslint/eslint-plugin': - specifier: ^6.0.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/parser': - specifier: ^6.0.0 - version: 6.21.0(eslint@8.57.1)(typescript@5.9.3) - '@vitejs/plugin-react-swc': - specifier: ^3.3.2 - version: 3.11.0(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) - eslint: - specifier: ^8.45.0 - version: 8.57.1 - eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.2(eslint@8.57.1) - eslint-plugin-react-refresh: - specifier: ^0.4.3 - version: 0.4.24(eslint@8.57.1) - typescript: - specifier: ^5.0.2 - version: 5.9.3 - vite: - specifier: ^4.4.5 - version: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) - vite-plugin-dts: - specifier: ^3.9.1 - version: 3.9.1(@types/node@20.5.1)(rollup@3.29.5)(typescript@5.9.3)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) - - src/plugins/demo-route: - dependencies: - react: - specifier: ^18.2.0 - version: 18.3.1 - react-bootstrap: - specifier: ^2.10.0 - version: 2.10.6(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react-dom: - specifier: ^18.2.0 - version: 18.3.1(react@18.3.1) - react-i18next: - specifier: ^11.18.3 - version: 11.18.6(i18next@21.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - devDependencies: - '@modyfi/vite-plugin-yaml': - specifier: ^1.1.0 - version: 1.1.1(rollup@3.29.5)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) - '@typescript-eslint/eslint-plugin': - specifier: ^6.0.0 - version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/parser': - specifier: ^6.0.0 - version: 6.21.0(eslint@8.57.1)(typescript@5.9.3) - '@vitejs/plugin-react-swc': - specifier: ^3.3.2 - version: 3.11.0(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) - eslint: - specifier: ^8.45.0 - version: 8.57.1 - eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.2(eslint@8.57.1) - eslint-plugin-react-refresh: - specifier: ^0.4.3 - version: 0.4.24(eslint@8.57.1) - typescript: - specifier: ^5.0.2 - version: 5.9.3 - vite: - specifier: ^4.4.5 - version: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) - vite-plugin-dts: - specifier: ^3.9.1 - version: 3.9.1(@types/node@20.5.1)(rollup@3.29.5)(typescript@5.9.3)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)) - packages: '@alloc/quick-lru@5.2.0': @@ -552,18 +356,10 @@ packages: resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.25.9': resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.25.9': resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} @@ -581,11 +377,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.28.5': - resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9': resolution: {integrity: sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==} engines: {node: '>=6.9.0'} @@ -1172,10 +963,6 @@ packages: resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} - engines: {node: '>=6.9.0'} - '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -1437,138 +1224,6 @@ packages: peerDependencies: postcss-selector-parser: ^6.0.10 - '@esbuild/android-arm64@0.18.20': - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.18.20': - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.18.20': - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.18.20': - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.18.20': - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.18.20': - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.18.20': - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.18.20': - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.18.20': - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.18.20': - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.18.20': - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.18.20': - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.18.20': - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.18.20': - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.18.20': - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.18.20': - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-x64@0.18.20': - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-x64@0.18.20': - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/sunos-x64@0.18.20': - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.18.20': - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.18.20': - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.18.20': - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - '@eslint-community/eslint-utils@4.4.1': resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1718,9 +1373,6 @@ packages: '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} @@ -1784,24 +1436,6 @@ packages: '@marijn/find-cluster-break@1.0.2': resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} - '@microsoft/api-extractor-model@7.28.13': - resolution: {integrity: sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==} - - '@microsoft/api-extractor@7.43.0': - resolution: {integrity: sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==} - hasBin: true - - '@microsoft/tsdoc-config@0.16.2': - resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==} - - '@microsoft/tsdoc@0.14.2': - resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} - - '@modyfi/vite-plugin-yaml@1.1.1': - resolution: {integrity: sha512-rEbfFNlMGLKpAYs2RsfLAhxCHFa6M4QKHHk0A4EYcCJAUwFtFO6qiEdLjUGUTtnRUxAC7GxxCa+ZbeUILSDvqQ==} - peerDependencies: - vite: '>=3.2.7' - '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} @@ -1879,9 +1513,6 @@ packages: react: '>=16.14.0' react-dom: '>=16.14.0' - '@rolldown/pluginutils@1.0.0-beta.27': - resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@rollup/plugin-babel@5.3.1': resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} engines: {node: '>= 10.0.0'} @@ -1910,52 +1541,12 @@ packages: peerDependencies: rollup: ^1.20.0||^2.0.0 - '@rollup/pluginutils@5.1.0': - resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/pluginutils@5.3.0': - resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} '@rushstack/eslint-patch@1.10.4': resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==} - '@rushstack/node-core-library@4.0.2': - resolution: {integrity: sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==} - peerDependencies: - '@types/node': '*' - peerDependenciesMeta: - '@types/node': - optional: true - - '@rushstack/rig-package@0.5.2': - resolution: {integrity: sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==} - - '@rushstack/terminal@0.10.0': - resolution: {integrity: sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==} - peerDependencies: - '@types/node': '*' - peerDependenciesMeta: - '@types/node': - optional: true - - '@rushstack/ts-command-line@4.19.1': - resolution: {integrity: sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==} - '@sinclair/typebox@0.24.51': resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} @@ -2250,21 +1841,6 @@ packages: peerDependencies: '@tiptap/core': ^3.11.1 - '@tiptap/extension-table-cell@3.11.1': - resolution: {integrity: sha512-loFq2aZ+nDyrgxPjOCY/73YelRHqQWMw4oIiB4D0sYiDka+bBN/cV7LGWqfP5CldF8oSBJ8u+5ViDWCilTfDeg==} - peerDependencies: - '@tiptap/extension-table': ^3.11.1 - - '@tiptap/extension-table-header@3.11.1': - resolution: {integrity: sha512-oCn71L7FYxnpzHO7hn8xbaF6jxRhPinNsqgde+5OY23BEvVBpX8QFbOJkphQDyMwvSHAw/3S+ZF+vxHZU51aRg==} - peerDependencies: - '@tiptap/extension-table': ^3.11.1 - - '@tiptap/extension-table-row@3.11.1': - resolution: {integrity: sha512-KfB9axBtfE59/xC++4SS2iYkfEv93k5EWDbjIjC6T62FpfTYlBDOQutj79Nnmn8XkS5srT4nmxrohqRc1wUSQg==} - peerDependencies: - '@tiptap/extension-table': ^3.11.1 - '@tiptap/extension-table@3.11.1': resolution: {integrity: sha512-ae81cJgJ3cAA1Ry0JtLKtoPpA23YvMy0WnAw1gqnOX9yTYRYgT5W6MzP0O2rIBOI6b5Xkt6xtZzChjwMzioGbQ==} peerDependencies: @@ -2329,9 +1905,6 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - '@types/argparse@1.0.38': - resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} - '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -2666,37 +2239,6 @@ packages: '@ungap/structured-clone@1.2.1': resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} - '@vitejs/plugin-react-swc@3.11.0': - resolution: {integrity: sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w==} - peerDependencies: - vite: ^4 || ^5 || ^6 || ^7 - - '@volar/language-core@1.11.1': - resolution: {integrity: sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==} - - '@volar/source-map@1.11.1': - resolution: {integrity: sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==} - - '@volar/typescript@1.11.1': - resolution: {integrity: sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==} - - '@vue/compiler-core@3.5.25': - resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==} - - '@vue/compiler-dom@3.5.25': - resolution: {integrity: sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==} - - '@vue/language-core@1.8.27': - resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - '@vue/shared@3.5.25': - resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==} - '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -3300,10 +2842,6 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} - commander@9.5.0: - resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} - engines: {node: ^12.20.0 || >=14} - common-tags@1.8.2: resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} engines: {node: '>=4.0.0'} @@ -3322,9 +2860,6 @@ packages: resolution: {integrity: sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==} engines: {node: '>= 0.8.0'} - computeds@0.0.1: - resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} - concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -3896,11 +3431,6 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} - esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} - engines: {node: '>=12'} - hasBin: true - escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -4096,11 +3626,6 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - eslint-plugin-react-refresh@0.4.24: - resolution: {integrity: sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w==} - peerDependencies: - eslint: '>=8.40' - eslint-plugin-react@7.37.2: resolution: {integrity: sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==} engines: {node: '>=4'} @@ -4175,9 +3700,6 @@ packages: estree-walker@1.0.1: resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -4353,10 +3875,6 @@ packages: resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} engines: {node: '>=14.14'} - fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} - fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} @@ -4666,10 +4184,6 @@ packages: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} - import-lazy@4.0.0: - resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} - engines: {node: '>=8'} - import-local@3.2.0: resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} engines: {node: '>=8'} @@ -5130,9 +4644,6 @@ packages: resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} hasBin: true - jju@1.4.0: - resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} - js-sha256@0.11.0: resolution: {integrity: sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==} @@ -5188,9 +4699,6 @@ packages: engines: {node: '>=6'} hasBin: true - jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} @@ -5227,9 +4735,6 @@ packages: resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} engines: {node: '>= 8'} - kolorist@1.8.0: - resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -5311,14 +4816,6 @@ packages: lodash.flow@3.5.0: resolution: {integrity: sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==} - lodash.get@4.4.2: - resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} - deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. - - lodash.isequal@4.5.0: - resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. - lodash.isfunction@3.0.9: resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} @@ -5383,9 +4880,6 @@ packages: magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -5503,9 +4997,6 @@ packages: minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - minimatch@3.0.8: - resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==} - minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -5542,9 +5033,6 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - muggle-string@0.3.1: - resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} - multicast-dns@7.2.5: resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} hasBin: true @@ -5770,9 +5258,6 @@ packages: pascal-case@3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} - path-browserify@1.0.1: - resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - path-exists@3.0.0: resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} engines: {node: '>=4'} @@ -5820,10 +5305,6 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} engines: {node: '>=0.10'} @@ -6710,9 +6191,6 @@ packages: resolution: {integrity: sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==} engines: {node: '>=10'} - resolve@1.19.0: - resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} - resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -6757,11 +6235,6 @@ packages: engines: {node: '>=10.0.0'} hasBin: true - rollup@3.29.5: - resolution: {integrity: sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} - hasBin: true - rope-sequence@1.3.4: resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} @@ -7304,10 +6777,6 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - tosource@2.0.0-alpha.3: - resolution: {integrity: sha512-KAB2lrSS48y91MzFPFuDg4hLbvDiyTjOVgaK7Erw+5AmZXNq4sFRVn8r6yxSLuNs15PaokrDRpS61ERY9uZOug==} - engines: {node: '>=10'} - tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -7435,16 +6904,6 @@ packages: engines: {node: '>=4.2.0'} hasBin: true - typescript@5.4.2: - resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} - engines: {node: '>=14.17'} - hasBin: true - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true - uc.micro@2.1.0: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} @@ -7484,10 +6943,6 @@ packages: resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} engines: {node: '>=8'} - universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - universalify@0.2.0: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} @@ -7555,64 +7010,16 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - validator@13.15.23: - resolution: {integrity: sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==} - engines: {node: '>= 0.10'} - vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - vite-plugin-dts@3.9.1: - resolution: {integrity: sha512-rVp2KM9Ue22NGWB8dNtWEr+KekN3rIgz1tWD050QnRGlriUCmaDwa7qA5zDEjbXg5lAXhYMSBJtx3q3hQIJZSg==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - typescript: '*' - vite: '*' - peerDependenciesMeta: - vite: - optional: true - - vite@4.5.14: - resolution: {integrity: sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==} - engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true - peerDependencies: - '@types/node': '>= 14' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - void-elements@3.1.0: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} vue-template-compiler@2.7.16: - resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} - - vue-tsc@1.8.27: - resolution: {integrity: sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==} - hasBin: true - peerDependencies: - typescript: '*' + resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} w3c-hr-time@1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} @@ -7923,11 +7330,6 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - z-schema@5.0.5: - resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} - engines: {node: '>=8.0.0'} - hasBin: true - zustand@5.0.2: resolution: {integrity: sha512-8qNdnJVJlHlrKXi50LDqqUNmUbuBjoKLrYQBnoChIbVph7vni+sY+YpvdjXG9YLd/Bxr6scMcR+rm5H3aSqPaw==} engines: {node: '>=12.20.0'} @@ -8105,12 +7507,8 @@ snapshots: '@babel/helper-string-parser@7.25.9': {} - '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.25.9': {} - '@babel/helper-validator-identifier@7.28.5': {} - '@babel/helper-validator-option@7.25.9': {} '@babel/helper-wrap-function@7.25.9': @@ -8130,10 +7528,6 @@ snapshots: dependencies: '@babel/types': 7.26.3 - '@babel/parser@7.28.5': - dependencies: - '@babel/types': 7.28.5 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -8849,11 +8243,6 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - '@babel/types@7.28.5': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - '@bcoe/v8-coverage@0.2.3': {} '@codemirror/autocomplete@6.18.3(@codemirror/language@6.10.6)(@codemirror/state@6.5.0)(@codemirror/view@6.35.3)(@lezer/common@1.2.3)': @@ -9310,72 +8699,6 @@ snapshots: dependencies: postcss-selector-parser: 6.1.2 - '@esbuild/android-arm64@0.18.20': - optional: true - - '@esbuild/android-arm@0.18.20': - optional: true - - '@esbuild/android-x64@0.18.20': - optional: true - - '@esbuild/darwin-arm64@0.18.20': - optional: true - - '@esbuild/darwin-x64@0.18.20': - optional: true - - '@esbuild/freebsd-arm64@0.18.20': - optional: true - - '@esbuild/freebsd-x64@0.18.20': - optional: true - - '@esbuild/linux-arm64@0.18.20': - optional: true - - '@esbuild/linux-arm@0.18.20': - optional: true - - '@esbuild/linux-ia32@0.18.20': - optional: true - - '@esbuild/linux-loong64@0.18.20': - optional: true - - '@esbuild/linux-mips64el@0.18.20': - optional: true - - '@esbuild/linux-ppc64@0.18.20': - optional: true - - '@esbuild/linux-riscv64@0.18.20': - optional: true - - '@esbuild/linux-s390x@0.18.20': - optional: true - - '@esbuild/linux-x64@0.18.20': - optional: true - - '@esbuild/netbsd-x64@0.18.20': - optional: true - - '@esbuild/openbsd-x64@0.18.20': - optional: true - - '@esbuild/sunos-x64@0.18.20': - optional: true - - '@esbuild/win32-arm64@0.18.20': - optional: true - - '@esbuild/win32-ia32@0.18.20': - optional: true - - '@esbuild/win32-x64@0.18.20': - optional: true - '@eslint-community/eslint-utils@4.4.1(eslint@8.57.1)': dependencies: eslint: 8.57.1 @@ -9649,8 +8972,6 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.0': {} - '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -9758,50 +9079,6 @@ snapshots: '@marijn/find-cluster-break@1.0.2': {} - '@microsoft/api-extractor-model@7.28.13(@types/node@20.5.1)': - dependencies: - '@microsoft/tsdoc': 0.14.2 - '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 4.0.2(@types/node@20.5.1) - transitivePeerDependencies: - - '@types/node' - - '@microsoft/api-extractor@7.43.0(@types/node@20.5.1)': - dependencies: - '@microsoft/api-extractor-model': 7.28.13(@types/node@20.5.1) - '@microsoft/tsdoc': 0.14.2 - '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 4.0.2(@types/node@20.5.1) - '@rushstack/rig-package': 0.5.2 - '@rushstack/terminal': 0.10.0(@types/node@20.5.1) - '@rushstack/ts-command-line': 4.19.1(@types/node@20.5.1) - lodash: 4.17.21 - minimatch: 3.0.8 - resolve: 1.22.8 - semver: 7.5.4 - source-map: 0.6.1 - typescript: 5.4.2 - transitivePeerDependencies: - - '@types/node' - - '@microsoft/tsdoc-config@0.16.2': - dependencies: - '@microsoft/tsdoc': 0.14.2 - ajv: 6.12.6 - jju: 1.4.0 - resolve: 1.19.0 - - '@microsoft/tsdoc@0.14.2': {} - - '@modyfi/vite-plugin-yaml@1.1.1(rollup@3.29.5)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0))': - dependencies: - '@rollup/pluginutils': 5.1.0(rollup@3.29.5) - js-yaml: 4.1.0 - tosource: 2.0.0-alpha.3 - vite: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) - transitivePeerDependencies: - - rollup - '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': dependencies: eslint-scope: 5.1.1 @@ -9871,8 +9148,6 @@ snapshots: uncontrollable: 8.0.4(react@18.3.1) warning: 4.0.3 - '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rollup/plugin-babel@5.3.1(@babel/core@7.26.0)(@types/babel__core@7.20.5)(rollup@2.79.2)': dependencies: '@babel/core': 7.26.0 @@ -9907,58 +9182,10 @@ snapshots: picomatch: 2.3.1 rollup: 2.79.2 - '@rollup/pluginutils@5.1.0(rollup@3.29.5)': - dependencies: - '@types/estree': 1.0.6 - estree-walker: 2.0.2 - picomatch: 2.3.1 - optionalDependencies: - rollup: 3.29.5 - - '@rollup/pluginutils@5.3.0(rollup@3.29.5)': - dependencies: - '@types/estree': 1.0.6 - estree-walker: 2.0.2 - picomatch: 4.0.3 - optionalDependencies: - rollup: 3.29.5 - '@rtsao/scc@1.1.0': {} '@rushstack/eslint-patch@1.10.4': {} - '@rushstack/node-core-library@4.0.2(@types/node@20.5.1)': - dependencies: - fs-extra: 7.0.1 - import-lazy: 4.0.0 - jju: 1.4.0 - resolve: 1.22.8 - semver: 7.5.4 - z-schema: 5.0.5 - optionalDependencies: - '@types/node': 20.5.1 - - '@rushstack/rig-package@0.5.2': - dependencies: - resolve: 1.22.8 - strip-json-comments: 3.1.1 - - '@rushstack/terminal@0.10.0(@types/node@20.5.1)': - dependencies: - '@rushstack/node-core-library': 4.0.2(@types/node@20.5.1) - supports-color: 8.1.1 - optionalDependencies: - '@types/node': 20.5.1 - - '@rushstack/ts-command-line@4.19.1(@types/node@20.5.1)': - dependencies: - '@rushstack/terminal': 0.10.0(@types/node@20.5.1) - '@types/argparse': 1.0.38 - argparse: 1.0.10 - string-argv: 0.3.2 - transitivePeerDependencies: - - '@types/node' - '@sinclair/typebox@0.24.51': {} '@sinonjs/commons@1.8.6': @@ -10088,8 +9315,10 @@ snapshots: '@swc/core-win32-arm64-msvc': 1.15.3 '@swc/core-win32-ia32-msvc': 1.15.3 '@swc/core-win32-x64-msvc': 1.15.3 + optional: true - '@swc/counter@0.1.3': {} + '@swc/counter@0.1.3': + optional: true '@swc/helpers@0.5.15': dependencies: @@ -10098,6 +9327,7 @@ snapshots: '@swc/types@0.1.25': dependencies: '@swc/counter': 0.1.3 + optional: true '@testing-library/dom@8.20.1': dependencies: @@ -10244,18 +9474,6 @@ snapshots: dependencies: '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) - '@tiptap/extension-table-cell@3.11.1(@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': - dependencies: - '@tiptap/extension-table': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - - '@tiptap/extension-table-header@3.11.1(@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': - dependencies: - '@tiptap/extension-table': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - - '@tiptap/extension-table-row@3.11.1(@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': - dependencies: - '@tiptap/extension-table': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': dependencies: '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) @@ -10357,8 +9575,6 @@ snapshots: '@tsconfig/node16@1.0.4': {} - '@types/argparse@1.0.38': {} - '@types/aria-query@5.0.4': {} '@types/babel__core@7.20.5': @@ -10636,26 +9852,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 - eslint: 8.57.1 - graphemer: 1.4.0 - ignore: 5.3.2 - natural-compare: 1.4.0 - semver: 7.6.3 - ts-api-utils: 1.4.3(typescript@5.9.3) - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.1)(typescript@4.9.5)': dependencies: '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) @@ -10689,19 +9885,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 - eslint: 8.57.1 - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/scope-manager@5.62.0': dependencies: '@typescript-eslint/types': 5.62.0 @@ -10736,18 +9919,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) - '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.9.3) - debug: 4.4.0 - eslint: 8.57.1 - ts-api-utils: 1.4.3(typescript@5.9.3) - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/types@5.62.0': {} '@typescript-eslint/types@6.21.0': {} @@ -10781,21 +9952,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@6.21.0(typescript@5.9.3)': - dependencies: - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.4.0 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.3 - semver: 7.6.3 - ts-api-utils: 1.4.3(typescript@5.9.3) - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@4.9.5)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) @@ -10825,20 +9981,6 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.9.3)': - dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 6.21.0 - '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) - eslint: 8.57.1 - semver: 7.6.3 - transitivePeerDependencies: - - supports-color - - typescript - '@typescript-eslint/visitor-keys@5.62.0': dependencies: '@typescript-eslint/types': 5.62.0 @@ -10851,56 +9993,6 @@ snapshots: '@ungap/structured-clone@1.2.1': {} - '@vitejs/plugin-react-swc@3.11.0(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0))': - dependencies: - '@rolldown/pluginutils': 1.0.0-beta.27 - '@swc/core': 1.15.3 - vite: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) - transitivePeerDependencies: - - '@swc/helpers' - - '@volar/language-core@1.11.1': - dependencies: - '@volar/source-map': 1.11.1 - - '@volar/source-map@1.11.1': - dependencies: - muggle-string: 0.3.1 - - '@volar/typescript@1.11.1': - dependencies: - '@volar/language-core': 1.11.1 - path-browserify: 1.0.1 - - '@vue/compiler-core@3.5.25': - dependencies: - '@babel/parser': 7.28.5 - '@vue/shared': 3.5.25 - entities: 4.5.0 - estree-walker: 2.0.2 - source-map-js: 1.2.1 - - '@vue/compiler-dom@3.5.25': - dependencies: - '@vue/compiler-core': 3.5.25 - '@vue/shared': 3.5.25 - - '@vue/language-core@1.8.27(typescript@5.9.3)': - dependencies: - '@volar/language-core': 1.11.1 - '@volar/source-map': 1.11.1 - '@vue/compiler-dom': 3.5.25 - '@vue/shared': 3.5.25 - computeds: 0.0.1 - minimatch: 9.0.5 - muggle-string: 0.3.1 - path-browserify: 1.0.1 - vue-template-compiler: 2.7.16 - optionalDependencies: - typescript: 5.9.3 - - '@vue/shared@3.5.25': {} - '@webassemblyjs/ast@1.14.1': dependencies: '@webassemblyjs/helper-numbers': 1.13.2 @@ -11616,9 +10708,6 @@ snapshots: commander@8.3.0: {} - commander@9.5.0: - optional: true - common-tags@1.8.2: {} commondir@1.0.1: {} @@ -11644,8 +10733,6 @@ snapshots: transitivePeerDependencies: - supports-color - computeds@0.0.1: {} - concat-map@0.0.1: {} confusing-browser-globals@1.0.11: {} @@ -11918,7 +11005,8 @@ snapshots: dayjs@1.11.13: {} - de-indent@1.0.2: {} + de-indent@1.0.2: + optional: true debug@2.6.9: dependencies: @@ -12257,31 +11345,6 @@ snapshots: is-date-object: 1.0.5 is-symbol: 1.1.0 - esbuild@0.18.20: - optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 - escalade@3.2.0: {} escape-html@1.0.3: {} @@ -12557,10 +11620,6 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-plugin-react-refresh@0.4.24(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - eslint-plugin-react@7.37.2(eslint@8.57.1): dependencies: array-includes: 3.1.8 @@ -12682,8 +11741,6 @@ snapshots: estree-walker@1.0.1: {} - estree-walker@2.0.2: {} - esutils@2.0.3: {} etag@1.8.1: {} @@ -12919,12 +11976,6 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 - fs-extra@7.0.1: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - fs-extra@9.1.0: dependencies: at-least-node: 1.0.0 @@ -13246,8 +12297,6 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 - import-lazy@4.0.0: {} - import-local@3.2.0: dependencies: pkg-dir: 4.2.0 @@ -13933,8 +12982,6 @@ snapshots: jiti@1.21.6: {} - jju@1.4.0: {} - js-sha256@0.11.0: {} js-tokens@4.0.0: {} @@ -14002,10 +13049,6 @@ snapshots: json5@2.2.3: {} - jsonfile@4.0.0: - optionalDependencies: - graceful-fs: 4.2.11 - jsonfile@6.1.0: dependencies: universalify: 2.0.1 @@ -14045,8 +13088,6 @@ snapshots: klona@2.0.6: {} - kolorist@1.8.0: {} - language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -14135,10 +13176,6 @@ snapshots: lodash.flow@3.5.0: {} - lodash.get@4.4.2: {} - - lodash.isequal@4.5.0: {} - lodash.isfunction@3.0.9: {} lodash.isplainobject@4.0.6: {} @@ -14195,10 +13232,6 @@ snapshots: dependencies: sourcemap-codec: 1.4.8 - magic-string@0.30.21: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - make-dir@3.1.0: dependencies: semver: 6.3.1 @@ -14295,10 +13328,6 @@ snapshots: minimalistic-assert@1.0.1: {} - minimatch@3.0.8: - dependencies: - brace-expansion: 1.1.11 - minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -14333,8 +13362,6 @@ snapshots: ms@2.1.3: {} - muggle-string@0.3.1: {} - multicast-dns@7.2.5: dependencies: dns-packet: 5.6.1 @@ -14578,8 +13605,6 @@ snapshots: no-case: 3.0.4 tslib: 2.8.1 - path-browserify@1.0.1: {} - path-exists@3.0.0: {} path-exists@4.0.0: {} @@ -14609,8 +13634,6 @@ snapshots: picomatch@2.3.1: {} - picomatch@4.0.3: {} - pidtree@0.6.0: {} pify@2.3.0: {} @@ -15650,11 +14673,6 @@ snapshots: resolve.exports@1.1.1: {} - resolve@1.19.0: - dependencies: - is-core-module: 2.15.1 - path-parse: 1.0.7 - resolve@1.22.8: dependencies: is-core-module: 2.15.1 @@ -15698,10 +14716,6 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - rollup@3.29.5: - optionalDependencies: - fsevents: 2.3.3 - rope-sequence@1.3.4: {} run-parallel@1.2.0: @@ -16326,8 +15340,6 @@ snapshots: toidentifier@1.0.1: {} - tosource@2.0.0-alpha.3: {} - tough-cookie@4.1.4: dependencies: psl: 1.15.0 @@ -16351,10 +15363,6 @@ snapshots: dependencies: typescript: 4.9.5 - ts-api-utils@1.4.3(typescript@5.9.3): - dependencies: - typescript: 5.9.3 - ts-interface-checker@0.1.13: {} ts-node@10.9.2(@swc/core@1.15.3)(@types/node@16.18.121)(typescript@4.9.5): @@ -16464,10 +15472,6 @@ snapshots: typescript@4.9.5: {} - typescript@5.4.2: {} - - typescript@5.9.3: {} - uc.micro@2.1.0: {} unbox-primitive@1.0.2: @@ -16506,8 +15510,6 @@ snapshots: dependencies: crypto-random-string: 2.0.0 - universalify@0.1.2: {} - universalify@0.2.0: {} universalify@2.0.1: {} @@ -16567,51 +15569,15 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - validator@13.15.23: {} - vary@1.1.2: {} - vite-plugin-dts@3.9.1(@types/node@20.5.1)(rollup@3.29.5)(typescript@5.9.3)(vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0)): - dependencies: - '@microsoft/api-extractor': 7.43.0(@types/node@20.5.1) - '@rollup/pluginutils': 5.3.0(rollup@3.29.5) - '@vue/language-core': 1.8.27(typescript@5.9.3) - debug: 4.4.0 - kolorist: 1.8.0 - magic-string: 0.30.21 - typescript: 5.9.3 - vue-tsc: 1.8.27(typescript@5.9.3) - optionalDependencies: - vite: 4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0) - transitivePeerDependencies: - - '@types/node' - - rollup - - supports-color - - vite@4.5.14(@types/node@20.5.1)(sass@1.54.4)(terser@5.37.0): - dependencies: - esbuild: 0.18.20 - postcss: 8.4.49 - rollup: 3.29.5 - optionalDependencies: - '@types/node': 20.5.1 - fsevents: 2.3.3 - sass: 1.54.4 - terser: 5.37.0 - void-elements@3.1.0: {} vue-template-compiler@2.7.16: dependencies: de-indent: 1.0.2 he: 1.2.0 - - vue-tsc@1.8.27(typescript@5.9.3): - dependencies: - '@volar/typescript': 1.11.1 - '@vue/language-core': 1.8.27(typescript@5.9.3) - semver: 7.6.3 - typescript: 5.9.3 + optional: true w3c-hr-time@1.0.2: dependencies: @@ -17055,14 +16021,6 @@ snapshots: yocto-queue@0.1.0: {} - z-schema@5.0.5: - dependencies: - lodash.get: 4.4.2 - lodash.isequal: 4.5.0 - validator: 13.15.23 - optionalDependencies: - commander: 9.5.0 - zustand@5.0.2(@types/react@18.3.16)(immer@9.0.21)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)): optionalDependencies: '@types/react': 18.3.16 From 3d43700556306965f7816e6cdb031327c16193a6 Mon Sep 17 00:00:00 2001 From: robin Date: Tue, 16 Dec 2025 14:50:29 +0800 Subject: [PATCH 27/92] refactor(editor): streamline editor component structure and enhance command methods - Removed unnecessary conditional rendering in the MDEditor component for the PluginRender. - Simplified the MarkdownEditor component's useEffect hooks for better clarity. - Refactored command methods to utilize self-referencing for improved maintainability. --- ui/src/components/Editor/MarkdownEditor.tsx | 9 +--- ui/src/components/Editor/index.tsx | 50 +++++++++---------- .../Editor/utils/codemirror/commands.ts | 43 ++++++++-------- 3 files changed, 48 insertions(+), 54 deletions(-) diff --git a/ui/src/components/Editor/MarkdownEditor.tsx b/ui/src/components/Editor/MarkdownEditor.tsx index 10145a228..fe5d8bb44 100644 --- a/ui/src/components/Editor/MarkdownEditor.tsx +++ b/ui/src/components/Editor/MarkdownEditor.tsx @@ -55,30 +55,25 @@ const MarkdownEditor: React.FC = ({ autoFocus, }); - // 初始化内容(只在编辑器创建时执行) useEffect(() => { if (!editor) { return; } - // 初始化编辑器内容 editor.setValue(value || ''); lastSyncedValueRef.current = value || ''; onEditorReady?.(editor); - }, [editor]); // 只在编辑器创建时执行 + }, [editor]); - // 当外部 value 变化时更新(但不是用户输入导致的) useEffect(() => { if (!editor) { return; } - // 如果 value 和 lastSyncedValueRef 相同,说明是用户输入导致的更新,跳过 if (value === lastSyncedValueRef.current) { return; } - // 外部 value 真正变化,更新编辑器 const currentValue = editor.getValue(); if (currentValue !== value) { editor.setValue(value || ''); @@ -86,11 +81,9 @@ const MarkdownEditor: React.FC = ({ } }, [editor, value]); - // 清理:组件卸载时销毁编辑器 useEffect(() => { return () => { if (editor) { - // CodeMirror EditorView 有 destroy 方法 const view = editor as unknown as EditorView; if (view.destroy) { view.destroy(); diff --git a/ui/src/components/Editor/index.tsx b/ui/src/components/Editor/index.tsx index a914d912c..94bd5836e 100644 --- a/ui/src/components/Editor/index.tsx +++ b/ui/src/components/Editor/index.tsx @@ -123,32 +123,30 @@ const MDEditor: ForwardRefRenderFunction = (
    - {currentEditor && ( - - - - -
    - - -
    - - -
    -
    -
      -
        - - -
        -
        - - - )} + + + + +
        + + +
        + + +
    +
    +
      +
        + + +
        +
        + +
        diff --git a/ui/src/components/Editor/utils/codemirror/commands.ts b/ui/src/components/Editor/utils/codemirror/commands.ts index 59ab064ec..152bc632d 100644 --- a/ui/src/components/Editor/utils/codemirror/commands.ts +++ b/ui/src/components/Editor/utils/codemirror/commands.ts @@ -33,7 +33,8 @@ import { Editor, Level } from '../../types'; * @returns Object containing all command methods */ export function createCommandMethods(editor: Editor) { - return { + // Create methods object that allows self-reference + const methods = { wrapText: (before: string, after = before, defaultText) => { const range = editor.state.selection.ranges[0]; const selectedText = editor.state.sliceDoc(range.from, range.to); @@ -79,39 +80,39 @@ export function createCommandMethods(editor: Editor) { }, insertBold: (text?: string) => { - editor.wrapText('**', '**', text || 'bold text'); + methods.wrapText('**', '**', text || 'bold text'); }, insertItalic: (text?: string) => { - editor.wrapText('*', '*', text || 'italic text'); + methods.wrapText('*', '*', text || 'italic text'); }, insertCode: (text?: string) => { - editor.wrapText('`', '`', text || 'code'); + methods.wrapText('`', '`', text || 'code'); }, insertStrikethrough: (text?: string) => { - editor.wrapText('~~', '~~', text || 'strikethrough text'); + methods.wrapText('~~', '~~', text || 'strikethrough text'); }, insertHeading: (level: Level, text?: string) => { const headingText = '#'.repeat(level); - editor.wrapText(`${headingText} `, '', text || 'heading'); + methods.wrapText(`${headingText} `, '', text || 'heading'); }, insertBlockquote: (text?: string) => { - editor.wrapText('> ', '', text || 'quote'); + methods.wrapText('> ', '', text || 'quote'); }, insertCodeBlock: (language?: string, code?: string) => { const lang = language || ''; const codeText = code || ''; const block = `\`\`\`${lang}\n${codeText}\n\`\`\``; - editor.appendBlock(block); + methods.appendBlock(block); }, insertHorizontalRule: () => { - editor.appendBlock('---'); + methods.appendBlock('---'); }, insertOrderedList: () => { @@ -121,7 +122,7 @@ export function createCommandMethods(editor: Editor) { if (/^\d+\.\s/.test(lineText)) { return; } - editor.replaceLines((lineItem) => { + methods.replaceLines((lineItem) => { if (lineItem.trim() === '') { return lineItem; } @@ -136,7 +137,7 @@ export function createCommandMethods(editor: Editor) { if (/^[-*+]\s/.test(lineText)) { return; } - editor.replaceLines((lineItem) => { + methods.replaceLines((lineItem) => { if (lineItem.trim() === '') { return lineItem; } @@ -149,11 +150,11 @@ export function createCommandMethods(editor: Editor) { const line = editor.state.doc.line(cursor.line); const lineText = line.text.trim(); if (/^\d+\.\s/.test(lineText)) { - editor.replaceLines((lineItem) => { + methods.replaceLines((lineItem) => { return lineItem.replace(/^\d+\.\s/, ''); }); } else { - editor.insertOrderedList(); + methods.insertOrderedList(); } }, @@ -162,22 +163,22 @@ export function createCommandMethods(editor: Editor) { const line = editor.state.doc.line(cursor.line); const lineText = line.text.trim(); if (/^[-*+]\s/.test(lineText)) { - editor.replaceLines((lineItem) => { + methods.replaceLines((lineItem) => { return lineItem.replace(/^[-*+]\s/, ''); }); } else { - editor.insertUnorderedList(); + methods.insertUnorderedList(); } }, insertLink: (url: string, text?: string) => { const linkText = text || url; - editor.wrapText('[', `](${url})`, linkText); + methods.wrapText('[', `](${url})`, linkText); }, insertImage: (url: string, alt?: string) => { const altText = alt || ''; - editor.wrapText('![', `](${url})`, altText); + methods.wrapText('![', `](${url})`, altText); }, insertTable: (rows = 3, cols = 3) => { @@ -192,11 +193,11 @@ export function createCommandMethods(editor: Editor) { table.push(`| ${'---'.repeat(cols).split('').join(' | ')} |`); } } - editor.appendBlock(table.join('\n')); + methods.appendBlock(table.join('\n')); }, indent: () => { - editor.replaceLines((line) => { + methods.replaceLines((line) => { if (line.trim() === '') { return line; } @@ -205,7 +206,7 @@ export function createCommandMethods(editor: Editor) { }, outdent: () => { - editor.replaceLines((line) => { + methods.replaceLines((line) => { if (line.trim() === '') { return line; } @@ -261,4 +262,6 @@ export function createCommandMethods(editor: Editor) { return /^[-*+]\s/.test(lineText); }, }; + + return methods; } From 498c1421983feface8b1bee2981eb9521bcc56fb Mon Sep 17 00:00:00 2001 From: robin Date: Tue, 16 Dec 2025 15:07:29 +0800 Subject: [PATCH 28/92] feat(editor): rename WYSIWYG editor to Rich editor and implement new RichEditor component - Updated the editor mode from WYSIWYG to Rich in the MDEditor component. - Introduced a new RichEditor component utilizing TipTap for enhanced editing capabilities. - Adjusted styles and references in the editor components to reflect the new naming convention. --- .../Editor/{WysiwygEditor.tsx => RichEditor.tsx} | 8 ++++---- ui/src/components/Editor/index.scss | 3 +-- ui/src/components/Editor/index.tsx | 16 ++++++++-------- ui/src/components/Editor/utils/tiptap/adapter.ts | 2 +- 4 files changed, 14 insertions(+), 15 deletions(-) rename ui/src/components/Editor/{WysiwygEditor.tsx => RichEditor.tsx} (96%) diff --git a/ui/src/components/Editor/WysiwygEditor.tsx b/ui/src/components/Editor/RichEditor.tsx similarity index 96% rename from ui/src/components/Editor/WysiwygEditor.tsx rename to ui/src/components/Editor/RichEditor.tsx index 7ddb28368..c574551c6 100644 --- a/ui/src/components/Editor/WysiwygEditor.tsx +++ b/ui/src/components/Editor/RichEditor.tsx @@ -33,7 +33,7 @@ import { TableKit } from '@tiptap/extension-table'; import { Editor } from './types'; import { createTipTapAdapter } from './utils/tiptap/adapter'; -interface WysiwygEditorProps { +interface RichEditorProps { value: string; onChange?: (value: string) => void; onFocus?: () => void; @@ -43,7 +43,7 @@ interface WysiwygEditorProps { onEditorReady?: (editor: Editor) => void; } -const WysiwygEditor: React.FC = ({ +const RichEditor: React.FC = ({ value, onChange, onFocus, @@ -153,10 +153,10 @@ const WysiwygEditor: React.FC = ({ } return ( -
        +
        ); }; -export default WysiwygEditor; +export default RichEditor; diff --git a/ui/src/components/Editor/index.scss b/ui/src/components/Editor/index.scss index 20ab5bab4..4775e84a5 100644 --- a/ui/src/components/Editor/index.scss +++ b/ui/src/components/Editor/index.scss @@ -114,8 +114,7 @@ height: 264px; } - // WYSIWYG 编辑器样式 - .wysiwyg-editor-wrap { + .rich-editor-wrap { height: 264px; overflow-y: auto; padding: 0.375rem 0.75rem; diff --git a/ui/src/components/Editor/index.tsx b/ui/src/components/Editor/index.tsx index 94bd5836e..c293fa653 100644 --- a/ui/src/components/Editor/index.tsx +++ b/ui/src/components/Editor/index.tsx @@ -51,7 +51,7 @@ import { import { htmlRender } from './utils'; import Viewer from './Viewer'; import { EditorContext } from './EditorContext'; -import WysiwygEditor from './WysiwygEditor'; +import RichEditor from './RichEditor'; import MarkdownEditor from './MarkdownEditor'; import { Editor } from './types'; @@ -86,14 +86,14 @@ const MDEditor: ForwardRefRenderFunction = ( }, ref, ) => { - const [mode, setMode] = useState<'markdown' | 'wysiwyg'>('markdown'); + const [mode, setMode] = useState<'markdown' | 'rich'>('markdown'); const [currentEditor, setCurrentEditor] = useState(null); const previewRef = useRef<{ getHtml; element } | null>(null); useRenderPlugin(previewRef.current?.element); const handleModeChange = useCallback( - (newMode: 'markdown' | 'wysiwyg') => { + (newMode: 'markdown' | 'rich') => { if (newMode === mode) { return; } @@ -116,7 +116,7 @@ const MDEditor: ForwardRefRenderFunction = ( [getHtml], ); - const EditorComponent = mode === 'markdown' ? MarkdownEditor : WysiwygEditor; + const EditorComponent = mode === 'markdown' ? MarkdownEditor : RichEditor; return ( <> @@ -155,17 +155,17 @@ const MDEditor: ForwardRefRenderFunction = ( className={`btn btn-sm ${ mode === 'markdown' ? 'btn-primary' : 'btn-outline-secondary' }`} - title="Markdown 模式" + title="Markdown Mode" onClick={() => handleModeChange('markdown')}>
        diff --git a/ui/src/components/Editor/utils/tiptap/adapter.ts b/ui/src/components/Editor/utils/tiptap/adapter.ts index 862cbf6c2..415edb175 100644 --- a/ui/src/components/Editor/utils/tiptap/adapter.ts +++ b/ui/src/components/Editor/utils/tiptap/adapter.ts @@ -29,7 +29,7 @@ import { createCommandMethods } from './commands'; * Adapts TipTap editor to CodeMirror editor interface * * This adapter function converts TipTap editor's API to a CodeMirror-compatible interface, - * enabling toolbar components to work properly in WYSIWYG mode. The adapter implements + * enabling toolbar components to work properly in Rich mode. The adapter implements * the complete `ExtendEditor` interface, including base methods, event handling, and command methods. * * @param editor - TipTap editor instance From d87726bd6e54e4fc88f8338f6f6499f878b00c4f Mon Sep 17 00:00:00 2001 From: robin Date: Wed, 17 Dec 2025 10:38:31 +0800 Subject: [PATCH 29/92] refactor(editor): enhance editor components with base props and initialization logic - Introduced BaseEditorProps interface to standardize props across MarkdownEditor and RichEditor components. - Improved initialization logic in RichEditor and MarkdownEditor to handle editor state more effectively. - Updated useEditor hook to support initial values and prevent unnecessary updates during prop changes. - Refactored command methods to utilize dispatch for state changes in CodeMirror editor. --- ui/src/components/Editor/MarkdownEditor.tsx | 33 ++-- ui/src/components/Editor/RichEditor.tsx | 137 +++++++------ ui/src/components/Editor/ToolBars/chart.tsx | 181 ------------------ ui/src/components/Editor/ToolBars/index.ts | 2 - ui/src/components/Editor/index.tsx | 5 +- ui/src/components/Editor/types.ts | 15 +- .../Editor/utils/codemirror/commands.ts | 16 +- ui/src/components/Editor/utils/index.ts | 26 ++- .../components/Editor/utils/tiptap/events.ts | 8 +- 9 files changed, 145 insertions(+), 278 deletions(-) delete mode 100644 ui/src/components/Editor/ToolBars/chart.tsx diff --git a/ui/src/components/Editor/MarkdownEditor.tsx b/ui/src/components/Editor/MarkdownEditor.tsx index fe5d8bb44..068a408f7 100644 --- a/ui/src/components/Editor/MarkdownEditor.tsx +++ b/ui/src/components/Editor/MarkdownEditor.tsx @@ -21,18 +21,10 @@ import { useEffect, useRef } from 'react'; import { EditorView } from '@codemirror/view'; -import { Editor } from './types'; +import { BaseEditorProps } from './types'; import { useEditor } from './utils'; -interface MarkdownEditorProps { - value: string; - onChange?: (value: string) => void; - onFocus?: () => void; - onBlur?: () => void; - placeholder?: string; - autoFocus?: boolean; - onEditorReady?: (editor: Editor) => void; -} +interface MarkdownEditorProps extends BaseEditorProps {} const MarkdownEditor: React.FC = ({ value, @@ -45,6 +37,7 @@ const MarkdownEditor: React.FC = ({ }) => { const editorRef = useRef(null); const lastSyncedValueRef = useRef(value); + const isInitializedRef = useRef(false); const editor = useEditor({ editorRef, @@ -53,24 +46,20 @@ const MarkdownEditor: React.FC = ({ onBlur, placeholder, autoFocus, + initialValue: value, }); useEffect(() => { - if (!editor) { + if (!editor || isInitializedRef.current) { return; } - editor.setValue(value || ''); - lastSyncedValueRef.current = value || ''; + isInitializedRef.current = true; onEditorReady?.(editor); - }, [editor]); + }, [editor, onEditorReady]); useEffect(() => { - if (!editor) { - return; - } - - if (value === lastSyncedValueRef.current) { + if (!editor || value === lastSyncedValueRef.current) { return; } @@ -82,6 +71,9 @@ const MarkdownEditor: React.FC = ({ }, [editor, value]); useEffect(() => { + lastSyncedValueRef.current = value; + isInitializedRef.current = false; + return () => { if (editor) { const view = editor as unknown as EditorView; @@ -89,8 +81,9 @@ const MarkdownEditor: React.FC = ({ view.destroy(); } } + isInitializedRef.current = false; }; - }, [editor]); + }, []); return (
        diff --git a/ui/src/components/Editor/RichEditor.tsx b/ui/src/components/Editor/RichEditor.tsx index c574551c6..916c82492 100644 --- a/ui/src/components/Editor/RichEditor.tsx +++ b/ui/src/components/Editor/RichEditor.tsx @@ -30,18 +30,10 @@ import { Markdown } from '@tiptap/markdown'; import Image from '@tiptap/extension-image'; import { TableKit } from '@tiptap/extension-table'; -import { Editor } from './types'; +import { Editor, BaseEditorProps } from './types'; import { createTipTapAdapter } from './utils/tiptap/adapter'; -interface RichEditorProps { - value: string; - onChange?: (value: string) => void; - onFocus?: () => void; - onBlur?: () => void; - placeholder?: string; - autoFocus?: boolean; - onEditorReady?: (editor: Editor) => void; -} +interface RichEditorProps extends BaseEditorProps {} const RichEditor: React.FC = ({ value, @@ -53,14 +45,60 @@ const RichEditor: React.FC = ({ onEditorReady, }) => { const lastSyncedValueRef = useRef(value); - const adaptedEditorRef = useRef(null); + const isInitializedRef = useRef(false); + const isUpdatingFromPropsRef = useRef(false); + const onEditorReadyRef = useRef(onEditorReady); + const autoFocusRef = useRef(autoFocus); + const initialValueRef = useRef(value); + + useEffect(() => { + onEditorReadyRef.current = onEditorReady; + autoFocusRef.current = autoFocus; + }, [onEditorReady, autoFocus]); + + const isViewAvailable = (editorInstance: TipTapEditor | null): boolean => { + if (!editorInstance) { + return false; + } + if (editorInstance.isDestroyed) { + return false; + } + return !!(editorInstance.view && editorInstance.state); + }; + + const handleCreate = useCallback( + ({ editor: editorInstance }: { editor: TipTapEditor }) => { + if (isInitializedRef.current || !isViewAvailable(editorInstance)) { + return; + } + + isInitializedRef.current = true; + + const initialValue = initialValueRef.current; + if (initialValue && initialValue.trim() !== '') { + editorInstance.commands.setContent(initialValue, { + contentType: 'markdown', + }); + lastSyncedValueRef.current = initialValue; + } + + adaptedEditorRef.current = createTipTapAdapter(editorInstance); + onEditorReadyRef.current?.(adaptedEditorRef.current); + + if (autoFocusRef.current) { + editorInstance.commands.focus(); + } + }, + [], + ); const handleUpdate = useCallback( ({ editor: editorInstance }: { editor: TipTapEditor }) => { - if (onChange) { + if (onChange && !isUpdatingFromPropsRef.current) { const markdown = editorInstance.getMarkdown(); onChange(markdown); + lastSyncedValueRef.current = markdown; } }, [onChange], @@ -84,7 +122,7 @@ const RichEditor: React.FC = ({ placeholder, }), ], - content: value || '', + onCreate: handleCreate, onUpdate: handleUpdate, onFocus: handleFocus, onBlur: handleBlur, @@ -96,67 +134,56 @@ const RichEditor: React.FC = ({ }); useEffect(() => { - if (!editor) { + if ( + !editor || + !isInitializedRef.current || + !isViewAvailable(editor) || + value === lastSyncedValueRef.current + ) { return; } - const checkEditorReady = () => { - if (editor.view && editor.view.dom) { + try { + const currentMarkdown = editor.getMarkdown(); + if (currentMarkdown !== value) { + isUpdatingFromPropsRef.current = true; if (value && value.trim() !== '') { editor.commands.setContent(value, { contentType: 'markdown' }); } else { editor.commands.clearContent(); } lastSyncedValueRef.current = value || ''; - if (!adaptedEditorRef.current) { - adaptedEditorRef.current = createTipTapAdapter(editor); - } - onEditorReady?.(adaptedEditorRef.current); - } else { - setTimeout(checkEditorReady, 10); + setTimeout(() => { + isUpdatingFromPropsRef.current = false; + }, 0); } - }; - - checkEditorReady(); - }, [editor]); - - useEffect(() => { - if (!editor) { - return; - } - - if (value === lastSyncedValueRef.current) { - return; - } - - const currentMarkdown = editor.getMarkdown(); - if (currentMarkdown !== value) { - if (value && value.trim() !== '') { - editor.commands.setContent(value, { contentType: 'markdown' }); - } else { - editor.commands.clearContent(); - } - lastSyncedValueRef.current = value || ''; + } catch (error) { + console.warn('Editor view not available when syncing value:', error); } }, [editor, value]); useEffect(() => { - if (editor && autoFocus) { - setTimeout(() => { - editor.commands.focus(); - }, 100); - } - }, [editor, autoFocus]); + initialValueRef.current = value; + lastSyncedValueRef.current = value; + isInitializedRef.current = false; + adaptedEditorRef.current = null; + isUpdatingFromPropsRef.current = false; + + return () => { + if (editor) { + editor.destroy(); + } + isInitializedRef.current = false; + adaptedEditorRef.current = null; + isUpdatingFromPropsRef.current = false; + }; + }, [editor]); if (!editor) { return
        Loading editor...
        ; } - return ( -
        - -
        - ); + return ; }; export default RichEditor; diff --git a/ui/src/components/Editor/ToolBars/chart.tsx b/ui/src/components/Editor/ToolBars/chart.tsx deleted file mode 100644 index a26a56388..000000000 --- a/ui/src/components/Editor/ToolBars/chart.tsx +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { FC, useEffect, useState, memo } from 'react'; -import { Dropdown } from 'react-bootstrap'; -import { useTranslation } from 'react-i18next'; - -import ToolItem from '../toolItem'; -import { IEditorContext } from '../types'; - -const Chart: FC = ({ editor }) => { - const { t } = useTranslation('translation', { keyPrefix: 'editor' }); - - const headerList = [ - { - label: t('chart.flow_chart'), - tpl: `graph TD - A[Christmas] -->|Get money| B(Go shopping) - B --> C{Let me think} - C -->|One| D[Laptop] - C -->|Two| E[iPhone] - C -->|Three| F[fa:fa-car Car]`, - }, - { - label: t('chart.sequence_diagram'), - tpl: `sequenceDiagram - Alice->>+John: Hello John, how are you? - Alice->>+John: John, can you hear me? - John-->>-Alice: Hi Alice, I can hear you! - John-->>-Alice: I feel great! - `, - }, - { - label: t('chart.state_diagram'), - tpl: `stateDiagram-v2 - [*] --> Still - Still --> [*] - Still --> Moving - Moving --> Still - Moving --> Crash - Crash --> [*] - `, - }, - { - label: t('chart.class_diagram'), - tpl: `classDiagram - Animal <|-- Duck - Animal <|-- Fish - Animal <|-- Zebra - Animal : +int age - Animal : +String gender - Animal: +isMammal() - Animal: +mate() - class Duck{ - +String beakColor - +swim() - +quack() - } - class Fish{ - -int sizeInFeet - -canEat() - } - class Zebra{ - +bool is_wild - +run() - } - `, - }, - { - label: t('chart.pie_chart'), - tpl: `pie title Pets adopted by volunteers - "Dogs" : 386 - "Cats" : 85 - "Rats" : 15 - `, - }, - { - label: t('chart.gantt_chart'), - tpl: `gantt - title A Gantt Diagram - dateFormat YYYY-MM-DD - section Section - A task :a1, 2014-01-01, 30d - Another task :after a1 , 20d - section Another - Task in sec :2014-01-12 , 12d - another task : 24d - `, - }, - { - label: t('chart.entity_relationship_diagram'), - tpl: `erDiagram - CUSTOMER }|..|{ DELIVERY-ADDRESS : has - CUSTOMER ||--o{ ORDER : places - CUSTOMER ||--o{ INVOICE : "liable for" - DELIVERY-ADDRESS ||--o{ ORDER : receives - INVOICE ||--|{ ORDER : covers - ORDER ||--|{ ORDER-ITEM : includes - PRODUCT-CATEGORY ||--|{ PRODUCT : contains - PRODUCT ||--o{ ORDER-ITEM : "ordered in" - `, - }, - ]; - const item = { - label: 'chart', - tip: `${t('chart.text')}`, - }; - const [isShow, setShowState] = useState(false); - const [isLocked, setLockState] = useState(false); - - useEffect(() => { - if (!editor) { - return; - } - editor.on('focus', () => { - setShowState(false); - }); - }, []); - - const click = (tpl) => { - const { ch } = editor.getCursor(); - - editor.replaceSelection(`${ch ? '\n' : ''}\`\`\`mermaid\n${tpl}\n\`\`\`\n`); - }; - - const onAddHeader = () => { - setShowState(!isShow); - }; - const handleMouseEnter = () => { - if (isLocked) { - return; - } - setLockState(true); - }; - - const handleMouseLeave = () => { - setLockState(false); - }; - return ( - - - {headerList.map((header) => { - return ( - { - e.preventDefault(); - click(header.tpl); - }}> - {header.label} - - ); - })} - - - ); -}; - -export default memo(Chart); diff --git a/ui/src/components/Editor/ToolBars/index.ts b/ui/src/components/Editor/ToolBars/index.ts index 05912bc6e..c3fa24be4 100644 --- a/ui/src/components/Editor/ToolBars/index.ts +++ b/ui/src/components/Editor/ToolBars/index.ts @@ -31,7 +31,6 @@ import Link from './link'; import BlockQuote from './blockquote'; import Image from './image'; import Help from './help'; -import Chart from './chart'; import File from './file'; export { @@ -49,6 +48,5 @@ export { BlockQuote, Image, Help, - Chart, File, }; diff --git a/ui/src/components/Editor/index.tsx b/ui/src/components/Editor/index.tsx index c293fa653..eb798c9df 100644 --- a/ui/src/components/Editor/index.tsx +++ b/ui/src/components/Editor/index.tsx @@ -98,10 +98,10 @@ const MDEditor: ForwardRefRenderFunction = ( return; } - setMode(newMode); setCurrentEditor(null); + setMode(newMode); }, - [mode, currentEditor], + [mode], ); const getHtml = useCallback(() => { @@ -172,6 +172,7 @@ const MDEditor: ForwardRefRenderFunction = (
        { onChange?.(markdown); diff --git a/ui/src/components/Editor/types.ts b/ui/src/components/Editor/types.ts index 926d3c203..e7d230819 100644 --- a/ui/src/components/Editor/types.ts +++ b/ui/src/components/Editor/types.ts @@ -116,11 +116,12 @@ export interface CodeMirrorEditor extends Editor { moduleType; } -// @deprecated 已废弃,请直接使用 Editor 接口 -// 保留此接口仅用于向后兼容,新代码不应使用 -export interface IEditorContext { - editor: Editor; - wrapText?; - replaceLines?; - appendBlock?; +export interface BaseEditorProps { + value: string; + onChange?: (value: string) => void; + onFocus?: () => void; + onBlur?: () => void; + placeholder?: string; + autoFocus?: boolean; + onEditorReady?: (editor: Editor) => void; } diff --git a/ui/src/components/Editor/utils/codemirror/commands.ts b/ui/src/components/Editor/utils/codemirror/commands.ts index 152bc632d..546382d46 100644 --- a/ui/src/components/Editor/utils/codemirror/commands.ts +++ b/ui/src/components/Editor/utils/codemirror/commands.ts @@ -69,14 +69,26 @@ export function createCommandMethods(editor: Editor) { const newLines = lines.map(replace) as string[]; const newText = newLines.join('\n'); - editor.setValue(newText); + editor.dispatch({ + changes: { + from: 0, + to: editor.state.doc.length, + insert: newText, + }, + }); }, appendBlock: (content: string) => { const { doc } = editor.state; const currentText = doc.toString(); const newText = currentText ? `${currentText}\n\n${content}` : content; - editor.setValue(newText); + editor.dispatch({ + changes: { + from: 0, + to: editor.state.doc.length, + insert: newText, + }, + }); }, insertBold: (text?: string) => { diff --git a/ui/src/components/Editor/utils/index.ts b/ui/src/components/Editor/utils/index.ts index 938b37613..5ba7192ca 100644 --- a/ui/src/components/Editor/utils/index.ts +++ b/ui/src/components/Editor/utils/index.ts @@ -17,7 +17,7 @@ * under the License. */ -import { useEffect, useState } from 'react'; +import { useEffect, useState, useRef } from 'react'; import { minimalSetup } from 'codemirror'; import { EditorState, Compartment } from '@codemirror/state'; @@ -129,12 +129,14 @@ export const useEditor = ({ editorRef, placeholder: placeholderText, autoFocus, + initialValue, onChange, onFocus, onBlur, }) => { const [editor, setEditor] = useState(null); - const [value, setValue] = useState(''); + const isInternalUpdateRef = useRef(false); + const init = async () => { const isDark = isDarkTheme(); @@ -162,6 +164,7 @@ export const useEditor = ({ }); const startState = EditorState.create({ + doc: initialValue || '', extensions: [ minimalSetup, markdown({ @@ -206,9 +209,20 @@ export const useEditor = ({ }, 10); } + const originalSetValue = cm.setValue; + cm.setValue = (newValue: string) => { + isInternalUpdateRef.current = true; + originalSetValue.call(cm, newValue); + setTimeout(() => { + isInternalUpdateRef.current = false; + }, 0); + }; + cm.on('change', () => { - const newValue = cm.getValue(); - setValue(newValue); + if (!isInternalUpdateRef.current && onChange) { + const newValue = cm.getValue(); + onChange(newValue); + } }); cm.on('focus', () => { @@ -224,10 +238,6 @@ export const useEditor = ({ return cm; }; - useEffect(() => { - onChange?.(value); - }, [value]); - useEffect(() => { if (!editorRef.current) { return; diff --git a/ui/src/components/Editor/utils/tiptap/events.ts b/ui/src/components/Editor/utils/tiptap/events.ts index 495ee6e57..2a86440de 100644 --- a/ui/src/components/Editor/utils/tiptap/events.ts +++ b/ui/src/components/Editor/utils/tiptap/events.ts @@ -25,7 +25,13 @@ import { logWarning } from './errorHandler'; * Checks if editor view is available */ function isViewAvailable(editor: TipTapEditor): boolean { - return !!(editor.view && editor.view.dom); + if (!editor) { + return false; + } + if (editor.isDestroyed) { + return false; + } + return !!(editor.view && editor.state); } /** From 7a4b57d1ffdb0b2980e8dc9b46e74b12b9e22cba Mon Sep 17 00:00:00 2001 From: robin Date: Wed, 17 Dec 2025 10:50:36 +0800 Subject: [PATCH 30/92] refactor(editor): improve editor component functionality and code clarity - Updated ToolItem component to ensure consistent return type for command functions. - Modified heading toolbar to allow optional label parameter in handleClick function. - Enhanced image component comments for clarity on editor state updates and event listener management. - Cleaned up utility functions in htmlRender to remove unnecessary comments and improve readability. --- ui/src/components/Editor/ToolBars/heading.tsx | 2 +- ui/src/components/Editor/ToolBars/image.tsx | 10 ++++------ ui/src/components/Editor/toolItem.tsx | 2 +- ui/src/components/Editor/types.ts | 9 --------- ui/src/components/Editor/utils/index.ts | 2 -- 5 files changed, 6 insertions(+), 19 deletions(-) diff --git a/ui/src/components/Editor/ToolBars/heading.tsx b/ui/src/components/Editor/ToolBars/heading.tsx index 4b49212cb..bcce69aef 100644 --- a/ui/src/components/Editor/ToolBars/heading.tsx +++ b/ui/src/components/Editor/ToolBars/heading.tsx @@ -62,7 +62,7 @@ const Heading = () => { const [isLocked, setLockState] = useState(false); const [currentEditor, setCurrentEditor] = useState(null); - const handleClick = (level: Level = 2, label = '大标题') => { + const handleClick = (level: Level = 2, label?: string) => { if (!currentEditor) { return; } diff --git a/ui/src/components/Editor/ToolBars/image.tsx b/ui/src/components/Editor/ToolBars/image.tsx index 67a79b3ca..52b2e5461 100644 --- a/ui/src/components/Editor/ToolBars/image.tsx +++ b/ui/src/components/Editor/ToolBars/image.tsx @@ -32,8 +32,8 @@ const Image = () => { const editor = useContext(EditorContext); const [editorState, setEditorState] = useState(editor); - // 当 editor 改变时,更新 editor state - // 这样切换编辑器模式时,事件监听器会重新绑定 + // Update editor state when editor context changes + // This ensures event listeners are re-bound when switching editor modes useEffect(() => { if (editor) { setEditorState(editor); @@ -329,20 +329,18 @@ const Image = () => { if (!editorState) { return undefined; } - // 绑定事件监听器 + editorState.on('dragenter', dragenter); editorState.on('dragover', dragover); editorState.on('drop', drop); editorState.on('paste', paste); + return () => { - // 清理事件监听器 editorState.off('dragenter', dragenter); editorState.off('dragover', dragover); editorState.off('drop', drop); editorState.off('paste', paste); }; - // 注意:dragenter, dragover, drop, paste 函数在组件生命周期内是稳定的 - // 它们不依赖任何会变化的值,所以不需要加入依赖项 }, [editorState]); useEffect(() => { diff --git a/ui/src/components/Editor/toolItem.tsx b/ui/src/components/Editor/toolItem.tsx index c0fdf1757..39f82d700 100644 --- a/ui/src/components/Editor/toolItem.tsx +++ b/ui/src/components/Editor/toolItem.tsx @@ -63,7 +63,7 @@ const ToolItem: FC = (props) => { editor?.addKeyMap({ [key]: () => { onClick?.(editor); - return true; // Command 类型要求返回 boolean + return true; }, }); }); diff --git a/ui/src/components/Editor/types.ts b/ui/src/components/Editor/types.ts index e7d230819..48f69322c 100644 --- a/ui/src/components/Editor/types.ts +++ b/ui/src/components/Editor/types.ts @@ -61,7 +61,6 @@ export interface ExtendEditor { setSelection: (anchor: Position, head?: Position) => void; setReadOnly: (readOnly: boolean) => void; - // 底层方法(供编辑器内部使用,不推荐工具栏直接使用) wrapText: (before: string, after?: string, defaultText?: string) => void; replaceLines: ( replace: Parameters['map']>[0], @@ -69,37 +68,29 @@ export interface ExtendEditor { ) => void; appendBlock: (content: string) => void; - // 语义化高级方法(工具栏推荐使用) - // 文本格式 insertBold: (text?: string) => void; insertItalic: (text?: string) => void; insertCode: (text?: string) => void; insertStrikethrough: (text?: string) => void; - // 块级元素 insertHeading: (level: Level, text?: string) => void; insertBlockquote: (text?: string) => void; insertCodeBlock: (language?: string, code?: string) => void; insertHorizontalRule: () => void; - // 列表 insertOrderedList: () => void; insertUnorderedList: () => void; toggleOrderedList: () => void; toggleUnorderedList: () => void; - // 链接和媒体 insertLink: (url: string, text?: string) => void; insertImage: (url: string, alt?: string) => void; - // 表格 insertTable: (rows?: number, cols?: number) => void; - // 缩进 indent: () => void; outdent: () => void; - // 状态查询 isBold: () => boolean; isItalic: () => boolean; isHeading: (level?: number) => boolean; diff --git a/ui/src/components/Editor/utils/index.ts b/ui/src/components/Editor/utils/index.ts index 5ba7192ca..eb4ad16e1 100644 --- a/ui/src/components/Editor/utils/index.ts +++ b/ui/src/components/Editor/utils/index.ts @@ -95,10 +95,8 @@ export function htmlRender(el: HTMLElement | null, config?: htmlRenderConfig) { `; codeTool.innerHTML = str; - // Add copy button to pre tag pre.style.position = 'relative'; - // 将 codeTool 和 pre 插入到 codeWrap 中, 并且使用 codeWrap 替换 pre codeWrap.appendChild(codeTool); pre.parentNode?.replaceChild(codeWrap, pre); codeWrap.appendChild(pre); From ffa8dc2bb85956f07f4d1c20616c1524832f1571 Mon Sep 17 00:00:00 2001 From: robin Date: Wed, 17 Dec 2025 14:20:09 +0800 Subject: [PATCH 31/92] feat(editor): update TipTap dependencies and enhance table functionality - Added @tiptap/core version 3.13.0 to package.json and updated related dependencies in pnpm-lock.yaml. - Refactored RichEditor to utilize new table extension with responsive wrapper and improved styling. - Adjusted editor mode initialization in MDEditor to default to 'rich' for enhanced user experience. - Removed redundant styles from index.scss to streamline the editor's appearance. --- ui/package.json | 1 + ui/pnpm-lock.yaml | 193 +++++++++--------- ui/src/components/Editor/RichEditor.tsx | 23 ++- ui/src/components/Editor/index.scss | 76 ------- ui/src/components/Editor/index.tsx | 4 +- .../Editor/utils/tiptap/tableExtension.ts | 81 ++++++++ 6 files changed, 202 insertions(+), 176 deletions(-) create mode 100644 ui/src/components/Editor/utils/tiptap/tableExtension.ts diff --git a/ui/package.json b/ui/package.json index 5a6704ceb..a771c39e3 100644 --- a/ui/package.json +++ b/ui/package.json @@ -21,6 +21,7 @@ "@codemirror/language-data": "^6.5.0", "@codemirror/state": "^6.5.0", "@codemirror/view": "^6.26.1", + "@tiptap/core": "^3.13.0", "@tiptap/extension-image": "^3.11.1", "@tiptap/extension-placeholder": "^3.11.1", "@tiptap/extension-table": "^3.11.1", diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index 83c706312..cbbed7e8f 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -20,21 +20,24 @@ importers: '@codemirror/view': specifier: ^6.26.1 version: 6.35.3 + '@tiptap/core': + specifier: ^3.13.0 + version: 3.13.0(@tiptap/pm@3.11.1) '@tiptap/extension-image': specifier: ^3.11.1 - version: 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) + version: 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1)) '@tiptap/extension-placeholder': specifier: ^3.11.1 - version: 3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + version: 3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) '@tiptap/extension-table': specifier: ^3.11.1 - version: 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + version: 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) '@tiptap/markdown': specifier: ^3.11.1 - version: 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + version: 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) '@tiptap/react': specifier: ^3.11.1 - version: 3.11.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.11.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tiptap/starter-kit': specifier: ^3.11.1 version: 3.11.1 @@ -1714,10 +1717,10 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' - '@tiptap/core@3.11.1': - resolution: {integrity: sha512-q7uzYrCq40JOIi6lceWe2HuA8tSr97iPwP/xtJd0bZjyL1rWhUyqxMb7y+aq4RcELrx/aNRa2JIvLtRRdy02Dg==} + '@tiptap/core@3.13.0': + resolution: {integrity: sha512-iUelgiTMgPVMpY5ZqASUpk8mC8HuR9FWKaDzK27w9oWip9tuB54Z8mePTxNcQaSPb6ErzEaC8x8egrRt7OsdGQ==} peerDependencies: - '@tiptap/pm': ^3.11.1 + '@tiptap/pm': ^3.13.0 '@tiptap/extension-blockquote@3.11.1': resolution: {integrity: sha512-c3DN5c/9kl8w1wCcylH9XqW0OyCegqE3EL4rDlVYkyBD0GwCnUS30pN+jdxCUq/tl94lkkRk7XMyEUwzQmG+5g==} @@ -1805,10 +1808,10 @@ packages: '@tiptap/core': ^3.11.1 '@tiptap/pm': ^3.11.1 - '@tiptap/extension-list-item@3.11.1': - resolution: {integrity: sha512-KFw3TAwN6hQ+oDeE3lRqwzCRKhxU1NWf9q5SAwiUxlp/LcEjuhXcYJYX8SHPOLOlTo0P42v1i0KBeLUPKnO58g==} + '@tiptap/extension-list-item@3.13.0': + resolution: {integrity: sha512-63NbcS/XeQP2jcdDEnEAE3rjJICDj8y1SN1h/MsJmSt1LusnEo8WQ2ub86QELO6XnD3M04V03cY6Knf6I5mTkw==} peerDependencies: - '@tiptap/extension-list': ^3.11.1 + '@tiptap/extension-list': ^3.13.0 '@tiptap/extension-list-keymap@3.11.1': resolution: {integrity: sha512-MpeuVi+bOHulbN65bOjaeoNJstNuAAEPdLwNjW25c9y2a8b5iZFY8vdVNENDiqq+dI+F5EaFGaEq0FN0uslfiA==} @@ -9367,134 +9370,134 @@ snapshots: '@babel/runtime': 7.26.0 '@testing-library/dom': 8.20.1 - '@tiptap/core@3.11.1(@tiptap/pm@3.11.1)': + '@tiptap/core@3.13.0(@tiptap/pm@3.11.1)': dependencies: '@tiptap/pm': 3.11.1 - '@tiptap/extension-blockquote@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + '@tiptap/extension-blockquote@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) - '@tiptap/extension-bold@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + '@tiptap/extension-bold@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) - '@tiptap/extension-bubble-menu@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + '@tiptap/extension-bubble-menu@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': dependencies: '@floating-ui/dom': 1.7.4 - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) '@tiptap/pm': 3.11.1 optional: true - '@tiptap/extension-bullet-list@3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + '@tiptap/extension-bullet-list@3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/extension-list': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-list': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-code-block@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + '@tiptap/extension-code-block@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) '@tiptap/pm': 3.11.1 - '@tiptap/extension-code@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + '@tiptap/extension-code@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) - '@tiptap/extension-document@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + '@tiptap/extension-document@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) - '@tiptap/extension-dropcursor@3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + '@tiptap/extension-dropcursor@3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/extensions': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extensions': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-floating-menu@3.11.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + '@tiptap/extension-floating-menu@3.11.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': dependencies: '@floating-ui/dom': 1.7.4 - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) '@tiptap/pm': 3.11.1 optional: true - '@tiptap/extension-gapcursor@3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + '@tiptap/extension-gapcursor@3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/extensions': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extensions': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-hard-break@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + '@tiptap/extension-hard-break@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) - '@tiptap/extension-heading@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + '@tiptap/extension-heading@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) - '@tiptap/extension-horizontal-rule@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + '@tiptap/extension-horizontal-rule@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) '@tiptap/pm': 3.11.1 - '@tiptap/extension-image@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + '@tiptap/extension-image@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) - '@tiptap/extension-italic@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + '@tiptap/extension-italic@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) - '@tiptap/extension-link@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + '@tiptap/extension-link@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) '@tiptap/pm': 3.11.1 linkifyjs: 4.3.2 - '@tiptap/extension-list-item@3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + '@tiptap/extension-list-item@3.13.0(@tiptap/extension-list@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/extension-list': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-list': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-list-keymap@3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + '@tiptap/extension-list-keymap@3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/extension-list': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-list': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + '@tiptap/extension-list@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) '@tiptap/pm': 3.11.1 - '@tiptap/extension-ordered-list@3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + '@tiptap/extension-ordered-list@3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/extension-list': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-list': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-paragraph@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + '@tiptap/extension-paragraph@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) - '@tiptap/extension-placeholder@3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': + '@tiptap/extension-placeholder@3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/extensions': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extensions': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-strike@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + '@tiptap/extension-strike@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) - '@tiptap/extension-table@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + '@tiptap/extension-table@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) '@tiptap/pm': 3.11.1 - '@tiptap/extension-text@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + '@tiptap/extension-text@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) - '@tiptap/extension-underline@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))': + '@tiptap/extension-underline@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) - '@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + '@tiptap/extensions@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) '@tiptap/pm': 3.11.1 - '@tiptap/markdown@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': + '@tiptap/markdown@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) '@tiptap/pm': 3.11.1 marked: 15.0.12 @@ -9519,9 +9522,9 @@ snapshots: prosemirror-transform: 1.10.5 prosemirror-view: 1.41.3 - '@tiptap/react@3.11.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@tiptap/react@3.11.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) '@tiptap/pm': 3.11.1 '@types/react': 18.3.16 '@types/react-dom': 18.3.5(@types/react@18.3.16) @@ -9531,36 +9534,36 @@ snapshots: react-dom: 18.3.1(react@18.3.1) use-sync-external-store: 1.6.0(react@18.3.1) optionalDependencies: - '@tiptap/extension-bubble-menu': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-floating-menu': 3.11.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-bubble-menu': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-floating-menu': 3.11.1(@floating-ui/dom@1.7.4)(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) transitivePeerDependencies: - '@floating-ui/dom' '@tiptap/starter-kit@3.11.1': dependencies: - '@tiptap/core': 3.11.1(@tiptap/pm@3.11.1) - '@tiptap/extension-blockquote': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) - '@tiptap/extension-bold': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) - '@tiptap/extension-bullet-list': 3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) - '@tiptap/extension-code': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) - '@tiptap/extension-code-block': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-document': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) - '@tiptap/extension-dropcursor': 3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) - '@tiptap/extension-gapcursor': 3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) - '@tiptap/extension-hard-break': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) - '@tiptap/extension-heading': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) - '@tiptap/extension-horizontal-rule': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-italic': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) - '@tiptap/extension-link': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-list': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) - '@tiptap/extension-list-item': 3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) - '@tiptap/extension-list-keymap': 3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) - '@tiptap/extension-ordered-list': 3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) - '@tiptap/extension-paragraph': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) - '@tiptap/extension-strike': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) - '@tiptap/extension-text': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) - '@tiptap/extension-underline': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1)) - '@tiptap/extensions': 3.11.1(@tiptap/core@3.11.1(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/core': 3.13.0(@tiptap/pm@3.11.1) + '@tiptap/extension-blockquote': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1)) + '@tiptap/extension-bold': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1)) + '@tiptap/extension-bullet-list': 3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-code': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1)) + '@tiptap/extension-code-block': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-document': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1)) + '@tiptap/extension-dropcursor': 3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-gapcursor': 3.11.1(@tiptap/extensions@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-hard-break': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1)) + '@tiptap/extension-heading': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1)) + '@tiptap/extension-horizontal-rule': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-italic': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1)) + '@tiptap/extension-link': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-list': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) + '@tiptap/extension-list-item': 3.13.0(@tiptap/extension-list@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-list-keymap': 3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-ordered-list': 3.11.1(@tiptap/extension-list@3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1)) + '@tiptap/extension-paragraph': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1)) + '@tiptap/extension-strike': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1)) + '@tiptap/extension-text': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1)) + '@tiptap/extension-underline': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1)) + '@tiptap/extensions': 3.11.1(@tiptap/core@3.13.0(@tiptap/pm@3.11.1))(@tiptap/pm@3.11.1) '@tiptap/pm': 3.11.1 '@tootallnate/once@1.1.2': {} diff --git a/ui/src/components/Editor/RichEditor.tsx b/ui/src/components/Editor/RichEditor.tsx index 916c82492..55fca5a99 100644 --- a/ui/src/components/Editor/RichEditor.tsx +++ b/ui/src/components/Editor/RichEditor.tsx @@ -28,10 +28,11 @@ import StarterKit from '@tiptap/starter-kit'; import Placeholder from '@tiptap/extension-placeholder'; import { Markdown } from '@tiptap/markdown'; import Image from '@tiptap/extension-image'; -import { TableKit } from '@tiptap/extension-table'; +import { TableRow, TableCell, TableHeader } from '@tiptap/extension-table'; import { Editor, BaseEditorProps } from './types'; import { createTipTapAdapter } from './utils/tiptap/adapter'; +import { TableWithWrapper } from './utils/tiptap/tableExtension'; interface RichEditorProps extends BaseEditorProps {} @@ -117,7 +118,23 @@ const RichEditor: React.FC = ({ StarterKit, Markdown, Image, - TableKit, + TableWithWrapper.configure({ + HTMLAttributes: { + class: 'table table-bordered', + style: { + width: '100%', + }, + }, + resizable: true, + wrapperClass: 'table-responsive', + }), + TableRow.configure({ + HTMLAttributes: { + class: 'table-row', + }, + }), + TableCell, + TableHeader, Placeholder.configure({ placeholder, }), @@ -128,7 +145,7 @@ const RichEditor: React.FC = ({ onBlur: handleBlur, editorProps: { attributes: { - class: 'tiptap-editor', + class: 'tiptap-editor fmt', }, }, }); diff --git a/ui/src/components/Editor/index.scss b/ui/src/components/Editor/index.scss index 4775e84a5..60a549aaf 100644 --- a/ui/src/components/Editor/index.scss +++ b/ui/src/components/Editor/index.scss @@ -139,82 +139,6 @@ height: 0; } } - - h1, - h2, - h3, - h4, - h5, - h6 { - margin: 1rem 0 0.5rem; - font-weight: 600; - line-height: 1.4; - } - - ul, - ol { - padding-left: 1.5rem; - margin: 0.5rem 0; - } - - li { - margin: 0.25rem 0; - } - - code { - background-color: var(--an-code-bg, #f4f4f4); - color: var(--an-code-color, #e83e8c); - padding: 0.2em 0.4em; - border-radius: 3px; - font-size: 0.9em; - } - - pre { - background-color: var(--an-code-block-bg, #f8f9fa); - border: 1px solid var(--an-ced4da); - border-radius: 4px; - padding: 1rem; - margin: 0.5rem 0; - overflow-x: auto; - - code { - background-color: transparent; - color: inherit; - padding: 0; - } - } - - blockquote { - border-left: 4px solid var(--an-primary, #0d6efd); - padding-left: 1rem; - margin: 0.5rem 0; - color: var(--an-text-secondary, #6c757d); - } - - a { - color: var(--an-link-color, #0d6efd); - text-decoration: underline; - - &:hover { - text-decoration: none; - } - } - - img { - max-width: 100%; - height: auto; - border-radius: 4px; - } - - hr { - border: none; - border-top: 1px solid var(--an-ced4da); - margin: 1rem 0; - } - - ::selection { - background-color: var(--an-selection-bg, rgba(0, 123, 255, 0.2)); - } } .editor-loading { diff --git a/ui/src/components/Editor/index.tsx b/ui/src/components/Editor/index.tsx index eb798c9df..91214ac3b 100644 --- a/ui/src/components/Editor/index.tsx +++ b/ui/src/components/Editor/index.tsx @@ -86,7 +86,7 @@ const MDEditor: ForwardRefRenderFunction = ( }, ref, ) => { - const [mode, setMode] = useState<'markdown' | 'rich'>('markdown'); + const [mode, setMode] = useState<'markdown' | 'rich'>('rich'); const [currentEditor, setCurrentEditor] = useState(null); const previewRef = useRef<{ getHtml; element } | null>(null); @@ -186,7 +186,7 @@ const MDEditor: ForwardRefRenderFunction = ( }} />
        - + {mode === 'markdown' && } ); }; diff --git a/ui/src/components/Editor/utils/tiptap/tableExtension.ts b/ui/src/components/Editor/utils/tiptap/tableExtension.ts new file mode 100644 index 000000000..70e68f77a --- /dev/null +++ b/ui/src/components/Editor/utils/tiptap/tableExtension.ts @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Table, TableOptions } from '@tiptap/extension-table'; +import type { NodeViewRendererProps } from '@tiptap/core'; + +interface TableWrapperOptions extends TableOptions { + wrapperClass?: string; +} + +export const TableWithWrapper = Table.extend({ + addOptions() { + const parentOptions = (this.parent?.() || {}) as Partial; + return { + ...parentOptions, + HTMLAttributes: parentOptions.HTMLAttributes || {}, + wrapperClass: 'table-responsive', + } as TableWrapperOptions; + }, + + addNodeView() { + return (props: NodeViewRendererProps) => { + const { node } = props; + const wrapperClass = this.options.wrapperClass || 'table-responsive'; + + const dom = document.createElement('div'); + dom.className = wrapperClass; + + const table = document.createElement('table'); + + const htmlAttrs = this.options.HTMLAttributes || {}; + if (htmlAttrs.class) { + table.className = htmlAttrs.class as string; + } + if (htmlAttrs.style && typeof htmlAttrs.style === 'object') { + Object.assign(table.style, htmlAttrs.style); + } + + const colgroup = document.createElement('colgroup'); + if (node.firstChild) { + const { childCount } = node.firstChild; + for (let i = 0; i < childCount; i += 1) { + const col = document.createElement('col'); + colgroup.appendChild(col); + } + } + table.appendChild(colgroup); + + const tbody = document.createElement('tbody'); + table.appendChild(tbody); + dom.appendChild(table); + + return { + dom, + contentDOM: tbody, + update: (updatedNode) => { + if (updatedNode.type !== node.type) { + return false; + } + return true; + }, + }; + }; + }, +}); From 1c2c733190376e62e8734918d542f61ebc3d9fa9 Mon Sep 17 00:00:00 2001 From: robin Date: Thu, 18 Dec 2025 10:43:59 +0800 Subject: [PATCH 32/92] feat(editor): enhance plugin system and improve command methods - Introduced PluginSlot component for better plugin insertion in the editor. - Updated MDEditor to default to 'markdown' mode for improved user experience. - Refactored command methods in TipTap to use chaining for better selection handling. - Enhanced PluginRender to load plugins asynchronously and prevent duplicate registrations. --- ui/src/components/Editor/index.tsx | 6 +- .../Editor/utils/tiptap/commands.ts | 20 ++-- ui/src/components/PluginRender/index.tsx | 105 +++++++++++++----- ui/src/utils/pluginKit/index.ts | 104 ++++++++++++++--- 4 files changed, 178 insertions(+), 57 deletions(-) diff --git a/ui/src/components/Editor/index.tsx b/ui/src/components/Editor/index.tsx index 91214ac3b..ebe04876c 100644 --- a/ui/src/components/Editor/index.tsx +++ b/ui/src/components/Editor/index.tsx @@ -29,7 +29,7 @@ import { import classNames from 'classnames'; import { PluginType, useRenderPlugin } from '@/utils/pluginKit'; -import PluginRender from '../PluginRender'; +import PluginRender, { PluginSlot } from '../PluginRender'; import { BlockQuote, @@ -86,7 +86,7 @@ const MDEditor: ForwardRefRenderFunction = ( }, ref, ) => { - const [mode, setMode] = useState<'markdown' | 'rich'>('rich'); + const [mode, setMode] = useState<'markdown' | 'rich'>('markdown'); const [currentEditor, setCurrentEditor] = useState(null); const previewRef = useRef<{ getHtml; element } | null>(null); @@ -145,10 +145,10 @@ const MDEditor: ForwardRefRenderFunction = (
        + -
        - -
        { onChange?.(markdown); @@ -186,7 +152,7 @@ const MDEditor: ForwardRefRenderFunction = ( }} />
        - {mode === 'markdown' && } + ); }; diff --git a/ui/src/components/Editor/utils/tiptap/adapter.ts b/ui/src/components/Editor/utils/tiptap/adapter.ts deleted file mode 100644 index 415edb175..000000000 --- a/ui/src/components/Editor/utils/tiptap/adapter.ts +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { Editor as TipTapEditor } from '@tiptap/react'; - -import { Editor, ExtendEditor } from '../../types'; - -import { createBaseMethods } from './base'; -import { createEventMethods } from './events'; -import { createCommandMethods } from './commands'; - -/** - * Adapts TipTap editor to CodeMirror editor interface - * - * This adapter function converts TipTap editor's API to a CodeMirror-compatible interface, - * enabling toolbar components to work properly in Rich mode. The adapter implements - * the complete `ExtendEditor` interface, including base methods, event handling, and command methods. - * - * @param editor - TipTap editor instance - * @returns Adapted editor instance that implements the unified Editor interface - * - * @example - * ```typescript - * const tipTapEditor = useEditor({ ... }); - * const adaptedEditor = createTipTapAdapter(tipTapEditor); - * // Now you can use the unified API - * adaptedEditor.insertBold('text'); - * adaptedEditor.insertHeading(1, 'Title'); - * ``` - */ -export function createTipTapAdapter(editor: TipTapEditor): Editor { - const baseMethods = createBaseMethods(editor); - const eventMethods = createEventMethods(editor); - const commandMethods = createCommandMethods(editor); - - const editorAdapter: ExtendEditor = { - ...baseMethods, - ...eventMethods, - ...commandMethods, - }; - - return editorAdapter as unknown as Editor; -} diff --git a/ui/src/components/Editor/utils/tiptap/base.ts b/ui/src/components/Editor/utils/tiptap/base.ts deleted file mode 100644 index e088a9f5d..000000000 --- a/ui/src/components/Editor/utils/tiptap/base.ts +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { Editor as TipTapEditor } from '@tiptap/react'; - -import { Position } from '../../types'; - -import { - safeExecuteCommand, - EditorErrorType, - handleEditorError, -} from './errorHandler'; -import { - convertTipTapPositionToCodeMirror, - convertCodeMirrorPositionToTipTap, -} from './position'; -import { MARKDOWN_PATTERNS } from './constants'; - -/** - * Creates base methods module - * - * Provides core base methods for the editor, including: - * - Content getter and setter (getValue, setValue) - * - Selection operations (getSelection, replaceSelection) - * - Cursor and selection position (getCursor, setSelection) - * - Read-only state control (setReadOnly) - * - * @param editor - TipTap editor instance - * @returns Object containing base methods - */ -export function createBaseMethods(editor: TipTapEditor) { - return { - getValue: () => { - return ( - safeExecuteCommand( - () => editor.getMarkdown(), - () => '', - EditorErrorType.COMMAND_EXECUTION_FAILED, - { function: 'getValue' }, - ) || '' - ); - }, - - setValue: (value: string) => { - safeExecuteCommand( - () => { - editor.commands.setContent(value, { contentType: 'markdown' }); - }, - undefined, - EditorErrorType.COMMAND_EXECUTION_FAILED, - { function: 'setValue', valueLength: value.length }, - ); - }, - - getSelection: () => { - const { from, to } = editor.state.selection; - return editor.state.doc.textBetween(from, to); - }, - - replaceSelection: (value: string) => { - const inlineCodeMatch = value.match(MARKDOWN_PATTERNS.INLINE_CODE); - if (inlineCodeMatch && value.length > 2) { - const codeText = inlineCodeMatch[1]; - safeExecuteCommand( - () => { - editor.commands.insertContent({ - type: 'text', - text: codeText, - marks: [{ type: 'code' }], - }); - }, - () => { - editor.commands.insertContent(value, { contentType: 'markdown' }); - }, - ); - return; - } - - const codeBlockMatch = value.match(MARKDOWN_PATTERNS.CODE_BLOCK); - if (codeBlockMatch) { - const [, , lang, codeText] = codeBlockMatch; - safeExecuteCommand( - () => { - editor.commands.insertContent({ - type: 'codeBlock', - attrs: lang ? { language: lang } : {}, - content: [ - { - type: 'text', - text: codeText, - }, - ], - }); - }, - () => { - editor.commands.insertContent(value, { contentType: 'markdown' }); - }, - ); - return; - } - - const imageMatch = value.match(MARKDOWN_PATTERNS.IMAGE); - if (imageMatch) { - const [, alt, url] = imageMatch; - safeExecuteCommand( - () => { - editor.commands.insertContent({ - type: 'image', - attrs: { - src: url, - alt: alt || '', - }, - }); - }, - () => { - editor.commands.insertContent(value, { contentType: 'markdown' }); - }, - ); - return; - } - - const linkMatch = value.match(MARKDOWN_PATTERNS.LINK); - if (linkMatch) { - const [, text, url] = linkMatch; - safeExecuteCommand( - () => { - editor.commands.insertContent({ - type: 'text', - text: text || url, - marks: [ - { - type: 'link', - attrs: { - href: url, - }, - }, - ], - }); - }, - () => { - editor.commands.insertContent(value, { contentType: 'markdown' }); - }, - ); - return; - } - - const autoLinkMatch = value.match(MARKDOWN_PATTERNS.AUTO_LINK); - if (autoLinkMatch && value.length > 2) { - const url = autoLinkMatch[1]; - safeExecuteCommand( - () => { - editor.commands.insertContent({ - type: 'text', - text: url, - marks: [ - { - type: 'link', - attrs: { - href: url, - }, - }, - ], - }); - }, - () => { - editor.commands.insertContent(value, { contentType: 'markdown' }); - }, - ); - return; - } - - if (MARKDOWN_PATTERNS.HORIZONTAL_RULE.test(value.trim())) { - safeExecuteCommand( - () => { - editor.commands.insertContent({ - type: 'horizontalRule', - }); - }, - () => { - editor.commands.insertContent(value, { contentType: 'markdown' }); - }, - ); - return; - } - - safeExecuteCommand(() => { - editor.commands.insertContent(value, { contentType: 'markdown' }); - }); - }, - - focus: () => { - editor.commands.focus(); - }, - - getCursor: () => { - try { - const { from } = editor.state.selection; - return convertTipTapPositionToCodeMirror(editor, from); - } catch (error) { - handleEditorError( - error as Error, - EditorErrorType.POSITION_CONVERSION_FAILED, - { - function: 'getCursor', - }, - ); - return { line: 0, ch: 0 }; - } - }, - - setSelection: (anchor?: unknown, head?: unknown) => { - try { - if ( - anchor && - typeof anchor === 'object' && - 'line' in anchor && - 'ch' in anchor - ) { - const anchorPos = convertCodeMirrorPositionToTipTap( - editor, - anchor as Position, - ); - let headPos = anchorPos; - - if ( - head && - typeof head === 'object' && - 'line' in head && - 'ch' in head - ) { - headPos = convertCodeMirrorPositionToTipTap( - editor, - head as Position, - ); - } - - safeExecuteCommand( - () => { - editor.commands.setTextSelection({ - from: anchorPos, - to: headPos, - }); - }, - undefined, - EditorErrorType.COMMAND_EXECUTION_FAILED, - { function: 'setSelection', anchorPos, headPos }, - ); - } else { - editor.commands.focus(); - } - } catch (error) { - handleEditorError( - error as Error, - EditorErrorType.COMMAND_EXECUTION_FAILED, - { - function: 'setSelection', - anchor, - head, - }, - ); - safeExecuteCommand( - () => { - editor.commands.focus(); - }, - undefined, - EditorErrorType.COMMAND_EXECUTION_FAILED, - { function: 'setSelection', isFallback: true }, - ); - } - }, - - setReadOnly: (readOnly: boolean) => { - editor.setEditable(!readOnly); - }, - - replaceRange: (value: string, from?: unknown, to?: unknown) => { - if (from && to && typeof from === 'object' && typeof to === 'object') { - const { from: currentFrom, to: currentTo } = editor.state.selection; - const imageMatch = value.match(MARKDOWN_PATTERNS.IMAGE); - if (imageMatch) { - const [, alt, url] = imageMatch; - safeExecuteCommand( - () => { - editor.commands.insertContentAt( - { from: currentFrom, to: currentTo }, - { - type: 'image', - attrs: { - src: url, - alt: alt || '', - }, - }, - ); - }, - () => { - editor.commands.insertContentAt( - { from: currentFrom, to: currentTo }, - value, - { contentType: 'markdown' }, - ); - }, - ); - return; - } - - safeExecuteCommand(() => { - editor.commands.insertContentAt( - { from: currentFrom, to: currentTo }, - value, - { contentType: 'markdown' }, - ); - }); - } else { - const imageMatch = value.match(MARKDOWN_PATTERNS.IMAGE); - if (imageMatch) { - const [, alt, url] = imageMatch; - safeExecuteCommand( - () => { - editor.commands.insertContent({ - type: 'image', - attrs: { - src: url, - alt: alt || '', - }, - }); - }, - () => { - editor.commands.insertContent(value, { - contentType: 'markdown', - }); - }, - ); - return; - } - - safeExecuteCommand(() => { - editor.commands.insertContent(value, { contentType: 'markdown' }); - }); - } - }, - }; -} diff --git a/ui/src/components/Editor/utils/tiptap/commands.ts b/ui/src/components/Editor/utils/tiptap/commands.ts deleted file mode 100644 index 08e2defc5..000000000 --- a/ui/src/components/Editor/utils/tiptap/commands.ts +++ /dev/null @@ -1,720 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { Editor as TipTapEditor } from '@tiptap/react'; -import { Command } from '@codemirror/view'; - -import { Level } from '../../types'; - -import { safeExecuteCommand, logWarning } from './errorHandler'; -import { MARKDOWN_PATTERNS } from './constants'; - -/** - * Creates command methods module - * - * Provides command methods for the editor, including: - * - Low-level methods: wrapText, replaceLines, appendBlock (for internal editor use) - * - Semantic methods: insertBold, insertHeading, insertImage, etc. (for toolbar use) - * - State query methods: isBold, isHeading, etc. - * - * @param editor - TipTap editor instance - * @returns Object containing all command methods - */ -export function createCommandMethods(editor: TipTapEditor) { - return { - wrapText: (before: string, after?: string, defaultText?: string) => { - const { from, to } = editor.state.selection; - const actualAfter = after || before; - - if (before === '**' && actualAfter === '**') { - if (from === to) { - if (defaultText) { - const insertPos = from; - editor.commands.insertContent(defaultText); - editor.commands.setTextSelection({ - from: insertPos, - to: insertPos + defaultText.length, - }); - editor.commands.toggleBold(); - } else { - editor.commands.toggleBold(); - } - } else { - editor.commands.toggleBold(); - } - return; - } - - if (before === '*' && actualAfter === '*') { - if (from === to) { - if (defaultText) { - const insertPos = from; - editor.commands.insertContent(defaultText); - editor.commands.setTextSelection({ - from: insertPos, - to: insertPos + defaultText.length, - }); - editor.commands.toggleItalic(); - } else { - editor.commands.toggleItalic(); - } - } else { - editor.commands.toggleItalic(); - } - return; - } - - if (before === '`' && actualAfter === '`') { - if (from === to) { - if (defaultText) { - const insertPos = from; - editor.commands.insertContent(defaultText); - editor.commands.setTextSelection({ - from: insertPos, - to: insertPos + defaultText.length, - }); - editor.commands.toggleCode(); - } else { - editor.commands.toggleCode(); - } - } else { - editor.commands.toggleCode(); - } - return; - } - - if (before === '```\n' && actualAfter === '\n```') { - if (from === to) { - const codeBlockText = defaultText - ? `\`\`\`\n${defaultText}\n\`\`\`` - : '```\n\n```'; - safeExecuteCommand( - () => { - editor.commands.insertContent(codeBlockText, { - contentType: 'markdown', - }); - }, - () => { - editor.commands.insertContent({ - type: 'codeBlock', - content: defaultText - ? [ - { - type: 'text', - text: defaultText, - }, - ] - : [], - }); - }, - ); - } else { - const selectedText = editor.state.doc.textBetween(from, to); - safeExecuteCommand( - () => { - editor.commands.insertContentAt( - { from, to }, - { - type: 'codeBlock', - content: [ - { - type: 'text', - text: selectedText, - }, - ], - }, - ); - }, - () => { - const codeBlockText = `\`\`\`\n${selectedText}\n\`\`\``; - editor.commands.insertContentAt({ from, to }, codeBlockText, { - contentType: 'markdown', - }); - }, - ); - } - return; - } - - if (from === to) { - const text = before + (defaultText || '') + actualAfter; - editor.commands.insertContent(text, { contentType: 'markdown' }); - } else { - const selectedText = editor.state.doc.textBetween(from, to); - const wrappedText = before + selectedText + actualAfter; - editor.commands.insertContentAt({ from, to }, wrappedText, { - contentType: 'markdown', - }); - } - }, - - replaceLines: (replace: Parameters['map']>[0]) => { - const { from } = editor.state.selection; - const $pos = editor.state.doc.resolve(from); - const block = $pos.parent; - const lineText = block.textContent; - const newText = replace(lineText, 0, [lineText]) as string; - - const finalText = newText || ' '; - const headingMatch = finalText.match(MARKDOWN_PATTERNS.HEADING); - if (headingMatch) { - const [, hashes, text] = headingMatch; - const level = hashes.length; - const start = $pos.start($pos.depth); - const end = $pos.end($pos.depth); - - if (start < 0 || end < 0 || start > end) { - logWarning('Invalid position range for heading', { start, end }); - return; - } - - const headingText = text.trim() || 'Heading'; - safeExecuteCommand( - () => { - if (start === end) { - editor.commands.insertContent({ - type: 'heading', - attrs: { level }, - content: [ - { - type: 'text', - text: headingText, - }, - ], - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - { - type: 'heading', - attrs: { level }, - content: [ - { - type: 'text', - text: headingText, - }, - ], - }, - ); - } - }, - () => { - const markdownText = finalText.trim() || `# Heading`; - if (start === end) { - editor.commands.insertContent(markdownText, { - contentType: 'markdown', - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - markdownText, - { contentType: 'markdown' }, - ); - } - }, - ); - return; - } - - if (finalText.startsWith('> ')) { - const quoteText = finalText.slice(2).trim(); - const start = $pos.start($pos.depth); - const end = $pos.end($pos.depth); - - if (start < 0 || end < 0 || start > end) { - logWarning('Invalid position range for heading', { start, end }); - return; - } - - const quoteMarkdown = quoteText ? `> ${quoteText}` : '> '; - safeExecuteCommand( - () => { - if (start === end) { - editor.commands.insertContent(quoteMarkdown, { - contentType: 'markdown', - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - quoteMarkdown, - { contentType: 'markdown' }, - ); - } - }, - () => { - if (start === end) { - editor.commands.insertContent({ - type: 'paragraph', - content: quoteText ? [{ type: 'text', text: quoteText }] : [], - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - { - type: 'paragraph', - content: quoteText ? [{ type: 'text', text: quoteText }] : [], - }, - ); - } - }, - ); - return; - } - - const olMatchOriginal = lineText.match( - MARKDOWN_PATTERNS.ORDERED_LIST_ORIGINAL, - ); - const olMatchNew = finalText.match(MARKDOWN_PATTERNS.ORDERED_LIST_NEW); - - if (olMatchOriginal || olMatchNew) { - const isInOrderedList = editor.isActive('orderedList'); - const start = $pos.start($pos.depth); - const end = $pos.end($pos.depth); - - if (start < 0 || end < 0 || start > end) { - logWarning('Invalid position range for ordered list', { - start, - end, - }); - return; - } - - if (olMatchOriginal && !olMatchNew) { - const textContent = finalText.trim(); - const contentToInsert = textContent || 'Paragraph'; - - safeExecuteCommand( - () => { - if (start === end) { - editor.commands.insertContent(contentToInsert, { - contentType: 'markdown', - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - contentToInsert, - { contentType: 'markdown' }, - ); - } - }, - () => { - if (start === end) { - editor.commands.insertContent({ - type: 'paragraph', - content: [{ type: 'text', text: contentToInsert }], - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - { - type: 'paragraph', - content: [{ type: 'text', text: contentToInsert }], - }, - ); - } - }, - ); - if (isInOrderedList) { - safeExecuteCommand(() => { - editor.chain().focus().toggleOrderedList().run(); - }); - } - } else if (!olMatchOriginal && olMatchNew) { - const [, , text] = olMatchNew; - const textContent = text.trim(); - const contentToInsert = textContent || 'List item'; - - safeExecuteCommand( - () => { - if (start === end) { - editor.commands.insertContent(contentToInsert, { - contentType: 'markdown', - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - contentToInsert, - { contentType: 'markdown' }, - ); - } - }, - () => { - if (start === end) { - editor.commands.insertContent({ - type: 'paragraph', - content: [{ type: 'text', text: contentToInsert }], - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - { - type: 'paragraph', - content: [{ type: 'text', text: contentToInsert }], - }, - ); - } - }, - ); - if (!isInOrderedList) { - safeExecuteCommand(() => { - editor.chain().focus().toggleOrderedList().run(); - }); - } - } - return; - } - const ulMatchOriginal = lineText.match( - MARKDOWN_PATTERNS.UNORDERED_LIST_ORIGINAL, - ); - const ulMatchNew = finalText.match(MARKDOWN_PATTERNS.UNORDERED_LIST_NEW); - - if (ulMatchOriginal || ulMatchNew) { - const isInBulletList = editor.isActive('bulletList'); - const start = $pos.start($pos.depth); - const end = $pos.end($pos.depth); - - if (start < 0 || end < 0 || start > end) { - logWarning('Invalid position range for unordered list', { - start, - end, - }); - return; - } - - if (ulMatchOriginal && !ulMatchNew) { - const textContent = finalText.trim(); - const contentToInsert = textContent || 'Paragraph'; - - safeExecuteCommand( - () => { - if (start === end) { - editor.commands.insertContent(contentToInsert, { - contentType: 'markdown', - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - contentToInsert, - { contentType: 'markdown' }, - ); - } - }, - () => { - if (start === end) { - editor.commands.insertContent({ - type: 'paragraph', - content: [{ type: 'text', text: contentToInsert }], - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - { - type: 'paragraph', - content: [{ type: 'text', text: contentToInsert }], - }, - ); - } - }, - ); - if (isInBulletList) { - safeExecuteCommand(() => { - editor.chain().focus().toggleBulletList().run(); - }); - } - } else if (!ulMatchOriginal && ulMatchNew) { - const [, text] = ulMatchNew; - const textContent = text.trim(); - const contentToInsert = textContent || 'List item'; - - safeExecuteCommand( - () => { - if (start === end) { - editor.commands.insertContent(contentToInsert, { - contentType: 'markdown', - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - contentToInsert, - { contentType: 'markdown' }, - ); - } - }, - () => { - if (start === end) { - editor.commands.insertContent({ - type: 'paragraph', - content: [{ type: 'text', text: contentToInsert }], - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - { - type: 'paragraph', - content: [{ type: 'text', text: contentToInsert }], - }, - ); - } - }, - ); - if (!isInBulletList) { - safeExecuteCommand(() => { - editor.chain().focus().toggleBulletList().run(); - }); - } - } - return; - } - - const start = $pos.start($pos.depth); - const end = $pos.end($pos.depth); - - if (start < 0 || end < 0 || start > end) { - logWarning('Invalid position range', { - start, - end, - function: 'replaceLines', - }); - return; - } - - const contentToInsert = finalText.trim() || ' '; - - safeExecuteCommand( - () => { - if (start === end) { - editor.commands.insertContent(contentToInsert, { - contentType: 'markdown', - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - contentToInsert, - { contentType: 'markdown' }, - ); - } - }, - () => { - if (start === end) { - editor.commands.insertContent({ - type: 'paragraph', - content: [{ type: 'text', text: contentToInsert }], - }); - } else { - editor.commands.insertContentAt( - { from: start, to: end }, - { - type: 'paragraph', - content: [{ type: 'text', text: contentToInsert }], - }, - ); - } - }, - ); - }, - - appendBlock: (content: string) => { - if (MARKDOWN_PATTERNS.HORIZONTAL_RULE.test(content.trim())) { - safeExecuteCommand( - () => { - editor.commands.insertContent({ - type: 'horizontalRule', - }); - }, - () => { - editor.commands.insertContent(content, { - contentType: 'markdown', - }); - }, - ); - return; - } - - safeExecuteCommand(() => { - editor.commands.insertContent(`\n\n${content}`, { - contentType: 'markdown', - }); - }); - }, - - addKeyMap: (keyMap: Record) => { - Object.keys(keyMap).forEach(() => {}); - }, - insertBold: (text?: string) => { - if (text) { - const { from } = editor.state.selection; - editor.commands.insertContent(text); - editor.commands.setTextSelection({ from, to: from + text.length }); - } - editor.commands.toggleBold(); - }, - - insertItalic: (text?: string) => { - if (text) { - const { from } = editor.state.selection; - editor.commands.insertContent(text); - editor.commands.setTextSelection({ from, to: from + text.length }); - } - editor.commands.toggleItalic(); - }, - - insertCode: (text?: string) => { - if (text) { - const { from } = editor.state.selection; - editor.commands.insertContent(text); - editor.commands.setTextSelection({ from, to: from + text.length }); - } - editor.commands.toggleCode(); - }, - - insertStrikethrough: (text?: string) => { - if (text) { - const { from } = editor.state.selection; - editor.commands.insertContent(text); - editor.commands.setTextSelection({ from, to: from + text.length }); - } - editor.commands.toggleStrike(); - }, - - insertHeading: (level: Level, text?: string) => { - if (text) { - // Insert heading using TipTap's native API to ensure proper structure - safeExecuteCommand( - () => { - editor.commands.insertContent({ - type: 'heading', - attrs: { level }, - content: [ - { - type: 'text', - text, - }, - ], - }); - // Select only the text part (excluding the heading node structure) - // After insertion, the cursor is at the end of the heading - // We need to select backwards from the current position - const { to } = editor.state.selection; - editor.commands.setTextSelection({ - from: to - text.length, - to, - }); - }, - () => { - // Fallback: use markdown format - const headingText = `${'#'.repeat(level)} ${text}`; - editor.commands.insertContent(headingText, { - contentType: 'markdown', - }); - }, - ); - } else { - editor.commands.toggleHeading({ level }); - } - }, - - insertBlockquote: (text?: string) => { - if (text) { - const { from } = editor.state.selection; - const blockquoteText = `> ${text}`; - - // Use chain to ensure selection happens after insertion - editor - .chain() - .focus() - .insertContent(blockquoteText, { contentType: 'markdown' }) - .setTextSelection({ - from: from + 1, - to: from + 1 + text.length, - }) - .run(); - } else { - editor.commands.toggleBlockquote(); - } - }, - - insertCodeBlock: (language?: string, code?: string) => { - const lang = language || ''; - const codeText = code || 'code here'; - editor.commands.insertContent(`\`\`\`${lang}\n${codeText}\n\`\`\``, { - contentType: 'markdown', - }); - }, - - insertHorizontalRule: () => { - editor.commands.setHorizontalRule(); - }, - - insertOrderedList: () => { - editor.commands.toggleOrderedList(); - }, - - insertUnorderedList: () => { - editor.commands.toggleBulletList(); - }, - - toggleOrderedList: () => { - editor.commands.toggleOrderedList(); - }, - - toggleUnorderedList: () => { - editor.commands.toggleBulletList(); - }, - - insertLink: (url: string, text?: string) => { - const linkText = text || url; - editor.commands.insertContent(`[${linkText}](${url})`, { - contentType: 'markdown', - }); - }, - - insertImage: (url: string, alt?: string) => { - editor.commands.setImage({ src: url, alt: alt || 'image' }); - }, - - insertTable: (rows = 3, cols = 3) => { - editor.commands.insertTable({ - rows, - cols, - withHeaderRow: true, - }); - }, - - indent: () => { - editor.commands.sinkListItem('listItem'); - }, - - outdent: () => { - editor.commands.liftListItem('listItem'); - }, - - isBold: () => editor.isActive('bold'), - isItalic: () => editor.isActive('italic'), - isHeading: (level?: number) => { - if (level) { - return editor.isActive('heading', { level }); - } - return editor.isActive('heading'); - }, - isBlockquote: () => editor.isActive('blockquote'), - isCodeBlock: () => editor.isActive('codeBlock'), - isOrderedList: () => editor.isActive('orderedList'), - isUnorderedList: () => editor.isActive('bulletList'), - }; -} diff --git a/ui/src/components/Editor/utils/tiptap/constants.ts b/ui/src/components/Editor/utils/tiptap/constants.ts deleted file mode 100644 index a4ff7de42..000000000 --- a/ui/src/components/Editor/utils/tiptap/constants.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * Markdown pattern matching regular expression constants - * - * Defines regular expression patterns for parsing and matching Markdown syntax. - * These patterns are used to convert Markdown syntax to TipTap nodes, or from TipTap nodes - * to Markdown format. - * - * @example - * ```typescript - * const headingMatch = text.match(MARKDOWN_PATTERNS.HEADING); - * if (headingMatch) { - * const level = headingMatch[1].length; // Number of # - * const text = headingMatch[2]; // Heading text - * } - * ``` - */ -export const MARKDOWN_PATTERNS = { - HEADING: /^(#{1,6})\s+(.+)$/, - ORDERED_LIST_ORIGINAL: /^(\s{0,})(\d+)\.\s/, - ORDERED_LIST_NEW: /^(\d+)\.\s*(.*)$/, - UNORDERED_LIST_ORIGINAL: /^(\s{0,})(-|\*)\s/, - UNORDERED_LIST_NEW: /^[-*]\s*(.*)$/, - INLINE_CODE: /^`(.+?)`$/, - CODE_BLOCK: /^(\n)?```(\w+)?\n([\s\S]*?)\n```(\n)?$/, - IMAGE: /^!\[([^\]]*)\]\(([^)]+)\)$/, - LINK: /^\[([^\]]*)\]\(([^)]+)\)$/, - AUTO_LINK: /^<(.+?)>$/, - HORIZONTAL_RULE: /^-{3,}$/, -} as const; diff --git a/ui/src/components/Editor/utils/tiptap/errorHandler.ts b/ui/src/components/Editor/utils/tiptap/errorHandler.ts deleted file mode 100644 index c8f4e7a3b..000000000 --- a/ui/src/components/Editor/utils/tiptap/errorHandler.ts +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * Editor error type enumeration - * - * Defines various error types that may occur in the editor, used for error classification and handling. - */ -export enum EditorErrorType { - COMMAND_EXECUTION_FAILED = 'COMMAND_EXECUTION_FAILED', - POSITION_CONVERSION_FAILED = 'POSITION_CONVERSION_FAILED', - CONTENT_PARSING_FAILED = 'CONTENT_PARSING_FAILED', - EVENT_LISTENER_FAILED = 'EVENT_LISTENER_FAILED', -} - -/** - * Editor error interface - */ -export interface EditorError { - type: EditorErrorType; - message: string; - originalError?: Error; - context?: Record; - timestamp: number; -} - -/** - * Handles editor errors with unified log format - * - * Unified error handling for the editor, recording error information, context, and stack traces - * for easier problem identification and debugging. - * - * @param error - Original error object - * @param type - Error type - * @param context - Optional context information (function name, parameters, etc.) - * @returns Processed error object - * - * @example - * ```typescript - * try { - * editor.commands.insertContent(content); - * } catch (error) { - * handleEditorError(error, EditorErrorType.COMMAND_EXECUTION_FAILED, { - * function: 'insertContent', - * content: content.substring(0, 50), - * }); - * } - * ``` - */ -export function handleEditorError( - error: Error, - type: EditorErrorType, - context?: Record, -): EditorError { - const editorError: EditorError = { - type, - message: error.message, - originalError: error, - context, - timestamp: Date.now(), - }; - - console.error(`[Editor Error] ${type}:`, { - message: editorError.message, - context: editorError.context, - stack: error.stack, - }); - - return editorError; -} - -/** - * Safely executes TipTap command with error handling and fallback strategy - * - * Automatically catches errors when executing TipTap commands. If a fallback function is provided, - * it attempts to execute the fallback operation when the main command fails. All errors are uniformly recorded. - * - * @param command - Main command function to execute - * @param fallback - Optional fallback function to execute when main command fails - * @param errorType - Error type, defaults to COMMAND_EXECUTION_FAILED - * @param context - Optional context information - * @returns Command execution result, returns undefined if failed and no fallback - * - * @example - * ```typescript - * const result = safeExecuteCommand( - * () => editor.commands.insertContent(content), - * () => editor.commands.insertContent(content, { contentType: 'markdown' }), - * EditorErrorType.COMMAND_EXECUTION_FAILED, - * { function: 'insertContent', contentLength: content.length } - * ); - * ``` - */ -export function safeExecuteCommand( - command: () => T, - fallback?: () => T, - errorType: EditorErrorType = EditorErrorType.COMMAND_EXECUTION_FAILED, - context?: Record, -): T | undefined { - try { - return command(); - } catch (error) { - handleEditorError(error as Error, errorType, context); - if (fallback) { - try { - return fallback(); - } catch (fallbackError) { - handleEditorError(fallbackError as Error, errorType, { - ...context, - isFallback: true, - }); - } - } - return undefined; - } -} - -/** - * Logs warning information (for non-fatal errors) - * - * Records non-fatal warning information to alert potential issues without affecting functionality. - * - * @param message - Warning message - * @param context - Optional context information - * - * @example - * ```typescript - * if (start < 0 || end < 0) { - * logWarning('Invalid position range', { start, end, function: 'setSelection' }); - * return; - * } - * ``` - */ -export function logWarning( - message: string, - context?: Record, -): void { - console.warn(`[Editor Warning] ${message}`, context || {}); -} diff --git a/ui/src/components/Editor/utils/tiptap/events.ts b/ui/src/components/Editor/utils/tiptap/events.ts deleted file mode 100644 index 2a86440de..000000000 --- a/ui/src/components/Editor/utils/tiptap/events.ts +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { Editor as TipTapEditor } from '@tiptap/react'; - -import { logWarning } from './errorHandler'; - -/** - * Checks if editor view is available - */ -function isViewAvailable(editor: TipTapEditor): boolean { - if (!editor) { - return false; - } - if (editor.isDestroyed) { - return false; - } - return !!(editor.view && editor.state); -} - -/** - * Creates event handling methods module - * - * Provides event handling methods for the editor, including: - * - on: Register event listeners (change, focus, blur, dragenter, dragover, drop, paste) - * - off: Remove event listeners - * - * Note: For DOM events (dragenter, dragover, drop, paste), - * the editor view must be mounted before binding events. - * - * @param editor - TipTap editor instance - * @returns Object containing event handling methods - */ -export function createEventMethods(editor: TipTapEditor) { - return { - on: (event: string, callback: (e?: unknown) => void) => { - if (event === 'change') { - editor.on('update', callback); - } else if (event === 'focus') { - editor.on('focus', callback); - } else if (event === 'blur') { - editor.on('blur', callback); - } else if ( - event === 'dragenter' || - event === 'dragover' || - event === 'drop' || - event === 'paste' - ) { - if (!isViewAvailable(editor)) { - logWarning( - 'TipTap editor view is not available yet. Event listener not attached.', - { - event, - }, - ); - return; - } - editor.view.dom.addEventListener(event, callback as EventListener); - } - }, - - off: (event: string, callback: (e?: unknown) => void) => { - if ( - (event === 'dragenter' || - event === 'dragover' || - event === 'drop' || - event === 'paste') && - !isViewAvailable(editor) - ) { - return; - } - if (event === 'change') { - editor.off('update', callback); - } else if (event === 'focus') { - editor.off('focus', callback); - } else if (event === 'blur') { - editor.off('blur', callback); - } else if ( - event === 'dragenter' || - event === 'dragover' || - event === 'drop' || - event === 'paste' - ) { - editor.view.dom.removeEventListener(event, callback as EventListener); - } - }, - }; -} diff --git a/ui/src/components/Editor/utils/tiptap/position.ts b/ui/src/components/Editor/utils/tiptap/position.ts deleted file mode 100644 index 378908b88..000000000 --- a/ui/src/components/Editor/utils/tiptap/position.ts +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { Editor as TipTapEditor } from '@tiptap/react'; - -import { Position } from '../../types'; - -import { handleEditorError, EditorErrorType } from './errorHandler'; - -/** - * Converts TipTap position to CodeMirror Position - * - * TipTap uses document tree-based node positions (character index), while CodeMirror uses - * line-based positions (line number and column number). This function converts between them. - * - * @param editor - TipTap editor instance - * @param pos - TipTap position index (character position) - * @returns CodeMirror position object with line and ch properties - * - * @example - * ```typescript - * const tipTapPos = 100; // Character position - * const codeMirrorPos = convertTipTapPositionToCodeMirror(editor, tipTapPos); - * // { line: 5, ch: 10 } - * ``` - */ -export function convertTipTapPositionToCodeMirror( - editor: TipTapEditor, - pos: number, -): Position { - try { - const { doc } = editor.state; - let line = 0; - let ch = 0; - let currentPos = 0; - - for (let i = 0; i < doc.content.childCount; i += 1) { - const child = doc.content.child(i); - const childSize = child.nodeSize; - - if (currentPos + childSize > pos) { - const text = child.textContent; - const relativePos = pos - currentPos; - - const textBeforePos = text.substring(0, relativePos); - const newlineMatches = textBeforePos.match(/\n/g); - line += newlineMatches ? newlineMatches.length : 0; - ch = relativePos - textBeforePos.lastIndexOf('\n') - 1; - break; - } - - const text = child.textContent; - const newlineMatches = text.match(/\n/g); - line += newlineMatches ? newlineMatches.length : 0; - currentPos += childSize; - } - - return { line, ch }; - } catch (error) { - handleEditorError( - error as Error, - EditorErrorType.POSITION_CONVERSION_FAILED, - { - function: 'convertTipTapPositionToCodeMirror', - position: pos, - }, - ); - return { line: 0, ch: 0 }; - } -} - -/** - * Converts CodeMirror Position to TipTap position index - * - * Converts CodeMirror's line-based position to TipTap's character index position. - * - * @param editor - TipTap editor instance - * @param position - CodeMirror position object with line and ch properties - * @returns TipTap position index (character position) - * - * @example - * ```typescript - * const codeMirrorPos = { line: 5, ch: 10 }; - * const tipTapPos = convertCodeMirrorPositionToTipTap(editor, codeMirrorPos); - * // 100 (character position) - * ``` - */ -export function convertCodeMirrorPositionToTipTap( - editor: TipTapEditor, - position: Position, -): number { - try { - const { doc } = editor.state; - let currentLine = 0; - let currentPos = 0; - - for (let i = 0; i < doc.content.childCount; i += 1) { - const child = doc.content.child(i); - const text = child.textContent; - const lines = text.split('\n'); - - if (currentLine + lines.length - 1 >= position.line) { - const lineInNode = position.line - currentLine; - const { ch: posInLine } = position; - - let pos = 0; - for (let j = 0; j < lineInNode; j += 1) { - pos += lines[j].length + 1; // +1 for newline - } - pos += posInLine; - - return currentPos + pos; - } - - currentLine += lines.length - 1; - currentPos += child.nodeSize; - } - - return doc.content.size; - } catch (error) { - handleEditorError( - error as Error, - EditorErrorType.POSITION_CONVERSION_FAILED, - { - function: 'convertCodeMirrorPositionToTipTap', - position, - }, - ); - return editor.state.doc.content.size; - } -} diff --git a/ui/src/components/Editor/utils/tiptap/tableExtension.ts b/ui/src/components/Editor/utils/tiptap/tableExtension.ts deleted file mode 100644 index 70e68f77a..000000000 --- a/ui/src/components/Editor/utils/tiptap/tableExtension.ts +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { Table, TableOptions } from '@tiptap/extension-table'; -import type { NodeViewRendererProps } from '@tiptap/core'; - -interface TableWrapperOptions extends TableOptions { - wrapperClass?: string; -} - -export const TableWithWrapper = Table.extend({ - addOptions() { - const parentOptions = (this.parent?.() || {}) as Partial; - return { - ...parentOptions, - HTMLAttributes: parentOptions.HTMLAttributes || {}, - wrapperClass: 'table-responsive', - } as TableWrapperOptions; - }, - - addNodeView() { - return (props: NodeViewRendererProps) => { - const { node } = props; - const wrapperClass = this.options.wrapperClass || 'table-responsive'; - - const dom = document.createElement('div'); - dom.className = wrapperClass; - - const table = document.createElement('table'); - - const htmlAttrs = this.options.HTMLAttributes || {}; - if (htmlAttrs.class) { - table.className = htmlAttrs.class as string; - } - if (htmlAttrs.style && typeof htmlAttrs.style === 'object') { - Object.assign(table.style, htmlAttrs.style); - } - - const colgroup = document.createElement('colgroup'); - if (node.firstChild) { - const { childCount } = node.firstChild; - for (let i = 0; i < childCount; i += 1) { - const col = document.createElement('col'); - colgroup.appendChild(col); - } - } - table.appendChild(colgroup); - - const tbody = document.createElement('tbody'); - table.appendChild(tbody); - dom.appendChild(table); - - return { - dom, - contentDOM: tbody, - update: (updatedNode) => { - if (updatedNode.type !== node.type) { - return false; - } - return true; - }, - }; - }; - }, -}); From 78714e83cfcc2641abbb4e63d6557894f59128a3 Mon Sep 17 00:00:00 2001 From: robin Date: Thu, 25 Dec 2025 11:50:55 +0800 Subject: [PATCH 41/92] feat(editor): implement image upload functionality with validation and hooks --- ui/src/components/Editor/ToolBars/image.tsx | 102 +------------- .../components/Editor/hooks/useImageUpload.ts | 129 ++++++++++++++++++ ui/src/components/Editor/index.tsx | 83 ++++++++++- ui/src/utils/pluginKit/index.ts | 39 ++++++ ui/src/utils/pluginKit/interface.ts | 2 + 5 files changed, 259 insertions(+), 96 deletions(-) create mode 100644 ui/src/components/Editor/hooks/useImageUpload.ts diff --git a/ui/src/components/Editor/ToolBars/image.tsx b/ui/src/components/Editor/ToolBars/image.tsx index 52b2e5461..0783e22e4 100644 --- a/ui/src/components/Editor/ToolBars/image.tsx +++ b/ui/src/components/Editor/ToolBars/image.tsx @@ -21,12 +21,10 @@ import { useEffect, useState, memo, useContext } from 'react'; import { Button, Form, Modal, Tab, Tabs } from 'react-bootstrap'; import { useTranslation } from 'react-i18next'; -import { Modal as AnswerModal } from '@/components'; import ToolItem from '../toolItem'; import { EditorContext } from '../EditorContext'; import { Editor } from '../types'; -import { uploadImage } from '@/services'; -import { writeSettingStore } from '@/stores'; +import { useImageUpload } from '../hooks/useImageUpload'; const Image = () => { const editor = useContext(EditorContext); @@ -40,12 +38,7 @@ const Image = () => { } }, [editor]); const { t } = useTranslation('translation', { keyPrefix: 'editor' }); - const { - max_image_size = 4, - max_attachment_size = 8, - authorized_image_extensions = [], - authorized_attachment_extensions = [], - } = writeSettingStore((state) => state.write); + const { verifyImageSize, uploadFiles } = useImageUpload(); const loadingText = `![${t('image.uploading')}...]()`; @@ -69,89 +62,6 @@ const Image = () => { errorMsg: '', }); - const verifyImageSize = (files: FileList) => { - if (files.length === 0) { - return false; - } - - /** - * When allowing attachments to be uploaded, verification logic for attachment information has been added. In order to avoid abnormal judgment caused by the order of drag and drop upload, the drag and drop upload verification of attachments and the drag and drop upload of images are put together. - * - */ - const canUploadAttachment = authorized_attachment_extensions.length > 0; - const allowedAllType = [ - ...authorized_image_extensions, - ...authorized_attachment_extensions, - ]; - const unSupportFiles = Array.from(files).filter((file) => { - const fileName = file.name.toLowerCase(); - return canUploadAttachment - ? !allowedAllType.find((v) => fileName.endsWith(v)) - : file.type.indexOf('image') === -1; - }); - - if (unSupportFiles.length > 0) { - AnswerModal.confirm({ - content: canUploadAttachment - ? t('file.not_supported', { file_type: allowedAllType.join(', ') }) - : t('image.form_image.fields.file.msg.only_image'), - showCancel: false, - }); - return false; - } - - const otherFiles = Array.from(files).filter((file) => { - return file.type.indexOf('image') === -1; - }); - - if (canUploadAttachment && otherFiles.length > 0) { - const attachmentOverSizeFiles = otherFiles.filter( - (file) => file.size / 1024 / 1024 > max_attachment_size, - ); - if (attachmentOverSizeFiles.length > 0) { - AnswerModal.confirm({ - content: t('file.max_size', { size: max_attachment_size }), - showCancel: false, - }); - return false; - } - } - - const imageFiles = Array.from(files).filter( - (file) => file.type.indexOf('image') > -1, - ); - const oversizedImages = imageFiles.filter( - (file) => file.size / 1024 / 1024 > max_image_size, - ); - if (oversizedImages.length > 0) { - AnswerModal.confirm({ - content: t('image.form_image.fields.file.msg.max_size', { - size: max_image_size, - }), - showCancel: false, - }); - return false; - } - - return true; - }; - - const upload = ( - files: FileList, - ): Promise<{ url: string; name: string; type: string }[]> => { - const promises = Array.from(files).map(async (file) => { - const type = file.type.indexOf('image') > -1 ? 'post' : 'post_attachment'; - const url = await uploadImage({ file, type }); - - return { - name: file.name, - url, - type, - }; - }); - - return Promise.all(promises); - }; function dragenter(e) { e.stopPropagation(); e.preventDefault(); @@ -178,7 +88,7 @@ const Image = () => { editorState.replaceSelection(loadingText); editorState.setReadOnly(true); - const urls = await upload(fileList) + const urls = await uploadFiles(fileList) .catch(() => { editorState.replaceRange('', startPos, endPos); }) @@ -217,7 +127,7 @@ const Image = () => { editorState?.replaceSelection(loadingText); editorState?.setReadOnly(true); - upload(clipboard.files) + uploadFiles(clipboard.files) .then((urls) => { const text = urls.map(({ name, url, type }) => { return `${type === 'post' ? '!' : ''}[${name}](${url})`; @@ -358,6 +268,8 @@ const Image = () => { setVisible(true); }; + const { uploadSingleFile } = useImageUpload(); + const onUpload = async (e) => { if (!editor) { return; @@ -369,7 +281,7 @@ const Image = () => { return; } - uploadImage({ file: e.target.files[0], type: 'post' }).then((url) => { + uploadSingleFile(e.target.files[0]).then((url) => { setLink({ ...link, value: url }); setImageName({ ...imageName, value: files[0].name }); }); diff --git a/ui/src/components/Editor/hooks/useImageUpload.ts b/ui/src/components/Editor/hooks/useImageUpload.ts new file mode 100644 index 000000000..bf97e24d6 --- /dev/null +++ b/ui/src/components/Editor/hooks/useImageUpload.ts @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { useTranslation } from 'react-i18next'; + +import { Modal as AnswerModal } from '@/components'; +import { uploadImage } from '@/services'; +import { writeSettingStore } from '@/stores'; + +export const useImageUpload = () => { + const { t } = useTranslation('translation', { keyPrefix: 'editor' }); + const { + max_image_size = 4, + max_attachment_size = 8, + authorized_image_extensions = [], + authorized_attachment_extensions = [], + } = writeSettingStore((state) => state.write); + + const verifyImageSize = (files: FileList | File[]): boolean => { + const fileArray = Array.isArray(files) ? files : Array.from(files); + + if (fileArray.length === 0) { + return false; + } + + const canUploadAttachment = authorized_attachment_extensions.length > 0; + const allowedAllType = [ + ...authorized_image_extensions, + ...authorized_attachment_extensions, + ]; + + const unSupportFiles = fileArray.filter((file) => { + const fileName = file.name.toLowerCase(); + return canUploadAttachment + ? !allowedAllType.find((v) => fileName.endsWith(v)) + : file.type.indexOf('image') === -1; + }); + + if (unSupportFiles.length > 0) { + AnswerModal.confirm({ + content: canUploadAttachment + ? t('file.not_supported', { file_type: allowedAllType.join(', ') }) + : t('image.form_image.fields.file.msg.only_image'), + showCancel: false, + }); + return false; + } + + const otherFiles = fileArray.filter((file) => { + return file.type.indexOf('image') === -1; + }); + + if (canUploadAttachment && otherFiles.length > 0) { + const attachmentOverSizeFiles = otherFiles.filter( + (file) => file.size / 1024 / 1024 > max_attachment_size, + ); + if (attachmentOverSizeFiles.length > 0) { + AnswerModal.confirm({ + content: t('file.max_size', { size: max_attachment_size }), + showCancel: false, + }); + return false; + } + } + + const imageFiles = fileArray.filter( + (file) => file.type.indexOf('image') > -1, + ); + const oversizedImages = imageFiles.filter( + (file) => file.size / 1024 / 1024 > max_image_size, + ); + if (oversizedImages.length > 0) { + AnswerModal.confirm({ + content: t('image.form_image.fields.file.msg.max_size', { + size: max_image_size, + }), + showCancel: false, + }); + return false; + } + + return true; + }; + + const uploadFiles = ( + files: FileList | File[], + ): Promise<{ url: string; name: string; type: string }[]> => { + const fileArray = Array.isArray(files) ? files : Array.from(files); + const promises = fileArray.map(async (file) => { + const type = file.type.indexOf('image') > -1 ? 'post' : 'post_attachment'; + const url = await uploadImage({ file, type }); + + return { + name: file.name, + url, + type, + }; + }); + + return Promise.all(promises); + }; + + const uploadSingleFile = async (file: File): Promise => { + const type = file.type.indexOf('image') > -1 ? 'post' : 'post_attachment'; + return uploadImage({ file, type }); + }; + + return { + verifyImageSize, + uploadFiles, + uploadSingleFile, + }; +}; diff --git a/ui/src/components/Editor/index.tsx b/ui/src/components/Editor/index.tsx index c6136c3c8..9c12bbb18 100644 --- a/ui/src/components/Editor/index.tsx +++ b/ui/src/components/Editor/index.tsx @@ -24,13 +24,21 @@ import { forwardRef, useImperativeHandle, useCallback, + useEffect, } from 'react'; +import { Spinner } from 'react-bootstrap'; import classNames from 'classnames'; -import { PluginType, useRenderPlugin } from '@/utils/pluginKit'; +import { + PluginType, + useRenderPlugin, + getReplacementPlugin, +} from '@/utils/pluginKit'; +import { writeSettingStore } from '@/stores'; import PluginRender, { PluginSlot } from '../PluginRender'; +import { useImageUpload } from './hooks/useImageUpload'; import { BlockQuote, Bold, @@ -87,6 +95,32 @@ const MDEditor: ForwardRefRenderFunction = ( ) => { const [currentEditor, setCurrentEditor] = useState(null); const previewRef = useRef<{ getHtml; element } | null>(null); + const [fullEditorPlugin, setFullEditorPlugin] = useState(null); + const [isLoading, setIsLoading] = useState(true); + const { verifyImageSize, uploadSingleFile } = useImageUpload(); + const { + max_image_size = 4, + authorized_image_extensions = [], + authorized_attachment_extensions = [], + } = writeSettingStore((state) => state.write); + + useEffect(() => { + let mounted = true; + + const loadPlugin = async () => { + const plugin = await getReplacementPlugin(PluginType.EditorReplacement); + if (mounted) { + setFullEditorPlugin(plugin); + setIsLoading(false); + } + }; + + loadPlugin(); + + return () => { + mounted = false; + }; + }, []); useRenderPlugin(previewRef.current?.element); @@ -104,6 +138,53 @@ const MDEditor: ForwardRefRenderFunction = ( const EditorComponent = MarkdownEditor; + if (isLoading) { + return ( +
        +
        + +
        +
        + ); + } + + if (fullEditorPlugin) { + const FullEditorComponent = fullEditorPlugin.component; + + const handleImageUpload = async (file: File | string): Promise => { + if (typeof file === 'string') { + return file; + } + + if (!verifyImageSize([file])) { + throw new Error('File validation failed'); + } + + return uploadSingleFile(file); + }; + + return ( + + ); + } + return ( <>
        diff --git a/ui/src/utils/pluginKit/index.ts b/ui/src/utils/pluginKit/index.ts index a217d8936..b62d3f59d 100644 --- a/ui/src/utils/pluginKit/index.ts +++ b/ui/src/utils/pluginKit/index.ts @@ -53,6 +53,8 @@ class Plugins { private initializationError: Error | null = null; + private replacementPlugins: Map = new Map(); + constructor() { this.initialization = this.init(); } @@ -176,6 +178,23 @@ class Plugins { return; } + // Handle singleton plugins (only one per type allowed) + const mode = plugin.info.registrationMode || 'multiple'; + if (mode === 'singleton') { + const existingPlugin = this.replacementPlugins.get(plugin.info.type); + if (existingPlugin) { + const error = new Error( + `[PluginKit] Plugin conflict: ` + + `Cannot register '${plugin.info.slug_name}' because '${existingPlugin.info.slug_name}' ` + + `is already registered as a singleton plugin of type '${plugin.info.type}'. ` + + `Only one singleton plugin per type is allowed.`, + ); + console.error(error.message); + throw error; + } + this.replacementPlugins.set(plugin.info.type, plugin); + } + if (plugin.i18nConfig) { initI18nResource(plugin.i18nConfig); } @@ -207,6 +226,10 @@ class Plugins { error: this.initializationError, }; } + + getReplacementPlugin(type: PluginType): Plugin | null { + return this.replacementPlugins.get(type) || null; + } } const plugins = new Plugins(); @@ -242,6 +265,21 @@ const validateRoutePlugin = async (slugName) => { return Boolean(registeredPlugin?.enabled); }; +const getReplacementPlugin = async ( + type: PluginType, +): Promise => { + try { + await plugins.initialization; + return plugins.getReplacementPlugin(type); + } catch (error) { + console.error( + `[PluginKit] Failed to get replacement plugin of type ${type}:`, + error, + ); + return null; + } +}; + const mergeRoutePlugins = async (routes) => { const routePlugins = await getRoutePlugins(); if (routePlugins.length === 0) { @@ -348,6 +386,7 @@ export { mergeRoutePlugins, useCaptchaPlugin, useRenderPlugin, + getReplacementPlugin, PluginType, }; export default plugins; diff --git a/ui/src/utils/pluginKit/interface.ts b/ui/src/utils/pluginKit/interface.ts index a1b641d86..1a2c4bee7 100644 --- a/ui/src/utils/pluginKit/interface.ts +++ b/ui/src/utils/pluginKit/interface.ts @@ -26,6 +26,7 @@ export enum PluginType { Connector = 'connector', Search = 'search', Editor = 'editor', + EditorReplacement = 'editor_replacement', Route = 'route', Captcha = 'captcha', Render = 'render', @@ -38,6 +39,7 @@ export interface PluginInfo { name?: string; description?: string; route?: string; + registrationMode?: 'multiple' | 'singleton'; } export interface Plugin { From 762e8a739d39e37aada9367bb7d6749022ea4425 Mon Sep 17 00:00:00 2001 From: robin Date: Thu, 25 Dec 2025 11:51:14 +0800 Subject: [PATCH 42/92] fix(gitignore): correct node_modules entry and remove specific plugin exceptions --- ui/.gitignore | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ui/.gitignore b/ui/.gitignore index a73983ee7..3b1e96bd4 100644 --- a/ui/.gitignore +++ b/ui/.gitignore @@ -1,7 +1,7 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies -/node_modules +node_modules /.pnp .pnp.js @@ -36,6 +36,4 @@ package-lock.json /src/plugins/* !/src/plugins/builtin !/src/plugins/Demo -!/src/plugins/answer-chart -!/src/plugins/answer-formula /src/plugins/*/*.go From 61d9bf34d3f9c60ee6db426ba4e6a90e76a1500a Mon Sep 17 00:00:00 2001 From: liqiang46 Date: Fri, 26 Dec 2025 23:00:24 +0800 Subject: [PATCH 43/92] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9C=80=E4=BD=B3?= =?UTF-8?q?=E8=AF=84=E8=AE=BA=E8=B6=8A=E6=9D=83=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在AcceptAnswer方法中添加了安全检查,确保要设置为最佳答案的回答确实属于该问题。 这可以防止攻击者将其他问题的回答设置为当前问题的最佳答案。 安全问题:越权设置最佳评论 修复方法:验证acceptedAnswerInfo.QuestionID == req.QuestionID --- internal/service/content/answer_service.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/service/content/answer_service.go b/internal/service/content/answer_service.go index f904b82f0..d3aab20b3 100644 --- a/internal/service/content/answer_service.go +++ b/internal/service/content/answer_service.go @@ -455,6 +455,11 @@ func (as *AnswerService) AcceptAnswer(ctx context.Context, req *schema.AcceptAns if !exist { return errors.BadRequest(reason.AnswerNotFound) } + + // check answer belong to question + if acceptedAnswerInfo.QuestionID != req.QuestionID { + return errors.BadRequest(reason.AnswerNotFound) + } acceptedAnswerInfo.ID = uid.DeShortID(acceptedAnswerInfo.ID) } From 42f8947e7c4bbd586b8496621079830880378346 Mon Sep 17 00:00:00 2001 From: Douglas Cortez Date: Wed, 24 Dec 2025 00:24:21 -0300 Subject: [PATCH 44/92] fix(notification): use SSO provider for external_id lookup in notifications --- .../user_external_login_repo.go | 2 +- .../notification/new_question_notification.go | 15 +++++++++------ .../service/notification_common/notification.go | 15 +++++++-------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/internal/repo/user_external_login/user_external_login_repo.go b/internal/repo/user_external_login/user_external_login_repo.go index c797e461d..b5cf85e86 100644 --- a/internal/repo/user_external_login/user_external_login_repo.go +++ b/internal/repo/user_external_login/user_external_login_repo.go @@ -87,7 +87,7 @@ func (ur *userExternalLoginRepo) GetByUserID(ctx context.Context, provider, user func (ur *userExternalLoginRepo) GetUserExternalLoginList(ctx context.Context, userID string) ( resp []*entity.UserExternalLogin, err error) { resp = make([]*entity.UserExternalLogin, 0) - err = ur.data.DB.Context(ctx).Where("user_id = ?", userID).Find(&resp) + err = ur.data.DB.Context(ctx).Where("user_id = ?", userID).OrderBy("updated_at DESC").Find(&resp) if err != nil { err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() } diff --git a/internal/service/notification/new_question_notification.go b/internal/service/notification/new_question_notification.go index 2f83042b2..085b3ec45 100644 --- a/internal/service/notification/new_question_notification.go +++ b/internal/service/notification/new_question_notification.go @@ -238,14 +238,17 @@ func (ns *ExternalNotificationService) syncNewQuestionNotificationToPlugin(ctx c } } - userInfo, exist, err := ns.userExternalLoginRepo.GetByUserID(ctx, fn.Info().SlugName, subscriberUserID) + externalLogins, err := ns.userExternalLoginRepo.GetUserExternalLoginList(ctx, subscriberUserID) if err != nil { - log.Errorf("get user external login info failed: %v", err) - return nil - } - if exist { - newMsg.ReceiverExternalID = userInfo.ExternalID + log.Errorf("get user external login list failed for user %s: %v", subscriberUserID, err) + } else if len(externalLogins) > 0 { + newMsg.ReceiverExternalID = externalLogins[0].ExternalID + if len(externalLogins) > 1 { + log.Debugf("user %s has %d SSO logins, using most recent: provider=%s", + subscriberUserID, len(externalLogins), externalLogins[0].Provider) + } } + fn.Notify(newMsg) } return nil diff --git a/internal/service/notification_common/notification.go b/internal/service/notification_common/notification.go index 0bbd1865f..5dbadcb96 100644 --- a/internal/service/notification_common/notification.go +++ b/internal/service/notification_common/notification.go @@ -423,15 +423,14 @@ func (ns *NotificationCommon) syncNotificationToPlugin(ctx context.Context, objI } } + externalLogins, err := ns.userExternalLoginRepo.GetUserExternalLoginList(ctx, msg.ReceiverUserID) + if err != nil { + log.Errorf("get user external login list failed for user %s: %v", msg.ReceiverUserID, err) + } else if len(externalLogins) > 0 { + pluginNotificationMsg.ReceiverExternalID = externalLogins[0].ExternalID + } + _ = plugin.CallNotification(func(fn plugin.Notification) error { - userInfo, exist, err := ns.userExternalLoginRepo.GetByUserID(ctx, fn.Info().SlugName, msg.ReceiverUserID) - if err != nil { - log.Errorf("get user external login info failed: %v", err) - return nil - } - if exist { - pluginNotificationMsg.ReceiverExternalID = userInfo.ExternalID - } fn.Notify(pluginNotificationMsg) return nil }) From c8908b7b3405e1bd927c6019e35630526a29c484 Mon Sep 17 00:00:00 2001 From: Douglas Cortez Date: Fri, 26 Dec 2025 12:18:26 -0300 Subject: [PATCH 45/92] fix(review): notifications from the specific external system will take precedence --- .../service/notification/new_question_notification.go | 10 ++++++++++ internal/service/notification_common/notification.go | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/internal/service/notification/new_question_notification.go b/internal/service/notification/new_question_notification.go index 085b3ec45..0a5471873 100644 --- a/internal/service/notification/new_question_notification.go +++ b/internal/service/notification/new_question_notification.go @@ -238,6 +238,7 @@ func (ns *ExternalNotificationService) syncNewQuestionNotificationToPlugin(ctx c } } + // Get all external logins as fallback externalLogins, err := ns.userExternalLoginRepo.GetUserExternalLoginList(ctx, subscriberUserID) if err != nil { log.Errorf("get user external login list failed for user %s: %v", subscriberUserID, err) @@ -249,6 +250,15 @@ func (ns *ExternalNotificationService) syncNewQuestionNotificationToPlugin(ctx c } } + // Try to get external login specific to this plugin (takes precedence over fallback) + userInfo, exist, err := ns.userExternalLoginRepo.GetByUserID(ctx, fn.Info().SlugName, subscriberUserID) + if err != nil { + log.Errorf("get user external login info failed: %v", err) + return nil + } + if exist { + newMsg.ReceiverExternalID = userInfo.ExternalID + } fn.Notify(newMsg) } return nil diff --git a/internal/service/notification_common/notification.go b/internal/service/notification_common/notification.go index 5dbadcb96..94ce86b16 100644 --- a/internal/service/notification_common/notification.go +++ b/internal/service/notification_common/notification.go @@ -431,6 +431,14 @@ func (ns *NotificationCommon) syncNotificationToPlugin(ctx context.Context, objI } _ = plugin.CallNotification(func(fn plugin.Notification) error { + userInfo, exist, err := ns.userExternalLoginRepo.GetByUserID(ctx, fn.Info().SlugName, msg.ReceiverUserID) + if err != nil { + log.Errorf("get user external login info failed: %v", err) + return nil + } + if exist { + pluginNotificationMsg.ReceiverExternalID = userInfo.ExternalID + } fn.Notify(pluginNotificationMsg) return nil }) From 57f31ec7eb38ee9b4bf2f74f18a0416e74d752b9 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Thu, 18 Dec 2025 19:48:44 +0900 Subject: [PATCH 46/92] fix: expand avatar column length from 1024 to 2048 The avatar column was too short to store long URLs from external OAuth providers. When users log in via connector-google plugin, the Google profile picture URL can exceed 1024 characters, causing a database error: Error 1406 (22001): Data too long for column 'avatar' at row 1 This change expands the avatar column from VARCHAR(1024) to VARCHAR(2048). Note: While URLs can technically exceed 2048 characters per specification, 2048 is the practical limit supported by most browsers and services. URLs longer than 2048 characters are extremely rare in real-world usage. --- internal/entity/user_entity.go | 2 +- internal/migrations/migrations.go | 1 + internal/migrations/v29.go | 37 +++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 internal/migrations/v29.go diff --git a/internal/entity/user_entity.go b/internal/entity/user_entity.go index 66d612926..8e63fc95a 100644 --- a/internal/entity/user_entity.go +++ b/internal/entity/user_entity.go @@ -60,7 +60,7 @@ type User struct { Status int `xorm:"not null default 1 INT(11) status"` AuthorityGroup int `xorm:"not null default 1 INT(11) authority_group"` DisplayName string `xorm:"not null default '' VARCHAR(30) display_name"` - Avatar string `xorm:"not null default '' VARCHAR(1024) avatar"` + Avatar string `xorm:"not null default '' VARCHAR(2048) avatar"` Mobile string `xorm:"not null VARCHAR(20) mobile"` Bio string `xorm:"not null TEXT bio"` BioHTML string `xorm:"not null TEXT bio_html"` diff --git a/internal/migrations/migrations.go b/internal/migrations/migrations.go index 2fbfbb7fd..7ea0bc984 100644 --- a/internal/migrations/migrations.go +++ b/internal/migrations/migrations.go @@ -104,6 +104,7 @@ var migrations = []Migration{ NewMigration("v1.5.1", "add plugin kv storage", addPluginKVStorage, true), NewMigration("v1.6.0", "move user config to interface", moveUserConfigToInterface, true), NewMigration("v1.7.0", "add optional tags", addOptionalTags, true), + NewMigration("v1.7.1", "expand avatar column length", expandAvatarColumnLength, false), } func GetMigrations() []Migration { diff --git a/internal/migrations/v29.go b/internal/migrations/v29.go new file mode 100644 index 000000000..82e120d1b --- /dev/null +++ b/internal/migrations/v29.go @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package migrations + +import ( + "context" + "fmt" + + "xorm.io/xorm" +) + +func expandAvatarColumnLength(ctx context.Context, x *xorm.Engine) error { + type User struct { + Avatar string `xorm:"not null default '' VARCHAR(2048) avatar"` + } + if err := x.Context(ctx).Sync(new(User)); err != nil { + return fmt.Errorf("expand avatar column length failed: %w", err) + } + return nil +} From a1f0b0963b889f11d43963022282e665dd4dc135 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Fri, 26 Dec 2025 11:39:16 +0900 Subject: [PATCH 47/92] fix: update migration version from v1.7.1 to v1.7.2 --- internal/migrations/migrations.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/migrations/migrations.go b/internal/migrations/migrations.go index 7ea0bc984..9fda8c34d 100644 --- a/internal/migrations/migrations.go +++ b/internal/migrations/migrations.go @@ -104,7 +104,7 @@ var migrations = []Migration{ NewMigration("v1.5.1", "add plugin kv storage", addPluginKVStorage, true), NewMigration("v1.6.0", "move user config to interface", moveUserConfigToInterface, true), NewMigration("v1.7.0", "add optional tags", addOptionalTags, true), - NewMigration("v1.7.1", "expand avatar column length", expandAvatarColumnLength, false), + NewMigration("v1.7.2", "expand avatar column length", expandAvatarColumnLength, false), } func GetMigrations() []Migration { From d7d692bb37f2d83b49a2466800eddf4aade7f94e Mon Sep 17 00:00:00 2001 From: shuai Date: Wed, 31 Dec 2025 15:37:38 +0800 Subject: [PATCH 48/92] fix: Fixed-layout navigation aligns with the width of the main content. --- ui/src/components/Header/index.scss | 21 +++++++++++++++++++++ ui/src/components/Header/index.tsx | 4 ++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/ui/src/components/Header/index.scss b/ui/src/components/Header/index.scss index f1df512d4..e9536b084 100644 --- a/ui/src/components/Header/index.scss +++ b/ui/src/components/Header/index.scss @@ -30,6 +30,11 @@ max-height: 2rem; } + .fixed-width { + padding-left: 28px; + padding-right: 36px; + } + .create-icon { color: var(--bs-nav-link-color); } @@ -120,6 +125,9 @@ @media (max-width: 1199.9px) { #header { + .fixed-width { + padding-right: 48px; + } .nav-grow { flex-grow: 1 !important; } @@ -134,8 +142,21 @@ } } +@media screen and (max-width: 991px) { + #header { + .fixed-width { + padding-left: 40px; + padding-right: 48px; + } + } +} + @media screen and (max-width: 767px) { #header { + .fixed-width { + padding-left: 1.5rem; + padding-right: 1.5rem; + } .nav-text { flex: 1; white-space: nowrap; diff --git a/ui/src/components/Header/index.tsx b/ui/src/components/Header/index.tsx index 4e9c8189a..22aad5aa1 100644 --- a/ui/src/components/Header/index.tsx +++ b/ui/src/components/Header/index.tsx @@ -115,8 +115,8 @@ const Header: FC = () => { id="header">
        Date: Tue, 9 Dec 2025 01:08:57 +0100 Subject: [PATCH 49/92] refactor(queue): improve queues * fix race condition for registering handler * add close method * use generics to reduce duplication * rename packages to drop underscore for go convention * rename interface to drop stutter with package name Signed-off-by: ferhat elmas --- cmd/wire_gen.go | 54 ++--- internal/base/queue/queue.go | 120 ++++++++++ internal/base/queue/queue_test.go | 211 ++++++++++++++++++ internal/controller/template_controller.go | 6 +- internal/repo/activity/answer_repo.go | 6 +- internal/repo/activity/vote_repo.go | 6 +- internal/service/activity_common/activity.go | 6 +- .../service/activity_queue/activity_queue.go | 69 ------ .../service/activityqueue/activity_queue.go | 31 +++ internal/service/badge/badge_award_service.go | 6 +- internal/service/badge/badge_event_handler.go | 6 +- internal/service/comment/comment_service.go | 22 +- internal/service/content/answer_service.go | 22 +- internal/service/content/question_service.go | 22 +- internal/service/content/revision_service.go | 12 +- internal/service/content/user_service.go | 6 +- internal/service/content/vote_service.go | 6 +- internal/service/event_queue/event_queue.go | 69 ------ internal/service/eventqueue/event_queue.go | 31 +++ internal/service/meta/meta_service.go | 6 +- .../external_notification_queue.go | 69 ------ internal/service/notice_queue/notice_queue.go | 69 ------ internal/service/noticequeue/notice_queue.go | 37 +++ .../notification/external_notification.go | 6 +- .../notification_common/notification.go | 6 +- internal/service/provider.go | 14 +- internal/service/question_common/question.go | 6 +- internal/service/report/report_service.go | 6 +- internal/service/review/review_service.go | 10 +- internal/service/tag/tag_service.go | 6 +- internal/service/tag_common/tag_common.go | 6 +- 31 files changed, 553 insertions(+), 399 deletions(-) create mode 100644 internal/base/queue/queue.go create mode 100644 internal/base/queue/queue_test.go delete mode 100644 internal/service/activity_queue/activity_queue.go create mode 100644 internal/service/activityqueue/activity_queue.go delete mode 100644 internal/service/event_queue/event_queue.go create mode 100644 internal/service/eventqueue/event_queue.go delete mode 100644 internal/service/notice_queue/external_notification_queue.go delete mode 100644 internal/service/notice_queue/notice_queue.go create mode 100644 internal/service/noticequeue/notice_queue.go diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index aae1c6af6..22a70f29d 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -72,7 +72,7 @@ import ( "github.com/apache/answer/internal/service/action" activity2 "github.com/apache/answer/internal/service/activity" activity_common2 "github.com/apache/answer/internal/service/activity_common" - "github.com/apache/answer/internal/service/activity_queue" + "github.com/apache/answer/internal/service/activityqueue" "github.com/apache/answer/internal/service/answer_common" auth2 "github.com/apache/answer/internal/service/auth" badge2 "github.com/apache/answer/internal/service/badge" @@ -83,14 +83,14 @@ import ( config2 "github.com/apache/answer/internal/service/config" "github.com/apache/answer/internal/service/content" "github.com/apache/answer/internal/service/dashboard" - "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/service/eventqueue" export2 "github.com/apache/answer/internal/service/export" file_record2 "github.com/apache/answer/internal/service/file_record" "github.com/apache/answer/internal/service/follow" "github.com/apache/answer/internal/service/importer" meta2 "github.com/apache/answer/internal/service/meta" "github.com/apache/answer/internal/service/meta_common" - "github.com/apache/answer/internal/service/notice_queue" + "github.com/apache/answer/internal/service/noticequeue" "github.com/apache/answer/internal/service/notification" "github.com/apache/answer/internal/service/notification_common" "github.com/apache/answer/internal/service/object_info" @@ -172,29 +172,29 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, tagRepo := tag.NewTagRepo(dataData, uniqueIDRepo) revisionRepo := revision.NewRevisionRepo(dataData, uniqueIDRepo) revisionService := revision_common.NewRevisionService(revisionRepo, userRepo) - activityQueueService := activity_queue.NewActivityQueueService() - tagCommonService := tag_common2.NewTagCommonService(tagCommonRepo, tagRelRepo, tagRepo, revisionService, siteInfoCommonService, activityQueueService) + v := activityqueue.NewService() + tagCommonService := tag_common2.NewTagCommonService(tagCommonRepo, tagRelRepo, tagRepo, revisionService, siteInfoCommonService, v) collectionRepo := collection.NewCollectionRepo(dataData, uniqueIDRepo) collectionCommon := collectioncommon.NewCollectionCommon(collectionRepo) answerCommon := answercommon.NewAnswerCommon(answerRepo) metaRepo := meta.NewMetaRepo(dataData) metaCommonService := metacommon.NewMetaCommonService(metaRepo) - questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaCommonService, configService, activityQueueService, revisionRepo, siteInfoCommonService, dataData) - eventQueueService := event_queue.NewEventQueueService() + questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaCommonService, configService, v, revisionRepo, siteInfoCommonService, dataData) + v2 := eventqueue.NewService() fileRecordRepo := file_record.NewFileRecordRepo(dataData) fileRecordService := file_record2.NewFileRecordService(fileRecordRepo, revisionRepo, serviceConf, siteInfoCommonService, userCommon) - userService := content.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo, userNotificationConfigService, questionCommon, eventQueueService, fileRecordService) + userService := content.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo, userNotificationConfigService, questionCommon, v2, fileRecordService) captchaRepo := captcha.NewCaptchaRepo(dataData) captchaService := action.NewCaptchaService(captchaRepo) userController := controller.NewUserController(authService, userService, captchaService, emailService, siteInfoCommonService, userNotificationConfigService) commentRepo := comment.NewCommentRepo(dataData, uniqueIDRepo) commentCommonRepo := comment.NewCommentCommonRepo(dataData, uniqueIDRepo) objService := object_info.NewObjService(answerRepo, questionRepo, commentCommonRepo, tagCommonRepo, tagCommonService) - notificationQueueService := notice_queue.NewNotificationQueueService() - externalNotificationQueueService := notice_queue.NewNewQuestionNotificationQueueService() + v3 := noticequeue.NewService() + v4 := noticequeue.NewExternalService() reviewRepo := review.NewReviewRepo(dataData) - reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, externalNotificationQueueService, tagCommonService, questionCommon, notificationQueueService, siteInfoCommonService, commentCommonRepo) - commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, notificationQueueService, externalNotificationQueueService, activityQueueService, eventQueueService, reviewService) + reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, v4, tagCommonService, questionCommon, v3, siteInfoCommonService, commentCommonRepo) + commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, v3, v4, v, v2, reviewService) rolePowerRelRepo := role.NewRolePowerRelRepo(dataData) rolePowerRelService := role2.NewRolePowerRelService(rolePowerRelRepo, userRoleRelService) rankService := rank2.NewRankService(userCommon, userRankRepo, objService, userRoleRelService, rolePowerRelService, configService) @@ -202,17 +202,17 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, rateLimitMiddleware := middleware.NewRateLimitMiddleware(limitRepo) commentController := controller.NewCommentController(commentService, rankService, captchaService, rateLimitMiddleware) reportRepo := report.NewReportRepo(dataData, uniqueIDRepo) - tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, activityQueueService) - answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, notificationQueueService) + tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, v) + answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, v3) answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, configService) - externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, externalNotificationQueueService, userExternalLoginRepo, siteInfoCommonService) - questionService := content.NewQuestionService(activityRepo, questionRepo, answerRepo, tagCommonService, tagService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, notificationQueueService, externalNotificationQueueService, activityQueueService, siteInfoCommonService, externalNotificationService, reviewService, configService, eventQueueService, reviewRepo) - answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, notificationQueueService, externalNotificationQueueService, activityQueueService, reviewService, eventQueueService) + externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, v4, userExternalLoginRepo, siteInfoCommonService) + questionService := content.NewQuestionService(activityRepo, questionRepo, answerRepo, tagCommonService, tagService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, v3, v4, v, siteInfoCommonService, externalNotificationService, reviewService, configService, v2, reviewRepo) + answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, v3, v4, v, reviewService, v2) reportHandle := report_handle.NewReportHandle(questionService, answerService, commentService) - reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, eventQueueService) + reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, v2) reportController := controller.NewReportController(reportService, rankService, captchaService) - contentVoteRepo := activity.NewVoteRepo(dataData, activityRepo, userRankRepo, notificationQueueService) - voteService := content.NewVoteService(contentVoteRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService, eventQueueService) + contentVoteRepo := activity.NewVoteRepo(dataData, activityRepo, userRankRepo, v3) + voteService := content.NewVoteService(contentVoteRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService, v2) voteController := controller.NewVoteController(voteService, rankService, captchaService) tagController := controller.NewTagController(tagService, tagCommonService, rankService) followFollowRepo := activity.NewFollowRepo(dataData, uniqueIDRepo, activityRepo) @@ -228,7 +228,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, searchService := content.NewSearchService(searchParser, searchRepo) searchController := controller.NewSearchController(searchService, captchaService) reviewActivityRepo := activity.NewReviewActivityRepo(dataData, activityRepo, userRankRepo, configService) - contentRevisionService := content.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService, notificationQueueService, activityQueueService, reportRepo, reviewService, reviewActivityRepo) + contentRevisionService := content.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService, v3, v, reportRepo, reviewService, reviewActivityRepo) revisionController := controller.NewRevisionController(contentRevisionService, rankService) rankController := controller.NewRankController(rankService) userAdminRepo := user.NewUserAdminRepo(dataData, authRepo) @@ -244,7 +244,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, siteInfoService := siteinfo.NewSiteInfoService(siteInfoRepo, siteInfoCommonService, emailService, tagCommonService, configService, questionCommon, fileRecordService) siteInfoController := controller_admin.NewSiteInfoController(siteInfoService) controllerSiteInfoController := controller.NewSiteInfoController(siteInfoCommonService) - notificationCommon := notificationcommon.NewNotificationCommon(dataData, notificationRepo, userCommon, activityRepo, followRepo, objService, notificationQueueService, userExternalLoginRepo, siteInfoCommonService) + notificationCommon := notificationcommon.NewNotificationCommon(dataData, notificationRepo, userCommon, activityRepo, followRepo, objService, v3, userExternalLoginRepo, siteInfoCommonService) badgeRepo := badge.NewBadgeRepo(dataData, uniqueIDRepo) notificationService := notification.NewNotificationService(dataData, notificationRepo, notificationCommon, revisionService, userRepo, reportRepo, reviewService, badgeRepo) notificationController := controller.NewNotificationController(notificationService, rankService) @@ -253,7 +253,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, uploaderService := uploader.NewUploaderService(serviceConf, siteInfoCommonService, fileRecordService) uploadController := controller.NewUploadController(uploaderService) activityActivityRepo := activity.NewActivityRepo(dataData, configService) - activityCommon := activity_common2.NewActivityCommon(activityRepo, activityQueueService) + activityCommon := activity_common2.NewActivityCommon(activityRepo, v) commentCommonService := comment_common.NewCommentCommonService(commentCommonRepo) activityService := activity2.NewActivityService(activityActivityRepo, userCommon, activityCommon, tagCommonService, objService, commentCommonService, revisionService, metaCommonService, configService) activityController := controller.NewActivityController(activityService) @@ -265,12 +265,12 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, permissionController := controller.NewPermissionController(rankService) userPluginController := controller.NewUserPluginController(pluginCommonService) reviewController := controller.NewReviewController(reviewService, rankService, captchaService) - metaService := meta2.NewMetaService(metaCommonService, userCommon, answerRepo, questionRepo, eventQueueService) + metaService := meta2.NewMetaService(metaCommonService, userCommon, answerRepo, questionRepo, v2) metaController := controller.NewMetaController(metaService) badgeGroupRepo := badge_group.NewBadgeGroupRepo(dataData, uniqueIDRepo) eventRuleRepo := badge.NewEventRuleRepo(dataData) - badgeAwardService := badge2.NewBadgeAwardService(badgeAwardRepo, badgeRepo, userCommon, objService, notificationQueueService) - badgeEventService := badge2.NewBadgeEventService(dataData, eventQueueService, badgeRepo, eventRuleRepo, badgeAwardService) + badgeAwardService := badge2.NewBadgeAwardService(badgeAwardRepo, badgeRepo, userCommon, objService, v3) + badgeEventService := badge2.NewBadgeEventService(dataData, v2, badgeRepo, eventRuleRepo, badgeAwardService) badgeService := badge2.NewBadgeService(badgeRepo, badgeGroupRepo, badgeAwardRepo, badgeEventService, siteInfoCommonService) badgeController := controller.NewBadgeController(badgeService, badgeAwardService) controller_adminBadgeController := controller_admin.NewBadgeController(badgeService) @@ -281,7 +281,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, avatarMiddleware := middleware.NewAvatarMiddleware(serviceConf, uploaderService) shortIDMiddleware := middleware.NewShortIDMiddleware(siteInfoCommonService) templateRenderController := templaterender.NewTemplateRenderController(questionService, userService, tagService, answerService, commentService, siteInfoCommonService, questionRepo) - templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService, eventQueueService, userService, questionService) + templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService, v2, userService, questionService) templateRouter := router.NewTemplateRouter(templateController, templateRenderController, siteInfoController, authUserMiddleware) connectorController := controller.NewConnectorController(siteInfoCommonService, emailService, userExternalLoginService) userCenterLoginService := user_external_login2.NewUserCenterLoginService(userRepo, userCommon, userExternalLoginRepo, userActiveActivityRepo, siteInfoCommonService) diff --git a/internal/base/queue/queue.go b/internal/base/queue/queue.go new file mode 100644 index 000000000..ae23d341c --- /dev/null +++ b/internal/base/queue/queue.go @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package queue + +import ( + "context" + "sync" + + "github.com/segmentfault/pacman/log" +) + +// Queue is a generic message queue service that processes messages asynchronously. +// It is thread-safe and supports graceful shutdown. +type Queue[T any] struct { + name string + queue chan T + handler func(ctx context.Context, msg T) error + mu sync.RWMutex + closed bool + wg sync.WaitGroup +} + +// New creates a new queue with the given name and buffer size. +func New[T any](name string, bufferSize int) *Queue[T] { + q := &Queue[T]{ + name: name, + queue: make(chan T, bufferSize), + } + q.startWorker() + return q +} + +// Send enqueues a message to be processed asynchronously. +// It will block if the queue is full. +func (q *Queue[T]) Send(ctx context.Context, msg T) { + q.mu.RLock() + closed := q.closed + q.mu.RUnlock() + + if closed { + log.Warnf("[%s] queue is closed, dropping message", q.name) + return + } + + select { + case q.queue <- msg: + log.Debugf("[%s] enqueued message: %+v", q.name, msg) + case <-ctx.Done(): + log.Warnf("[%s] context cancelled while sending message", q.name) + } +} + +// RegisterHandler sets the handler function for processing messages. +// This is thread-safe and can be called at any time. +func (q *Queue[T]) RegisterHandler(handler func(ctx context.Context, msg T) error) { + q.mu.Lock() + defer q.mu.Unlock() + q.handler = handler +} + +// Close gracefully shuts down the queue, waiting for pending messages to be processed. +func (q *Queue[T]) Close() { + q.mu.Lock() + if q.closed { + q.mu.Unlock() + return + } + q.closed = true + q.mu.Unlock() + + close(q.queue) + q.wg.Wait() + log.Infof("[%s] queue closed", q.name) +} + +// startWorker starts the background goroutine that processes messages. +func (q *Queue[T]) startWorker() { + q.wg.Add(1) + go func() { + defer q.wg.Done() + for msg := range q.queue { + q.processMessage(msg) + } + }() +} + +// processMessage handles a single message with proper synchronization. +func (q *Queue[T]) processMessage(msg T) { + q.mu.RLock() + handler := q.handler + q.mu.RUnlock() + + if handler == nil { + log.Warnf("[%s] no handler registered, dropping message: %+v", q.name, msg) + return + } + + // Use background context for async processing + // TODO: Consider adding timeout or using a derived context + if err := handler(context.TODO(), msg); err != nil { + log.Errorf("[%s] handler error: %v", q.name, err) + } +} diff --git a/internal/base/queue/queue_test.go b/internal/base/queue/queue_test.go new file mode 100644 index 000000000..79355fb72 --- /dev/null +++ b/internal/base/queue/queue_test.go @@ -0,0 +1,211 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package queue + +import ( + "context" + "sync" + "sync/atomic" + "testing" + "time" +) + +type testMessage struct { + ID int + Data string +} + +func TestQueue_SendAndReceive(t *testing.T) { + q := New[*testMessage]("test", 10) + defer q.Close() + + received := make(chan *testMessage, 1) + q.RegisterHandler(func(ctx context.Context, msg *testMessage) error { + received <- msg + return nil + }) + + msg := &testMessage{ID: 1, Data: "hello"} + q.Send(context.Background(), msg) + + select { + case r := <-received: + if r.ID != msg.ID || r.Data != msg.Data { + t.Errorf("received message mismatch: got %+v, want %+v", r, msg) + } + case <-time.After(time.Second): + t.Fatal("timeout waiting for message") + } +} + +func TestQueue_MultipleMessages(t *testing.T) { + q := New[*testMessage]("test", 10) + defer q.Close() + + var count atomic.Int32 + var wg sync.WaitGroup + numMessages := 100 + wg.Add(numMessages) + + q.RegisterHandler(func(ctx context.Context, msg *testMessage) error { + count.Add(1) + wg.Done() + return nil + }) + + for i := range numMessages { + q.Send(context.Background(), &testMessage{ID: i}) + } + + done := make(chan struct{}) + go func() { + wg.Wait() + close(done) + }() + + select { + case <-done: + if int(count.Load()) != numMessages { + t.Errorf("expected %d messages, got %d", numMessages, count.Load()) + } + case <-time.After(5 * time.Second): + t.Fatalf("timeout: only received %d of %d messages", count.Load(), numMessages) + } +} + +func TestQueue_NoHandlerDropsMessage(t *testing.T) { + q := New[*testMessage]("test", 10) + defer q.Close() + + // Send without handler - should not panic + q.Send(context.Background(), &testMessage{ID: 1}) + + // Give time for the message to be processed (dropped) + time.Sleep(100 * time.Millisecond) +} + +func TestQueue_RegisterHandlerAfterSend(t *testing.T) { + q := New[*testMessage]("test", 10) + defer q.Close() + + received := make(chan *testMessage, 1) + + // Send first + q.Send(context.Background(), &testMessage{ID: 1}) + + // Small delay then register handler + time.Sleep(50 * time.Millisecond) + q.RegisterHandler(func(ctx context.Context, msg *testMessage) error { + received <- msg + return nil + }) + + // Send another message that should be received + q.Send(context.Background(), &testMessage{ID: 2}) + + select { + case r := <-received: + if r.ID != 2 { + // First message was dropped (no handler), second should be received + t.Logf("received message ID: %d", r.ID) + } + case <-time.After(time.Second): + t.Fatal("timeout waiting for message") + } +} + +func TestQueue_Close(t *testing.T) { + q := New[*testMessage]("test", 10) + + var count atomic.Int32 + q.RegisterHandler(func(ctx context.Context, msg *testMessage) error { + count.Add(1) + return nil + }) + + // Send some messages + for i := range 5 { + q.Send(context.Background(), &testMessage{ID: i}) + } + + // Close and wait + q.Close() + + // All messages should have been processed + if count.Load() != 5 { + t.Errorf("expected 5 messages processed, got %d", count.Load()) + } + + // Sending after close should not panic + q.Send(context.Background(), &testMessage{ID: 99}) +} + +func TestQueue_ConcurrentSend(t *testing.T) { + q := New[*testMessage]("test", 100) + defer q.Close() + + var count atomic.Int32 + q.RegisterHandler(func(ctx context.Context, msg *testMessage) error { + count.Add(1) + return nil + }) + + var wg sync.WaitGroup + numGoroutines := 10 + messagesPerGoroutine := 100 + + for i := range numGoroutines { + wg.Add(1) + go func(id int) { + defer wg.Done() + for j := range messagesPerGoroutine { + q.Send(context.Background(), &testMessage{ID: id*1000 + j}) + } + }(i) + } + + wg.Wait() + + // Wait for processing + time.Sleep(500 * time.Millisecond) + + expected := int32(numGoroutines * messagesPerGoroutine) + if count.Load() != expected { + t.Errorf("expected %d messages, got %d", expected, count.Load()) + } +} + +func TestQueue_ConcurrentRegisterHandler(t *testing.T) { + q := New[*testMessage]("test", 10) + defer q.Close() + + // Concurrently register handlers - should not race + var wg sync.WaitGroup + for range 10 { + wg.Add(1) + go func() { + defer wg.Done() + q.RegisterHandler(func(ctx context.Context, msg *testMessage) error { + return nil + }) + }() + } + wg.Wait() +} diff --git a/internal/controller/template_controller.go b/internal/controller/template_controller.go index 257b02fa4..e6b94f4f2 100644 --- a/internal/controller/template_controller.go +++ b/internal/controller/template_controller.go @@ -32,7 +32,7 @@ import ( "github.com/apache/answer/internal/base/middleware" "github.com/apache/answer/internal/base/pager" "github.com/apache/answer/internal/service/content" - "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/service/eventqueue" "github.com/apache/answer/plugin" "github.com/apache/answer/internal/base/constant" @@ -59,7 +59,7 @@ type TemplateController struct { cssPath string templateRenderController *templaterender.TemplateRenderController siteInfoService siteinfo_common.SiteInfoCommonService - eventQueueService event_queue.EventQueueService + eventQueueService eventqueue.Service userService *content.UserService questionService *content.QuestionService } @@ -68,7 +68,7 @@ type TemplateController struct { func NewTemplateController( templateRenderController *templaterender.TemplateRenderController, siteInfoService siteinfo_common.SiteInfoCommonService, - eventQueueService event_queue.EventQueueService, + eventQueueService eventqueue.Service, userService *content.UserService, questionService *content.QuestionService, ) *TemplateController { diff --git a/internal/repo/activity/answer_repo.go b/internal/repo/activity/answer_repo.go index 4aca874a7..96813f50c 100644 --- a/internal/repo/activity/answer_repo.go +++ b/internal/repo/activity/answer_repo.go @@ -34,7 +34,7 @@ import ( "github.com/apache/answer/internal/schema" "github.com/apache/answer/internal/service/activity" "github.com/apache/answer/internal/service/activity_common" - "github.com/apache/answer/internal/service/notice_queue" + "github.com/apache/answer/internal/service/noticequeue" "github.com/apache/answer/internal/service/rank" "github.com/apache/answer/pkg/converter" "github.com/segmentfault/pacman/errors" @@ -46,7 +46,7 @@ type AnswerActivityRepo struct { data *data.Data activityRepo activity_common.ActivityRepo userRankRepo rank.UserRankRepo - notificationQueueService notice_queue.NotificationQueueService + notificationQueueService noticequeue.Service } // NewAnswerActivityRepo new repository @@ -54,7 +54,7 @@ func NewAnswerActivityRepo( data *data.Data, activityRepo activity_common.ActivityRepo, userRankRepo rank.UserRankRepo, - notificationQueueService notice_queue.NotificationQueueService, + notificationQueueService noticequeue.Service, ) activity.AnswerActivityRepo { return &AnswerActivityRepo{ data: data, diff --git a/internal/repo/activity/vote_repo.go b/internal/repo/activity/vote_repo.go index f2d2be5f8..389ae18d8 100644 --- a/internal/repo/activity/vote_repo.go +++ b/internal/repo/activity/vote_repo.go @@ -28,7 +28,7 @@ import ( "github.com/segmentfault/pacman/log" "github.com/apache/answer/internal/base/constant" - "github.com/apache/answer/internal/service/notice_queue" + "github.com/apache/answer/internal/service/noticequeue" "github.com/apache/answer/pkg/converter" "github.com/apache/answer/internal/base/pager" @@ -51,7 +51,7 @@ type VoteRepo struct { data *data.Data activityRepo activity_common.ActivityRepo userRankRepo rank.UserRankRepo - notificationQueueService notice_queue.NotificationQueueService + notificationQueueService noticequeue.Service } // NewVoteRepo new repository @@ -59,7 +59,7 @@ func NewVoteRepo( data *data.Data, activityRepo activity_common.ActivityRepo, userRankRepo rank.UserRankRepo, - notificationQueueService notice_queue.NotificationQueueService, + notificationQueueService noticequeue.Service, ) content.VoteRepo { return &VoteRepo{ data: data, diff --git a/internal/service/activity_common/activity.go b/internal/service/activity_common/activity.go index 74f73a755..3d2efd6a3 100644 --- a/internal/service/activity_common/activity.go +++ b/internal/service/activity_common/activity.go @@ -25,7 +25,7 @@ import ( "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" - "github.com/apache/answer/internal/service/activity_queue" + "github.com/apache/answer/internal/service/activityqueue" "github.com/apache/answer/pkg/converter" "github.com/apache/answer/pkg/uid" "github.com/segmentfault/pacman/log" @@ -49,13 +49,13 @@ type ActivityRepo interface { type ActivityCommon struct { activityRepo ActivityRepo - activityQueueService activity_queue.ActivityQueueService + activityQueueService activityqueue.Service } // NewActivityCommon new activity common func NewActivityCommon( activityRepo ActivityRepo, - activityQueueService activity_queue.ActivityQueueService, + activityQueueService activityqueue.Service, ) *ActivityCommon { activity := &ActivityCommon{ activityRepo: activityRepo, diff --git a/internal/service/activity_queue/activity_queue.go b/internal/service/activity_queue/activity_queue.go deleted file mode 100644 index 7b8c1e3b8..000000000 --- a/internal/service/activity_queue/activity_queue.go +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package activity_queue - -import ( - "context" - - "github.com/apache/answer/internal/schema" - "github.com/segmentfault/pacman/log" -) - -type ActivityQueueService interface { - Send(ctx context.Context, msg *schema.ActivityMsg) - RegisterHandler(handler func(ctx context.Context, msg *schema.ActivityMsg) error) -} - -type activityQueueService struct { - Queue chan *schema.ActivityMsg - Handler func(ctx context.Context, msg *schema.ActivityMsg) error -} - -func (ns *activityQueueService) Send(ctx context.Context, msg *schema.ActivityMsg) { - ns.Queue <- msg -} - -func (ns *activityQueueService) RegisterHandler( - handler func(ctx context.Context, msg *schema.ActivityMsg) error) { - ns.Handler = handler -} - -func (ns *activityQueueService) working() { - go func() { - for msg := range ns.Queue { - log.Debugf("received activity %+v", msg) - if ns.Handler == nil { - log.Warnf("no handler for activity") - continue - } - if err := ns.Handler(context.Background(), msg); err != nil { - log.Error(err) - } - } - }() -} - -// NewActivityQueueService create a new activity queue service -func NewActivityQueueService() ActivityQueueService { - ns := &activityQueueService{} - ns.Queue = make(chan *schema.ActivityMsg, 128) - ns.working() - return ns -} diff --git a/internal/service/activityqueue/activity_queue.go b/internal/service/activityqueue/activity_queue.go new file mode 100644 index 000000000..d32caf5e9 --- /dev/null +++ b/internal/service/activityqueue/activity_queue.go @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package activityqueue + +import ( + "github.com/apache/answer/internal/base/queue" + "github.com/apache/answer/internal/schema" +) + +type Service = *queue.Queue[*schema.ActivityMsg] + +func NewService() Service { + return queue.New[*schema.ActivityMsg]("activity", 128) +} diff --git a/internal/service/badge/badge_award_service.go b/internal/service/badge/badge_award_service.go index 982c1d1a4..0799b87c0 100644 --- a/internal/service/badge/badge_award_service.go +++ b/internal/service/badge/badge_award_service.go @@ -28,7 +28,7 @@ import ( "github.com/apache/answer/internal/base/translator" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" - "github.com/apache/answer/internal/service/notice_queue" + "github.com/apache/answer/internal/service/noticequeue" "github.com/apache/answer/internal/service/object_info" usercommon "github.com/apache/answer/internal/service/user_common" "github.com/apache/answer/pkg/uid" @@ -62,7 +62,7 @@ type BadgeAwardService struct { badgeRepo BadgeRepo userCommon *usercommon.UserCommon objectInfoService *object_info.ObjService - notificationQueueService notice_queue.NotificationQueueService + notificationQueueService noticequeue.Service } func NewBadgeAwardService( @@ -70,7 +70,7 @@ func NewBadgeAwardService( badgeRepo BadgeRepo, userCommon *usercommon.UserCommon, objectInfoService *object_info.ObjService, - notificationQueueService notice_queue.NotificationQueueService, + notificationQueueService noticequeue.Service, ) *BadgeAwardService { return &BadgeAwardService{ badgeAwardRepo: badgeAwardRepo, diff --git a/internal/service/badge/badge_event_handler.go b/internal/service/badge/badge_event_handler.go index 24cabf29b..0a9a84c0f 100644 --- a/internal/service/badge/badge_event_handler.go +++ b/internal/service/badge/badge_event_handler.go @@ -25,13 +25,13 @@ import ( "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" - "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/service/eventqueue" "github.com/segmentfault/pacman/log" ) type BadgeEventService struct { data *data.Data - eventQueueService event_queue.EventQueueService + eventQueueService eventqueue.Service badgeRepo BadgeRepo eventRuleRepo EventRuleRepo badgeAwardService *BadgeAwardService @@ -45,7 +45,7 @@ type EventRuleRepo interface { func NewBadgeEventService( data *data.Data, - eventQueueService event_queue.EventQueueService, + eventQueueService eventqueue.Service, badgeRepo BadgeRepo, eventRuleRepo EventRuleRepo, badgeAwardService *BadgeAwardService, diff --git a/internal/service/comment/comment_service.go b/internal/service/comment/comment_service.go index dc599e6df..30ff43c6b 100644 --- a/internal/service/comment/comment_service.go +++ b/internal/service/comment/comment_service.go @@ -22,7 +22,7 @@ package comment import ( "context" - "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/service/eventqueue" "github.com/apache/answer/internal/service/review" "time" @@ -33,10 +33,10 @@ import ( "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" "github.com/apache/answer/internal/service/activity_common" - "github.com/apache/answer/internal/service/activity_queue" + "github.com/apache/answer/internal/service/activityqueue" "github.com/apache/answer/internal/service/comment_common" "github.com/apache/answer/internal/service/export" - "github.com/apache/answer/internal/service/notice_queue" + "github.com/apache/answer/internal/service/noticequeue" "github.com/apache/answer/internal/service/object_info" "github.com/apache/answer/internal/service/permission" usercommon "github.com/apache/answer/internal/service/user_common" @@ -88,10 +88,10 @@ type CommentService struct { objectInfoService *object_info.ObjService emailService *export.EmailService userRepo usercommon.UserRepo - notificationQueueService notice_queue.NotificationQueueService - externalNotificationQueueService notice_queue.ExternalNotificationQueueService - activityQueueService activity_queue.ActivityQueueService - eventQueueService event_queue.EventQueueService + notificationQueueService noticequeue.Service + externalNotificationQueueService noticequeue.ExternalService + activityQueueService activityqueue.Service + eventQueueService eventqueue.Service reviewService *review.ReviewService } @@ -104,10 +104,10 @@ func NewCommentService( voteCommon activity_common.VoteRepo, emailService *export.EmailService, userRepo usercommon.UserRepo, - notificationQueueService notice_queue.NotificationQueueService, - externalNotificationQueueService notice_queue.ExternalNotificationQueueService, - activityQueueService activity_queue.ActivityQueueService, - eventQueueService event_queue.EventQueueService, + notificationQueueService noticequeue.Service, + externalNotificationQueueService noticequeue.ExternalService, + activityQueueService activityqueue.Service, + eventQueueService eventqueue.Service, reviewService *review.ReviewService, ) *CommentService { return &CommentService{ diff --git a/internal/service/content/answer_service.go b/internal/service/content/answer_service.go index d3aab20b3..2ad875177 100644 --- a/internal/service/content/answer_service.go +++ b/internal/service/content/answer_service.go @@ -24,7 +24,7 @@ import ( "encoding/json" "time" - "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/service/eventqueue" "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/reason" @@ -32,11 +32,11 @@ import ( "github.com/apache/answer/internal/schema" "github.com/apache/answer/internal/service/activity" "github.com/apache/answer/internal/service/activity_common" - "github.com/apache/answer/internal/service/activity_queue" + "github.com/apache/answer/internal/service/activityqueue" answercommon "github.com/apache/answer/internal/service/answer_common" collectioncommon "github.com/apache/answer/internal/service/collection_common" "github.com/apache/answer/internal/service/export" - "github.com/apache/answer/internal/service/notice_queue" + "github.com/apache/answer/internal/service/noticequeue" "github.com/apache/answer/internal/service/permission" questioncommon "github.com/apache/answer/internal/service/question_common" "github.com/apache/answer/internal/service/review" @@ -65,11 +65,11 @@ type AnswerService struct { voteRepo activity_common.VoteRepo emailService *export.EmailService roleService *role.UserRoleRelService - notificationQueueService notice_queue.NotificationQueueService - externalNotificationQueueService notice_queue.ExternalNotificationQueueService - activityQueueService activity_queue.ActivityQueueService + notificationQueueService noticequeue.Service + externalNotificationQueueService noticequeue.ExternalService + activityQueueService activityqueue.Service reviewService *review.ReviewService - eventQueueService event_queue.EventQueueService + eventQueueService eventqueue.Service } func NewAnswerService( @@ -85,11 +85,11 @@ func NewAnswerService( voteRepo activity_common.VoteRepo, emailService *export.EmailService, roleService *role.UserRoleRelService, - notificationQueueService notice_queue.NotificationQueueService, - externalNotificationQueueService notice_queue.ExternalNotificationQueueService, - activityQueueService activity_queue.ActivityQueueService, + notificationQueueService noticequeue.Service, + externalNotificationQueueService noticequeue.ExternalService, + activityQueueService activityqueue.Service, reviewService *review.ReviewService, - eventQueueService event_queue.EventQueueService, + eventQueueService eventqueue.Service, ) *AnswerService { return &AnswerService{ answerRepo: answerRepo, diff --git a/internal/service/content/question_service.go b/internal/service/content/question_service.go index b8372a72e..bc3ac0bb6 100644 --- a/internal/service/content/question_service.go +++ b/internal/service/content/question_service.go @@ -25,7 +25,7 @@ import ( "strings" "time" - "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/service/eventqueue" "github.com/apache/answer/plugin" "github.com/apache/answer/internal/base/constant" @@ -38,13 +38,13 @@ import ( "github.com/apache/answer/internal/schema" "github.com/apache/answer/internal/service/activity" "github.com/apache/answer/internal/service/activity_common" - "github.com/apache/answer/internal/service/activity_queue" + "github.com/apache/answer/internal/service/activityqueue" answercommon "github.com/apache/answer/internal/service/answer_common" collectioncommon "github.com/apache/answer/internal/service/collection_common" "github.com/apache/answer/internal/service/config" "github.com/apache/answer/internal/service/export" metacommon "github.com/apache/answer/internal/service/meta_common" - "github.com/apache/answer/internal/service/notice_queue" + "github.com/apache/answer/internal/service/noticequeue" "github.com/apache/answer/internal/service/notification" "github.com/apache/answer/internal/service/permission" questioncommon "github.com/apache/answer/internal/service/question_common" @@ -84,14 +84,14 @@ type QuestionService struct { collectionCommon *collectioncommon.CollectionCommon answerActivityService *activity.AnswerActivityService emailService *export.EmailService - notificationQueueService notice_queue.NotificationQueueService - externalNotificationQueueService notice_queue.ExternalNotificationQueueService - activityQueueService activity_queue.ActivityQueueService + notificationQueueService noticequeue.Service + externalNotificationQueueService noticequeue.ExternalService + activityQueueService activityqueue.Service siteInfoService siteinfo_common.SiteInfoCommonService newQuestionNotificationService *notification.ExternalNotificationService reviewService *review.ReviewService configService *config.ConfigService - eventQueueService event_queue.EventQueueService + eventQueueService eventqueue.Service reviewRepo review.ReviewRepo } @@ -110,14 +110,14 @@ func NewQuestionService( collectionCommon *collectioncommon.CollectionCommon, answerActivityService *activity.AnswerActivityService, emailService *export.EmailService, - notificationQueueService notice_queue.NotificationQueueService, - externalNotificationQueueService notice_queue.ExternalNotificationQueueService, - activityQueueService activity_queue.ActivityQueueService, + notificationQueueService noticequeue.Service, + externalNotificationQueueService noticequeue.ExternalService, + activityQueueService activityqueue.Service, siteInfoService siteinfo_common.SiteInfoCommonService, newQuestionNotificationService *notification.ExternalNotificationService, reviewService *review.ReviewService, configService *config.ConfigService, - eventQueueService event_queue.EventQueueService, + eventQueueService eventqueue.Service, reviewRepo review.ReviewRepo, ) *QuestionService { return &QuestionService{ diff --git a/internal/service/content/revision_service.go b/internal/service/content/revision_service.go index 4ac08e769..13ec65b7d 100644 --- a/internal/service/content/revision_service.go +++ b/internal/service/content/revision_service.go @@ -32,9 +32,9 @@ import ( "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" "github.com/apache/answer/internal/service/activity" - "github.com/apache/answer/internal/service/activity_queue" + "github.com/apache/answer/internal/service/activityqueue" answercommon "github.com/apache/answer/internal/service/answer_common" - "github.com/apache/answer/internal/service/notice_queue" + "github.com/apache/answer/internal/service/noticequeue" "github.com/apache/answer/internal/service/object_info" questioncommon "github.com/apache/answer/internal/service/question_common" "github.com/apache/answer/internal/service/report_common" @@ -62,8 +62,8 @@ type RevisionService struct { answerRepo answercommon.AnswerRepo tagRepo tag_common.TagRepo tagCommon *tag_common.TagCommonService - notificationQueueService notice_queue.NotificationQueueService - activityQueueService activity_queue.ActivityQueueService + notificationQueueService noticequeue.Service + activityQueueService activityqueue.Service reportRepo report_common.ReportRepo reviewService *review.ReviewService reviewActivity activity.ReviewActivityRepo @@ -79,8 +79,8 @@ func NewRevisionService( answerRepo answercommon.AnswerRepo, tagRepo tag_common.TagRepo, tagCommon *tag_common.TagCommonService, - notificationQueueService notice_queue.NotificationQueueService, - activityQueueService activity_queue.ActivityQueueService, + notificationQueueService noticequeue.Service, + activityQueueService activityqueue.Service, reportRepo report_common.ReportRepo, reviewService *review.ReviewService, reviewActivity activity.ReviewActivityRepo, diff --git a/internal/service/content/user_service.go b/internal/service/content/user_service.go index e9cc35788..711d6caa0 100644 --- a/internal/service/content/user_service.go +++ b/internal/service/content/user_service.go @@ -25,7 +25,7 @@ import ( "fmt" "time" - "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/service/eventqueue" "github.com/apache/answer/pkg/token" "github.com/apache/answer/internal/base/constant" @@ -68,7 +68,7 @@ type UserService struct { userNotificationConfigRepo user_notification_config.UserNotificationConfigRepo userNotificationConfigService *user_notification_config.UserNotificationConfigService questionService *questioncommon.QuestionCommon - eventQueueService event_queue.EventQueueService + eventQueueService eventqueue.Service fileRecordService *file_record.FileRecordService } @@ -84,7 +84,7 @@ func NewUserService(userRepo usercommon.UserRepo, userNotificationConfigRepo user_notification_config.UserNotificationConfigRepo, userNotificationConfigService *user_notification_config.UserNotificationConfigService, questionService *questioncommon.QuestionCommon, - eventQueueService event_queue.EventQueueService, + eventQueueService eventqueue.Service, fileRecordService *file_record.FileRecordService, ) *UserService { return &UserService{ diff --git a/internal/service/content/vote_service.go b/internal/service/content/vote_service.go index aa6150497..1f74769f5 100644 --- a/internal/service/content/vote_service.go +++ b/internal/service/content/vote_service.go @@ -24,7 +24,7 @@ import ( "fmt" "strings" - "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/service/eventqueue" "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" @@ -62,7 +62,7 @@ type VoteService struct { answerRepo answercommon.AnswerRepo commentCommonRepo comment_common.CommentCommonRepo objectService *object_info.ObjService - eventQueueService event_queue.EventQueueService + eventQueueService eventqueue.Service } func NewVoteService( @@ -72,7 +72,7 @@ func NewVoteService( answerRepo answercommon.AnswerRepo, commentCommonRepo comment_common.CommentCommonRepo, objectService *object_info.ObjService, - eventQueueService event_queue.EventQueueService, + eventQueueService eventqueue.Service, ) *VoteService { return &VoteService{ voteRepo: voteRepo, diff --git a/internal/service/event_queue/event_queue.go b/internal/service/event_queue/event_queue.go deleted file mode 100644 index 77dc302b5..000000000 --- a/internal/service/event_queue/event_queue.go +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package event_queue - -import ( - "context" - - "github.com/apache/answer/internal/schema" - "github.com/segmentfault/pacman/log" -) - -type EventQueueService interface { - Send(ctx context.Context, msg *schema.EventMsg) - RegisterHandler(handler func(ctx context.Context, msg *schema.EventMsg) error) -} - -type eventQueueService struct { - Queue chan *schema.EventMsg - Handler func(ctx context.Context, msg *schema.EventMsg) error -} - -func (ns *eventQueueService) Send(ctx context.Context, msg *schema.EventMsg) { - ns.Queue <- msg -} - -func (ns *eventQueueService) RegisterHandler( - handler func(ctx context.Context, msg *schema.EventMsg) error) { - ns.Handler = handler -} - -func (ns *eventQueueService) working() { - go func() { - for msg := range ns.Queue { - log.Debugf("received badge %+v", msg) - if ns.Handler == nil { - log.Warnf("no handler for badge") - continue - } - if err := ns.Handler(context.Background(), msg); err != nil { - log.Error(err) - } - } - }() -} - -// NewEventQueueService create a new badge queue service -func NewEventQueueService() EventQueueService { - ns := &eventQueueService{} - ns.Queue = make(chan *schema.EventMsg, 128) - ns.working() - return ns -} diff --git a/internal/service/eventqueue/event_queue.go b/internal/service/eventqueue/event_queue.go new file mode 100644 index 000000000..8d3a22392 --- /dev/null +++ b/internal/service/eventqueue/event_queue.go @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package eventqueue + +import ( + "github.com/apache/answer/internal/base/queue" + "github.com/apache/answer/internal/schema" +) + +type Service = *queue.Queue[*schema.EventMsg] + +func NewService() Service { + return queue.New[*schema.EventMsg]("event", 128) +} diff --git a/internal/service/meta/meta_service.go b/internal/service/meta/meta_service.go index c1ca7c619..e48e8f468 100644 --- a/internal/service/meta/meta_service.go +++ b/internal/service/meta/meta_service.go @@ -26,7 +26,7 @@ import ( "strconv" "strings" - "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/service/eventqueue" "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" @@ -48,7 +48,7 @@ type MetaService struct { userCommon *usercommon.UserCommon questionRepo questioncommon.QuestionRepo answerRepo answercommon.AnswerRepo - eventQueueService event_queue.EventQueueService + eventQueueService eventqueue.Service } func NewMetaService( @@ -56,7 +56,7 @@ func NewMetaService( userCommon *usercommon.UserCommon, answerRepo answercommon.AnswerRepo, questionRepo questioncommon.QuestionRepo, - eventQueueService event_queue.EventQueueService, + eventQueueService eventqueue.Service, ) *MetaService { return &MetaService{ metaCommonService: metaCommonService, diff --git a/internal/service/notice_queue/external_notification_queue.go b/internal/service/notice_queue/external_notification_queue.go deleted file mode 100644 index 6322a77ec..000000000 --- a/internal/service/notice_queue/external_notification_queue.go +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package notice_queue - -import ( - "context" - - "github.com/apache/answer/internal/schema" - "github.com/segmentfault/pacman/log" -) - -type ExternalNotificationQueueService interface { - Send(ctx context.Context, msg *schema.ExternalNotificationMsg) - RegisterHandler(handler func(ctx context.Context, msg *schema.ExternalNotificationMsg) error) -} - -type externalNotificationQueueService struct { - Queue chan *schema.ExternalNotificationMsg - Handler func(ctx context.Context, msg *schema.ExternalNotificationMsg) error -} - -func (ns *externalNotificationQueueService) Send(ctx context.Context, msg *schema.ExternalNotificationMsg) { - ns.Queue <- msg -} - -func (ns *externalNotificationQueueService) RegisterHandler( - handler func(ctx context.Context, msg *schema.ExternalNotificationMsg) error) { - ns.Handler = handler -} - -func (ns *externalNotificationQueueService) working() { - go func() { - for msg := range ns.Queue { - log.Debugf("received notification %+v", msg) - if ns.Handler == nil { - log.Warnf("no handler for notification") - continue - } - if err := ns.Handler(context.Background(), msg); err != nil { - log.Error(err) - } - } - }() -} - -// NewNewQuestionNotificationQueueService create a new notification queue service -func NewNewQuestionNotificationQueueService() ExternalNotificationQueueService { - ns := &externalNotificationQueueService{} - ns.Queue = make(chan *schema.ExternalNotificationMsg, 128) - ns.working() - return ns -} diff --git a/internal/service/notice_queue/notice_queue.go b/internal/service/notice_queue/notice_queue.go deleted file mode 100644 index 22b733e32..000000000 --- a/internal/service/notice_queue/notice_queue.go +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package notice_queue - -import ( - "context" - - "github.com/apache/answer/internal/schema" - "github.com/segmentfault/pacman/log" -) - -type NotificationQueueService interface { - Send(ctx context.Context, msg *schema.NotificationMsg) - RegisterHandler(handler func(ctx context.Context, msg *schema.NotificationMsg) error) -} - -type notificationQueueService struct { - Queue chan *schema.NotificationMsg - Handler func(ctx context.Context, msg *schema.NotificationMsg) error -} - -func (ns *notificationQueueService) Send(ctx context.Context, msg *schema.NotificationMsg) { - ns.Queue <- msg -} - -func (ns *notificationQueueService) RegisterHandler( - handler func(ctx context.Context, msg *schema.NotificationMsg) error) { - ns.Handler = handler -} - -func (ns *notificationQueueService) working() { - go func() { - for msg := range ns.Queue { - log.Debugf("received notification %+v", msg) - if ns.Handler == nil { - log.Warnf("no handler for notification") - continue - } - if err := ns.Handler(context.Background(), msg); err != nil { - log.Error(err) - } - } - }() -} - -// NewNotificationQueueService create a new notification queue service -func NewNotificationQueueService() NotificationQueueService { - ns := ¬ificationQueueService{} - ns.Queue = make(chan *schema.NotificationMsg, 128) - ns.working() - return ns -} diff --git a/internal/service/noticequeue/notice_queue.go b/internal/service/noticequeue/notice_queue.go new file mode 100644 index 000000000..138f9ce61 --- /dev/null +++ b/internal/service/noticequeue/notice_queue.go @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package noticequeue + +import ( + "github.com/apache/answer/internal/base/queue" + "github.com/apache/answer/internal/schema" +) + +type Service = *queue.Queue[*schema.NotificationMsg] + +func NewService() Service { + return queue.New[*schema.NotificationMsg]("notification", 128) +} + +type ExternalService = *queue.Queue[*schema.ExternalNotificationMsg] + +func NewExternalService() ExternalService { + return queue.New[*schema.ExternalNotificationMsg]("external_notification", 128) +} diff --git a/internal/service/notification/external_notification.go b/internal/service/notification/external_notification.go index d6bdd2fb7..425a8c2bb 100644 --- a/internal/service/notification/external_notification.go +++ b/internal/service/notification/external_notification.go @@ -28,7 +28,7 @@ import ( "github.com/apache/answer/internal/schema" "github.com/apache/answer/internal/service/activity_common" "github.com/apache/answer/internal/service/export" - "github.com/apache/answer/internal/service/notice_queue" + "github.com/apache/answer/internal/service/noticequeue" "github.com/apache/answer/internal/service/siteinfo_common" usercommon "github.com/apache/answer/internal/service/user_common" "github.com/apache/answer/internal/service/user_external_login" @@ -42,7 +42,7 @@ type ExternalNotificationService struct { followRepo activity_common.FollowRepo emailService *export.EmailService userRepo usercommon.UserRepo - notificationQueueService notice_queue.ExternalNotificationQueueService + notificationQueueService noticequeue.ExternalService userExternalLoginRepo user_external_login.UserExternalLoginRepo siteInfoService siteinfo_common.SiteInfoCommonService } @@ -53,7 +53,7 @@ func NewExternalNotificationService( followRepo activity_common.FollowRepo, emailService *export.EmailService, userRepo usercommon.UserRepo, - notificationQueueService notice_queue.ExternalNotificationQueueService, + notificationQueueService noticequeue.ExternalService, userExternalLoginRepo user_external_login.UserExternalLoginRepo, siteInfoService siteinfo_common.SiteInfoCommonService, ) *ExternalNotificationService { diff --git a/internal/service/notification_common/notification.go b/internal/service/notification_common/notification.go index 94ce86b16..aa3f4106c 100644 --- a/internal/service/notification_common/notification.go +++ b/internal/service/notification_common/notification.go @@ -35,7 +35,7 @@ import ( "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" "github.com/apache/answer/internal/service/activity_common" - "github.com/apache/answer/internal/service/notice_queue" + "github.com/apache/answer/internal/service/noticequeue" "github.com/apache/answer/internal/service/object_info" usercommon "github.com/apache/answer/internal/service/user_common" "github.com/apache/answer/pkg/uid" @@ -66,7 +66,7 @@ type NotificationCommon struct { followRepo activity_common.FollowRepo userCommon *usercommon.UserCommon objectInfoService *object_info.ObjService - notificationQueueService notice_queue.NotificationQueueService + notificationQueueService noticequeue.Service userExternalLoginRepo user_external_login.UserExternalLoginRepo siteInfoService siteinfo_common.SiteInfoCommonService } @@ -78,7 +78,7 @@ func NewNotificationCommon( activityRepo activity_common.ActivityRepo, followRepo activity_common.FollowRepo, objectInfoService *object_info.ObjService, - notificationQueueService notice_queue.NotificationQueueService, + notificationQueueService noticequeue.Service, userExternalLoginRepo user_external_login.UserExternalLoginRepo, siteInfoService siteinfo_common.SiteInfoCommonService, ) *NotificationCommon { diff --git a/internal/service/provider.go b/internal/service/provider.go index 65535f41b..f6d954709 100644 --- a/internal/service/provider.go +++ b/internal/service/provider.go @@ -23,7 +23,7 @@ import ( "github.com/apache/answer/internal/service/action" "github.com/apache/answer/internal/service/activity" "github.com/apache/answer/internal/service/activity_common" - "github.com/apache/answer/internal/service/activity_queue" + "github.com/apache/answer/internal/service/activityqueue" answercommon "github.com/apache/answer/internal/service/answer_common" "github.com/apache/answer/internal/service/auth" "github.com/apache/answer/internal/service/badge" @@ -34,14 +34,14 @@ import ( "github.com/apache/answer/internal/service/config" "github.com/apache/answer/internal/service/content" "github.com/apache/answer/internal/service/dashboard" - "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/service/eventqueue" "github.com/apache/answer/internal/service/export" "github.com/apache/answer/internal/service/file_record" "github.com/apache/answer/internal/service/follow" "github.com/apache/answer/internal/service/importer" "github.com/apache/answer/internal/service/meta" metacommon "github.com/apache/answer/internal/service/meta_common" - "github.com/apache/answer/internal/service/notice_queue" + "github.com/apache/answer/internal/service/noticequeue" "github.com/apache/answer/internal/service/notification" notficationcommon "github.com/apache/answer/internal/service/notification_common" "github.com/apache/answer/internal/service/object_info" @@ -114,14 +114,14 @@ var ProviderSetService = wire.NewSet( user_external_login.NewUserCenterLoginService, plugin_common.NewPluginCommonService, config.NewConfigService, - notice_queue.NewNotificationQueueService, - activity_queue.NewActivityQueueService, + noticequeue.NewService, + activityqueue.NewService, user_notification_config.NewUserNotificationConfigService, notification.NewExternalNotificationService, - notice_queue.NewNewQuestionNotificationQueueService, + noticequeue.NewExternalService, review.NewReviewService, meta.NewMetaService, - event_queue.NewEventQueueService, + eventqueue.NewService, badge.NewBadgeService, badge.NewBadgeEventService, badge.NewBadgeAwardService, diff --git a/internal/service/question_common/question.go b/internal/service/question_common/question.go index 846dea894..557a5db15 100644 --- a/internal/service/question_common/question.go +++ b/internal/service/question_common/question.go @@ -34,7 +34,7 @@ import ( "github.com/apache/answer/internal/base/handler" "github.com/apache/answer/internal/base/reason" "github.com/apache/answer/internal/service/activity_common" - "github.com/apache/answer/internal/service/activity_queue" + "github.com/apache/answer/internal/service/activityqueue" "github.com/apache/answer/internal/service/config" metacommon "github.com/apache/answer/internal/service/meta_common" "github.com/apache/answer/internal/service/revision" @@ -103,7 +103,7 @@ type QuestionCommon struct { AnswerCommon *answercommon.AnswerCommon metaCommonService *metacommon.MetaCommonService configService *config.ConfigService - activityQueueService activity_queue.ActivityQueueService + activityQueueService activityqueue.Service revisionRepo revision.RevisionRepo siteInfoService siteinfo_common.SiteInfoCommonService data *data.Data @@ -119,7 +119,7 @@ func NewQuestionCommon(questionRepo QuestionRepo, answerCommon *answercommon.AnswerCommon, metaCommonService *metacommon.MetaCommonService, configService *config.ConfigService, - activityQueueService activity_queue.ActivityQueueService, + activityQueueService activityqueue.Service, revisionRepo revision.RevisionRepo, siteInfoService siteinfo_common.SiteInfoCommonService, data *data.Data, diff --git a/internal/service/report/report_service.go b/internal/service/report/report_service.go index d32ccdabf..84c15d597 100644 --- a/internal/service/report/report_service.go +++ b/internal/service/report/report_service.go @@ -22,7 +22,7 @@ package report import ( "encoding/json" - "github.com/apache/answer/internal/service/event_queue" + "github.com/apache/answer/internal/service/eventqueue" "github.com/apache/answer/internal/base/constant" "github.com/apache/answer/internal/base/handler" @@ -57,7 +57,7 @@ type ReportService struct { commentCommonRepo comment_common.CommentCommonRepo reportHandle *report_handle.ReportHandle configService *config.ConfigService - eventQueueService event_queue.EventQueueService + eventQueueService eventqueue.Service } // NewReportService new report service @@ -70,7 +70,7 @@ func NewReportService( commentCommonRepo comment_common.CommentCommonRepo, reportHandle *report_handle.ReportHandle, configService *config.ConfigService, - eventQueueService event_queue.EventQueueService, + eventQueueService eventqueue.Service, ) *ReportService { return &ReportService{ reportRepo: reportRepo, diff --git a/internal/service/review/review_service.go b/internal/service/review/review_service.go index a23b9ee43..bbb142894 100644 --- a/internal/service/review/review_service.go +++ b/internal/service/review/review_service.go @@ -29,7 +29,7 @@ import ( "github.com/apache/answer/internal/schema" answercommon "github.com/apache/answer/internal/service/answer_common" commentcommon "github.com/apache/answer/internal/service/comment_common" - "github.com/apache/answer/internal/service/notice_queue" + "github.com/apache/answer/internal/service/noticequeue" "github.com/apache/answer/internal/service/object_info" questioncommon "github.com/apache/answer/internal/service/question_common" "github.com/apache/answer/internal/service/role" @@ -66,8 +66,8 @@ type ReviewService struct { userRoleService *role.UserRoleRelService tagCommon *tagcommon.TagCommonService questionCommon *questioncommon.QuestionCommon - externalNotificationQueueService notice_queue.ExternalNotificationQueueService - notificationQueueService notice_queue.NotificationQueueService + externalNotificationQueueService noticequeue.ExternalService + notificationQueueService noticequeue.Service siteInfoService siteinfo_common.SiteInfoCommonService commentCommonRepo commentcommon.CommentCommonRepo } @@ -81,10 +81,10 @@ func NewReviewService( questionRepo questioncommon.QuestionRepo, answerRepo answercommon.AnswerRepo, userRoleService *role.UserRoleRelService, - externalNotificationQueueService notice_queue.ExternalNotificationQueueService, + externalNotificationQueueService noticequeue.ExternalService, tagCommon *tagcommon.TagCommonService, questionCommon *questioncommon.QuestionCommon, - notificationQueueService notice_queue.NotificationQueueService, + notificationQueueService noticequeue.Service, siteInfoService siteinfo_common.SiteInfoCommonService, commentCommonRepo commentcommon.CommentCommonRepo, ) *ReviewService { diff --git a/internal/service/tag/tag_service.go b/internal/service/tag/tag_service.go index e61bfa06e..640f06b69 100644 --- a/internal/service/tag/tag_service.go +++ b/internal/service/tag/tag_service.go @@ -25,7 +25,7 @@ import ( "strings" "github.com/apache/answer/internal/base/constant" - "github.com/apache/answer/internal/service/activity_queue" + "github.com/apache/answer/internal/service/activityqueue" "github.com/apache/answer/internal/service/revision_common" "github.com/apache/answer/internal/service/siteinfo_common" tagcommonser "github.com/apache/answer/internal/service/tag_common" @@ -50,7 +50,7 @@ type TagService struct { revisionService *revision_common.RevisionService followCommon activity_common.FollowRepo siteInfoService siteinfo_common.SiteInfoCommonService - activityQueueService activity_queue.ActivityQueueService + activityQueueService activityqueue.Service } // NewTagService new tag service @@ -60,7 +60,7 @@ func NewTagService( revisionService *revision_common.RevisionService, followCommon activity_common.FollowRepo, siteInfoService siteinfo_common.SiteInfoCommonService, - activityQueueService activity_queue.ActivityQueueService, + activityQueueService activityqueue.Service, ) *TagService { return &TagService{ tagRepo: tagRepo, diff --git a/internal/service/tag_common/tag_common.go b/internal/service/tag_common/tag_common.go index 87c10bcc9..9ca8e100f 100644 --- a/internal/service/tag_common/tag_common.go +++ b/internal/service/tag_common/tag_common.go @@ -33,7 +33,7 @@ import ( "github.com/apache/answer/internal/base/validator" "github.com/apache/answer/internal/entity" "github.com/apache/answer/internal/schema" - "github.com/apache/answer/internal/service/activity_queue" + "github.com/apache/answer/internal/service/activityqueue" "github.com/apache/answer/internal/service/revision_common" "github.com/apache/answer/internal/service/siteinfo_common" "github.com/apache/answer/pkg/converter" @@ -89,7 +89,7 @@ type TagCommonService struct { tagRelRepo TagRelRepo tagRepo TagRepo siteInfoService siteinfo_common.SiteInfoCommonService - activityQueueService activity_queue.ActivityQueueService + activityQueueService activityqueue.Service } // NewTagCommonService new tag service @@ -99,7 +99,7 @@ func NewTagCommonService( tagRepo TagRepo, revisionService *revision_common.RevisionService, siteInfoService siteinfo_common.SiteInfoCommonService, - activityQueueService activity_queue.ActivityQueueService, + activityQueueService activityqueue.Service, ) *TagCommonService { return &TagCommonService{ tagCommonRepo: tagCommonRepo, From 5ff6106d37807ef79fd04ab4ba56a43a961bf6fe Mon Sep 17 00:00:00 2001 From: ferhat elmas Date: Tue, 6 Jan 2026 22:25:29 +0100 Subject: [PATCH 50/92] fix: address comments and add a test Signed-off-by: ferhat elmas --- internal/base/queue/queue.go | 16 +++++-- internal/base/queue/queue_test.go | 42 +++++++++++++++++++ .../service/activityqueue/activity_queue.go | 2 +- internal/service/eventqueue/event_queue.go | 2 +- internal/service/noticequeue/notice_queue.go | 4 +- 5 files changed, 59 insertions(+), 7 deletions(-) diff --git a/internal/base/queue/queue.go b/internal/base/queue/queue.go index ae23d341c..b3a8757a2 100644 --- a/internal/base/queue/queue.go +++ b/internal/base/queue/queue.go @@ -26,6 +26,17 @@ import ( "github.com/segmentfault/pacman/log" ) +type Service[T any] interface { + // Send enqueues a message to be processed asynchronously. + Send(ctx context.Context, msg T) + + // RegisterHandler sets the handler function for processing messages. + RegisterHandler(handler func(ctx context.Context, msg T) error) + + // Close gracefully shuts down the queue, waiting for pending messages to be processed. + Close() +} + // Queue is a generic message queue service that processes messages asynchronously. // It is thread-safe and supports graceful shutdown. type Queue[T any] struct { @@ -51,10 +62,9 @@ func New[T any](name string, bufferSize int) *Queue[T] { // It will block if the queue is full. func (q *Queue[T]) Send(ctx context.Context, msg T) { q.mu.RLock() - closed := q.closed - q.mu.RUnlock() + defer q.mu.RUnlock() - if closed { + if q.closed { log.Warnf("[%s] queue is closed, dropping message", q.name) return } diff --git a/internal/base/queue/queue_test.go b/internal/base/queue/queue_test.go index 79355fb72..23f0fda75 100644 --- a/internal/base/queue/queue_test.go +++ b/internal/base/queue/queue_test.go @@ -21,6 +21,7 @@ package queue import ( "context" + "fmt" "sync" "sync/atomic" "testing" @@ -209,3 +210,44 @@ func TestQueue_ConcurrentRegisterHandler(t *testing.T) { } wg.Wait() } + +// TestQueue_SendCloseRace is a regression test for the race condition between +// Send and Close. Without proper synchronization, concurrent Send and Close +// calls could cause a "send on closed channel" panic. +// Run with: go test -race -run TestQueue_SendCloseRace +func TestQueue_SendCloseRace(t *testing.T) { + for i := range 100 { + t.Run(fmt.Sprintf("iteration_%d", i), func(t *testing.T) { + // Use large buffer to avoid blocking on channel send while holding RLock + q := New[*testMessage]("test-race", 1000) + q.RegisterHandler(func(ctx context.Context, msg *testMessage) error { + return nil + }) + + var wg sync.WaitGroup + + // Use cancellable context so senders can exit when Close is called + ctx, cancel := context.WithCancel(context.Background()) + + // Start multiple senders + for j := range 10 { + wg.Add(1) + go func(id int) { + defer wg.Done() + for k := range 100 { + q.Send(ctx, &testMessage{ID: id*1000 + k}) + } + }(j) + } + + // Close while senders are still running + go func() { + time.Sleep(time.Microsecond * 10) + cancel() // Cancel context to unblock any waiting senders + q.Close() + }() + + wg.Wait() + }) + } +} diff --git a/internal/service/activityqueue/activity_queue.go b/internal/service/activityqueue/activity_queue.go index d32caf5e9..2210977bd 100644 --- a/internal/service/activityqueue/activity_queue.go +++ b/internal/service/activityqueue/activity_queue.go @@ -24,7 +24,7 @@ import ( "github.com/apache/answer/internal/schema" ) -type Service = *queue.Queue[*schema.ActivityMsg] +type Service queue.Service[*schema.ActivityMsg] func NewService() Service { return queue.New[*schema.ActivityMsg]("activity", 128) diff --git a/internal/service/eventqueue/event_queue.go b/internal/service/eventqueue/event_queue.go index 8d3a22392..e93a83636 100644 --- a/internal/service/eventqueue/event_queue.go +++ b/internal/service/eventqueue/event_queue.go @@ -24,7 +24,7 @@ import ( "github.com/apache/answer/internal/schema" ) -type Service = *queue.Queue[*schema.EventMsg] +type Service queue.Service[*schema.EventMsg] func NewService() Service { return queue.New[*schema.EventMsg]("event", 128) diff --git a/internal/service/noticequeue/notice_queue.go b/internal/service/noticequeue/notice_queue.go index 138f9ce61..5e4d4b0f9 100644 --- a/internal/service/noticequeue/notice_queue.go +++ b/internal/service/noticequeue/notice_queue.go @@ -24,13 +24,13 @@ import ( "github.com/apache/answer/internal/schema" ) -type Service = *queue.Queue[*schema.NotificationMsg] +type Service queue.Service[*schema.NotificationMsg] func NewService() Service { return queue.New[*schema.NotificationMsg]("notification", 128) } -type ExternalService = *queue.Queue[*schema.ExternalNotificationMsg] +type ExternalService queue.Service[*schema.ExternalNotificationMsg] func NewExternalService() ExternalService { return queue.New[*schema.ExternalNotificationMsg]("external_notification", 128) From 1fbb802e8f4f79bae635b746f44ef7cdc671d89b Mon Sep 17 00:00:00 2001 From: maishivamhoo123 Date: Tue, 23 Dec 2025 14:17:38 +0530 Subject: [PATCH 51/92] feat: load optional .env file and add .env.example --- .env.example | 36 + .gitignore | 3 + README.md | 9 + cmd/main.go | 6 + data/conf/config.yaml | 25 + data/i18n/af_ZA.yaml | 1384 +++++++++++++++++++++++ data/i18n/ar_SA.yaml | 1384 +++++++++++++++++++++++ data/i18n/az_AZ.yaml | 1371 +++++++++++++++++++++++ data/i18n/bal_BA.yaml | 1371 +++++++++++++++++++++++ data/i18n/ban_ID.yaml | 1371 +++++++++++++++++++++++ data/i18n/bn_BD.yaml | 1371 +++++++++++++++++++++++ data/i18n/bs_BA.yaml | 1371 +++++++++++++++++++++++ data/i18n/ca_ES.yaml | 1384 +++++++++++++++++++++++ data/i18n/cs_CZ.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/cy_GB.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/da_DK.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/de_DE.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/el_GR.yaml | 1384 +++++++++++++++++++++++ data/i18n/en_US.yaml | 2395 ++++++++++++++++++++++++++++++++++++++++ data/i18n/es_ES.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/fa_IR.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/fi_FI.yaml | 1384 +++++++++++++++++++++++ data/i18n/fr_FR.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/he_IL.yaml | 1384 +++++++++++++++++++++++ data/i18n/hi_IN.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/hu_HU.yaml | 1384 +++++++++++++++++++++++ data/i18n/hy_AM.yaml | 1371 +++++++++++++++++++++++ data/i18n/i18n.yaml | 64 ++ data/i18n/id_ID.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/it_IT.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/ja_JP.yaml | 2360 ++++++++++++++++++++++++++++++++++++++++ data/i18n/ko_KR.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/ml_IN.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/nl_NL.yaml | 1384 +++++++++++++++++++++++ data/i18n/no_NO.yaml | 1385 +++++++++++++++++++++++ data/i18n/pl_PL.yaml | 2414 +++++++++++++++++++++++++++++++++++++++++ data/i18n/pt_BR.yaml | 1381 +++++++++++++++++++++++ data/i18n/pt_PT.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/ro_RO.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/ru_RU.yaml | 2360 ++++++++++++++++++++++++++++++++++++++++ data/i18n/sk_SK.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/sq_AL.yaml | 1371 +++++++++++++++++++++++ data/i18n/sr_SP.yaml | 1384 +++++++++++++++++++++++ data/i18n/sv_SE.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/te_IN.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/tr_TR.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/uk_UA.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/vi_VN.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/zh_CN.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ data/i18n/zh_TW.yaml | 2359 ++++++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 2 + 52 files changed, 86392 insertions(+) create mode 100644 .env.example create mode 100644 data/conf/config.yaml create mode 100644 data/i18n/af_ZA.yaml create mode 100644 data/i18n/ar_SA.yaml create mode 100644 data/i18n/az_AZ.yaml create mode 100644 data/i18n/bal_BA.yaml create mode 100644 data/i18n/ban_ID.yaml create mode 100644 data/i18n/bn_BD.yaml create mode 100644 data/i18n/bs_BA.yaml create mode 100644 data/i18n/ca_ES.yaml create mode 100644 data/i18n/cs_CZ.yaml create mode 100644 data/i18n/cy_GB.yaml create mode 100644 data/i18n/da_DK.yaml create mode 100644 data/i18n/de_DE.yaml create mode 100644 data/i18n/el_GR.yaml create mode 100644 data/i18n/en_US.yaml create mode 100644 data/i18n/es_ES.yaml create mode 100644 data/i18n/fa_IR.yaml create mode 100644 data/i18n/fi_FI.yaml create mode 100644 data/i18n/fr_FR.yaml create mode 100644 data/i18n/he_IL.yaml create mode 100644 data/i18n/hi_IN.yaml create mode 100644 data/i18n/hu_HU.yaml create mode 100644 data/i18n/hy_AM.yaml create mode 100644 data/i18n/i18n.yaml create mode 100644 data/i18n/id_ID.yaml create mode 100644 data/i18n/it_IT.yaml create mode 100644 data/i18n/ja_JP.yaml create mode 100644 data/i18n/ko_KR.yaml create mode 100644 data/i18n/ml_IN.yaml create mode 100644 data/i18n/nl_NL.yaml create mode 100644 data/i18n/no_NO.yaml create mode 100644 data/i18n/pl_PL.yaml create mode 100644 data/i18n/pt_BR.yaml create mode 100644 data/i18n/pt_PT.yaml create mode 100644 data/i18n/ro_RO.yaml create mode 100644 data/i18n/ru_RU.yaml create mode 100644 data/i18n/sk_SK.yaml create mode 100644 data/i18n/sq_AL.yaml create mode 100644 data/i18n/sr_SP.yaml create mode 100644 data/i18n/sv_SE.yaml create mode 100644 data/i18n/te_IN.yaml create mode 100644 data/i18n/tr_TR.yaml create mode 100644 data/i18n/uk_UA.yaml create mode 100644 data/i18n/vi_VN.yaml create mode 100644 data/i18n/zh_CN.yaml create mode 100644 data/i18n/zh_TW.yaml diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..b08736cdf --- /dev/null +++ b/.env.example @@ -0,0 +1,36 @@ +# Installation +INSTALL_PORT=80 +AUTO_INSTALL=false + +# Database +DB_TYPE= +DB_USERNAME= +DB_PASSWORD= +DB_HOST= +DB_NAME= +DB_FILE= + +# Site +LANGUAGE=en-US +SITE_NAME=Apache Answer +SITE_URL= +CONTACT_EMAIL= + +# Admin +ADMIN_NAME= +ADMIN_PASSWORD= +ADMIN_EMAIL= + +# Content +EXTERNAL_CONTENT_DISPLAY=ask_before_display + +# Swagger +SWAGGER_HOST= +SWAGGER_ADDRESS_PORT= + +# Server +SITE_ADDR=0.0.0.0:3000 + +# Logging +LOG_LEVEL=INFO +LOG_PATH= diff --git a/.gitignore b/.gitignore index 257ef31d6..ba66f51a0 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,6 @@ dist/ # Lint setup generated file .husky/ + +# Environment variables +.env \ No newline at end of file diff --git a/README.md b/README.md index 6e96c516a..ffa171694 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,15 @@ You can also check out the [plugins here](https://answer.apache.org/plugins). - [mockgen](https://github.com/uber-go/mock?tab=readme-ov-file#installation) >= 0.6.0 - [wire](https://github.com/google/wire/) >= 0.5.0 +### Environment Configuration + + You may create a `.env` file in the project root. + Copy `.env.example` and fill required values. + + ```bash + cp .env.example .env + + ### Build ```bash diff --git a/cmd/main.go b/cmd/main.go index f166d2309..1f8153001 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -31,12 +31,18 @@ import ( "github.com/apache/answer/internal/base/path" "github.com/apache/answer/internal/schema" "github.com/gin-gonic/gin" + "github.com/joho/godotenv" "github.com/segmentfault/pacman" "github.com/segmentfault/pacman/contrib/log/zap" "github.com/segmentfault/pacman/contrib/server/http" "github.com/segmentfault/pacman/log" ) +func init() { + // Load .env if present, ignore error to keep backward compatibility + _ = godotenv.Load() +} + // go build -ldflags "-X github.com/apache/answer/cmd.Version=x.y.z" var ( // Name is the name of the project diff --git a/data/conf/config.yaml b/data/conf/config.yaml new file mode 100644 index 000000000..6419bb538 --- /dev/null +++ b/data/conf/config.yaml @@ -0,0 +1,25 @@ +debug: false +server: + http: + addr: 0.0.0.0:80 +data: + database: + driver: sqlite3 + connection: ./data/answer.db + cache: + file_path: data/cache/cache.db +i18n: + bundle_dir: data/i18n +service_config: + upload_path: data/uploads + clean_up_uploads: true + clean_orphan_uploads_period_hours: 48 + purge_deleted_files_period_days: 30 +swaggerui: + show: true + protocol: http + host: 127.0.0.1 + address: :80 +ui: + base_url: "" + api_base_url: "" diff --git a/data/i18n/af_ZA.yaml b/data/i18n/af_ZA.yaml new file mode 100644 index 000000000..0121bde1a --- /dev/null +++ b/data/i18n/af_ZA.yaml @@ -0,0 +1,1384 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: Success. + unknown: + other: Unknown error. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + email: + other: Email + password: + other: Password + email_or_password_wrong_error: + other: Email and password do not match. + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + question: + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + rank: + fail_to_meet_the_condition: + other: Rank fail to meet the condition. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend Tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + smtp: + config_from_name_cannot_be_email: + other: The From Name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to Revision. + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + report: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude: + name: + other: rude or abusive + desc: + other: A reasonable person would find this content inappropriate for respectful discourse. + duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + not_answer: + name: + other: not an answer + desc: + other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. + not_need: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + other: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comments + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to {{site_name}} + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to {{site_name}} + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as <link> + head: + label: Head + text: This will insert before </head> + header: + label: Header + text: This will insert after <body> + footer: + label: Footer + text: This will insert before </body>. + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/ar_SA.yaml b/data/i18n/ar_SA.yaml new file mode 100644 index 000000000..25c086f11 --- /dev/null +++ b/data/i18n/ar_SA.yaml @@ -0,0 +1,1384 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: Success. + unknown: + other: Unknown error. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + email: + other: Email + password: + other: Password + email_or_password_wrong_error: + other: Email and password do not match. + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + question: + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + rank: + fail_to_meet_the_condition: + other: Rank fail to meet the condition. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend Tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + smtp: + config_from_name_cannot_be_email: + other: The From Name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to Revision. + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + report: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude: + name: + other: rude or abusive + desc: + other: A reasonable person would find this content inappropriate for respectful discourse. + duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + not_answer: + name: + other: not an answer + desc: + other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. + not_need: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + other: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comments + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to {{site_name}} + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to {{site_name}} + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/az_AZ.yaml b/data/i18n/az_AZ.yaml new file mode 100644 index 000000000..4249c5f03 --- /dev/null +++ b/data/i18n/az_AZ.yaml @@ -0,0 +1,1371 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: "Success." + unknown: + other: "Unknown error." + request_format_error: + other: "Request format is not valid." + unauthorized_error: + other: "Unauthorized." + database_error: + other: "Data server error." + role: + name: + user: + other: "User" + admin: + other: "Admin" + moderator: + other: "Moderator" + description: + user: + other: "Default with no special access." + admin: + other: "Have the full power to access the site." + moderator: + other: "Has access to all posts except admin settings." + email: + other: "Email" + password: + other: "Password" + email_or_password_wrong_error: + other: "Email and password do not match." + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: "Answer do not found." + cannot_deleted: + other: "No permission to delete." + cannot_update: + other: "No permission to update." + comment: + edit_without_permission: + other: "Comment are not allowed to edit." + not_found: + other: "Comment not found." + email: + duplicate: + other: "Email already exists." + need_to_be_verified: + other: "Email should be verified." + verify_url_expired: + other: "Email verified URL has expired, please resend the email." + lang: + not_found: + other: "Language file not found." + object: + captcha_verification_failed: + other: "Captcha wrong." + disallow_follow: + other: "You are not allowed to follow." + disallow_vote: + other: "You are not allowed to vote." + disallow_vote_your_self: + other: "You can't vote for your own post." + not_found: + other: "Object not found." + verification_failed: + other: "Verification failed." + email_or_password_incorrect: + other: "Email and password do not match." + old_password_verification_failed: + other: "The old password verification failed" + new_password_same_as_previous_setting: + other: "The new password is the same as the previous one." + question: + not_found: + other: "Question not found." + cannot_deleted: + other: "No permission to delete." + cannot_close: + other: "No permission to close." + cannot_update: + other: "No permission to update." + rank: + fail_to_meet_the_condition: + other: "Rank fail to meet the condition." + report: + handle_failed: + other: "Report handle failed." + not_found: + other: "Report not found." + tag: + not_found: + other: "Tag not found." + recommend_tag_not_found: + other: "Recommend Tag is not exist." + recommend_tag_enter: + other: "Please enter at least one required tag." + not_contain_synonym_tags: + other: "Should not contain synonym tags." + cannot_update: + other: "No permission to update." + cannot_set_synonym_as_itself: + other: "You cannot set the synonym of the current tag as itself." + smtp: + config_from_name_cannot_be_email: + other: "The From Name cannot be a email address." + theme: + not_found: + other: "Theme not found." + revision: + review_underway: + other: "Can't edit currently, there is a version in the review queue." + no_permission: + other: "No permission to Revision." + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: "User not found." + suspended: + other: "User has been suspended." + username_invalid: + other: "Username is invalid." + username_duplicate: + other: "Username is already in use." + set_avatar: + other: "Avatar set failed." + cannot_update_your_role: + other: "You cannot modify your role." + not_allowed_registration: + other: "Currently the site is not open for registration" + config: + read_config_failed: + other: "Read config failed" + database: + connection_failed: + other: "Database connection failed" + create_table_failed: + other: "Create table failed" + install: + create_config_failed: + other: "Can't create the config.yaml file." + report: + spam: + name: + other: "spam" + desc: + other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." + rude: + name: + other: "rude or abusive" + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + duplicate: + name: + other: "a duplicate" + desc: + other: "This question has been asked before and already has an answer." + not_answer: + name: + other: "not an answer" + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." + not_need: + name: + other: "no longer needed" + desc: + other: "This comment is outdated, conversational or not relevant to this post." + other: + name: + other: "something else" + desc: + other: "This post requires staff attention for another reason not listed above." + question: + close: + duplicate: + name: + other: "spam" + desc: + other: "This question has been asked before and already has an answer." + guideline: + name: + other: "a community-specific reason" + desc: + other: "This question doesn't meet a community guideline." + multiple: + name: + other: "needs details or clarity" + desc: + other: "This question currently includes multiple questions in one. It should focus on one problem only." + other: + name: + other: "something else" + desc: + other: "This post requires another reason not listed above." + operation_type: + asked: + other: "asked" + answered: + other: "answered" + modified: + other: "modified" + notification: + action: + update_question: + other: "updated question" + answer_the_question: + other: "answered question" + update_answer: + other: "updated answer" + accept_answer: + other: "accepted answer" + comment_question: + other: "commented question" + comment_answer: + other: "commented answer" + reply_to_you: + other: "replied to you" + mention_you: + other: "mentioned you" + your_question_is_closed: + other: "Your question has been closed" + your_question_was_deleted: + other: "Your question has been deleted" + your_answer_was_deleted: + other: "Your answer has been deleted" + your_comment_was_deleted: + other: "Your comment has been deleted" +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comment + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to Answer + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name up to 30 characters + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username up to 30 characters + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to Answer + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: "After you've done that, click “Next” button." + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: display_name must be at 2 - 30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/bal_BA.yaml b/data/i18n/bal_BA.yaml new file mode 100644 index 000000000..4249c5f03 --- /dev/null +++ b/data/i18n/bal_BA.yaml @@ -0,0 +1,1371 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: "Success." + unknown: + other: "Unknown error." + request_format_error: + other: "Request format is not valid." + unauthorized_error: + other: "Unauthorized." + database_error: + other: "Data server error." + role: + name: + user: + other: "User" + admin: + other: "Admin" + moderator: + other: "Moderator" + description: + user: + other: "Default with no special access." + admin: + other: "Have the full power to access the site." + moderator: + other: "Has access to all posts except admin settings." + email: + other: "Email" + password: + other: "Password" + email_or_password_wrong_error: + other: "Email and password do not match." + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: "Answer do not found." + cannot_deleted: + other: "No permission to delete." + cannot_update: + other: "No permission to update." + comment: + edit_without_permission: + other: "Comment are not allowed to edit." + not_found: + other: "Comment not found." + email: + duplicate: + other: "Email already exists." + need_to_be_verified: + other: "Email should be verified." + verify_url_expired: + other: "Email verified URL has expired, please resend the email." + lang: + not_found: + other: "Language file not found." + object: + captcha_verification_failed: + other: "Captcha wrong." + disallow_follow: + other: "You are not allowed to follow." + disallow_vote: + other: "You are not allowed to vote." + disallow_vote_your_self: + other: "You can't vote for your own post." + not_found: + other: "Object not found." + verification_failed: + other: "Verification failed." + email_or_password_incorrect: + other: "Email and password do not match." + old_password_verification_failed: + other: "The old password verification failed" + new_password_same_as_previous_setting: + other: "The new password is the same as the previous one." + question: + not_found: + other: "Question not found." + cannot_deleted: + other: "No permission to delete." + cannot_close: + other: "No permission to close." + cannot_update: + other: "No permission to update." + rank: + fail_to_meet_the_condition: + other: "Rank fail to meet the condition." + report: + handle_failed: + other: "Report handle failed." + not_found: + other: "Report not found." + tag: + not_found: + other: "Tag not found." + recommend_tag_not_found: + other: "Recommend Tag is not exist." + recommend_tag_enter: + other: "Please enter at least one required tag." + not_contain_synonym_tags: + other: "Should not contain synonym tags." + cannot_update: + other: "No permission to update." + cannot_set_synonym_as_itself: + other: "You cannot set the synonym of the current tag as itself." + smtp: + config_from_name_cannot_be_email: + other: "The From Name cannot be a email address." + theme: + not_found: + other: "Theme not found." + revision: + review_underway: + other: "Can't edit currently, there is a version in the review queue." + no_permission: + other: "No permission to Revision." + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: "User not found." + suspended: + other: "User has been suspended." + username_invalid: + other: "Username is invalid." + username_duplicate: + other: "Username is already in use." + set_avatar: + other: "Avatar set failed." + cannot_update_your_role: + other: "You cannot modify your role." + not_allowed_registration: + other: "Currently the site is not open for registration" + config: + read_config_failed: + other: "Read config failed" + database: + connection_failed: + other: "Database connection failed" + create_table_failed: + other: "Create table failed" + install: + create_config_failed: + other: "Can't create the config.yaml file." + report: + spam: + name: + other: "spam" + desc: + other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." + rude: + name: + other: "rude or abusive" + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + duplicate: + name: + other: "a duplicate" + desc: + other: "This question has been asked before and already has an answer." + not_answer: + name: + other: "not an answer" + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." + not_need: + name: + other: "no longer needed" + desc: + other: "This comment is outdated, conversational or not relevant to this post." + other: + name: + other: "something else" + desc: + other: "This post requires staff attention for another reason not listed above." + question: + close: + duplicate: + name: + other: "spam" + desc: + other: "This question has been asked before and already has an answer." + guideline: + name: + other: "a community-specific reason" + desc: + other: "This question doesn't meet a community guideline." + multiple: + name: + other: "needs details or clarity" + desc: + other: "This question currently includes multiple questions in one. It should focus on one problem only." + other: + name: + other: "something else" + desc: + other: "This post requires another reason not listed above." + operation_type: + asked: + other: "asked" + answered: + other: "answered" + modified: + other: "modified" + notification: + action: + update_question: + other: "updated question" + answer_the_question: + other: "answered question" + update_answer: + other: "updated answer" + accept_answer: + other: "accepted answer" + comment_question: + other: "commented question" + comment_answer: + other: "commented answer" + reply_to_you: + other: "replied to you" + mention_you: + other: "mentioned you" + your_question_is_closed: + other: "Your question has been closed" + your_question_was_deleted: + other: "Your question has been deleted" + your_answer_was_deleted: + other: "Your answer has been deleted" + your_comment_was_deleted: + other: "Your comment has been deleted" +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comment + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to Answer + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name up to 30 characters + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username up to 30 characters + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to Answer + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: "After you've done that, click “Next” button." + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: display_name must be at 2 - 30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/ban_ID.yaml b/data/i18n/ban_ID.yaml new file mode 100644 index 000000000..4249c5f03 --- /dev/null +++ b/data/i18n/ban_ID.yaml @@ -0,0 +1,1371 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: "Success." + unknown: + other: "Unknown error." + request_format_error: + other: "Request format is not valid." + unauthorized_error: + other: "Unauthorized." + database_error: + other: "Data server error." + role: + name: + user: + other: "User" + admin: + other: "Admin" + moderator: + other: "Moderator" + description: + user: + other: "Default with no special access." + admin: + other: "Have the full power to access the site." + moderator: + other: "Has access to all posts except admin settings." + email: + other: "Email" + password: + other: "Password" + email_or_password_wrong_error: + other: "Email and password do not match." + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: "Answer do not found." + cannot_deleted: + other: "No permission to delete." + cannot_update: + other: "No permission to update." + comment: + edit_without_permission: + other: "Comment are not allowed to edit." + not_found: + other: "Comment not found." + email: + duplicate: + other: "Email already exists." + need_to_be_verified: + other: "Email should be verified." + verify_url_expired: + other: "Email verified URL has expired, please resend the email." + lang: + not_found: + other: "Language file not found." + object: + captcha_verification_failed: + other: "Captcha wrong." + disallow_follow: + other: "You are not allowed to follow." + disallow_vote: + other: "You are not allowed to vote." + disallow_vote_your_self: + other: "You can't vote for your own post." + not_found: + other: "Object not found." + verification_failed: + other: "Verification failed." + email_or_password_incorrect: + other: "Email and password do not match." + old_password_verification_failed: + other: "The old password verification failed" + new_password_same_as_previous_setting: + other: "The new password is the same as the previous one." + question: + not_found: + other: "Question not found." + cannot_deleted: + other: "No permission to delete." + cannot_close: + other: "No permission to close." + cannot_update: + other: "No permission to update." + rank: + fail_to_meet_the_condition: + other: "Rank fail to meet the condition." + report: + handle_failed: + other: "Report handle failed." + not_found: + other: "Report not found." + tag: + not_found: + other: "Tag not found." + recommend_tag_not_found: + other: "Recommend Tag is not exist." + recommend_tag_enter: + other: "Please enter at least one required tag." + not_contain_synonym_tags: + other: "Should not contain synonym tags." + cannot_update: + other: "No permission to update." + cannot_set_synonym_as_itself: + other: "You cannot set the synonym of the current tag as itself." + smtp: + config_from_name_cannot_be_email: + other: "The From Name cannot be a email address." + theme: + not_found: + other: "Theme not found." + revision: + review_underway: + other: "Can't edit currently, there is a version in the review queue." + no_permission: + other: "No permission to Revision." + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: "User not found." + suspended: + other: "User has been suspended." + username_invalid: + other: "Username is invalid." + username_duplicate: + other: "Username is already in use." + set_avatar: + other: "Avatar set failed." + cannot_update_your_role: + other: "You cannot modify your role." + not_allowed_registration: + other: "Currently the site is not open for registration" + config: + read_config_failed: + other: "Read config failed" + database: + connection_failed: + other: "Database connection failed" + create_table_failed: + other: "Create table failed" + install: + create_config_failed: + other: "Can't create the config.yaml file." + report: + spam: + name: + other: "spam" + desc: + other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." + rude: + name: + other: "rude or abusive" + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + duplicate: + name: + other: "a duplicate" + desc: + other: "This question has been asked before and already has an answer." + not_answer: + name: + other: "not an answer" + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." + not_need: + name: + other: "no longer needed" + desc: + other: "This comment is outdated, conversational or not relevant to this post." + other: + name: + other: "something else" + desc: + other: "This post requires staff attention for another reason not listed above." + question: + close: + duplicate: + name: + other: "spam" + desc: + other: "This question has been asked before and already has an answer." + guideline: + name: + other: "a community-specific reason" + desc: + other: "This question doesn't meet a community guideline." + multiple: + name: + other: "needs details or clarity" + desc: + other: "This question currently includes multiple questions in one. It should focus on one problem only." + other: + name: + other: "something else" + desc: + other: "This post requires another reason not listed above." + operation_type: + asked: + other: "asked" + answered: + other: "answered" + modified: + other: "modified" + notification: + action: + update_question: + other: "updated question" + answer_the_question: + other: "answered question" + update_answer: + other: "updated answer" + accept_answer: + other: "accepted answer" + comment_question: + other: "commented question" + comment_answer: + other: "commented answer" + reply_to_you: + other: "replied to you" + mention_you: + other: "mentioned you" + your_question_is_closed: + other: "Your question has been closed" + your_question_was_deleted: + other: "Your question has been deleted" + your_answer_was_deleted: + other: "Your answer has been deleted" + your_comment_was_deleted: + other: "Your comment has been deleted" +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comment + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to Answer + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name up to 30 characters + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username up to 30 characters + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to Answer + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: "After you've done that, click “Next” button." + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: display_name must be at 2 - 30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/bn_BD.yaml b/data/i18n/bn_BD.yaml new file mode 100644 index 000000000..4249c5f03 --- /dev/null +++ b/data/i18n/bn_BD.yaml @@ -0,0 +1,1371 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: "Success." + unknown: + other: "Unknown error." + request_format_error: + other: "Request format is not valid." + unauthorized_error: + other: "Unauthorized." + database_error: + other: "Data server error." + role: + name: + user: + other: "User" + admin: + other: "Admin" + moderator: + other: "Moderator" + description: + user: + other: "Default with no special access." + admin: + other: "Have the full power to access the site." + moderator: + other: "Has access to all posts except admin settings." + email: + other: "Email" + password: + other: "Password" + email_or_password_wrong_error: + other: "Email and password do not match." + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: "Answer do not found." + cannot_deleted: + other: "No permission to delete." + cannot_update: + other: "No permission to update." + comment: + edit_without_permission: + other: "Comment are not allowed to edit." + not_found: + other: "Comment not found." + email: + duplicate: + other: "Email already exists." + need_to_be_verified: + other: "Email should be verified." + verify_url_expired: + other: "Email verified URL has expired, please resend the email." + lang: + not_found: + other: "Language file not found." + object: + captcha_verification_failed: + other: "Captcha wrong." + disallow_follow: + other: "You are not allowed to follow." + disallow_vote: + other: "You are not allowed to vote." + disallow_vote_your_self: + other: "You can't vote for your own post." + not_found: + other: "Object not found." + verification_failed: + other: "Verification failed." + email_or_password_incorrect: + other: "Email and password do not match." + old_password_verification_failed: + other: "The old password verification failed" + new_password_same_as_previous_setting: + other: "The new password is the same as the previous one." + question: + not_found: + other: "Question not found." + cannot_deleted: + other: "No permission to delete." + cannot_close: + other: "No permission to close." + cannot_update: + other: "No permission to update." + rank: + fail_to_meet_the_condition: + other: "Rank fail to meet the condition." + report: + handle_failed: + other: "Report handle failed." + not_found: + other: "Report not found." + tag: + not_found: + other: "Tag not found." + recommend_tag_not_found: + other: "Recommend Tag is not exist." + recommend_tag_enter: + other: "Please enter at least one required tag." + not_contain_synonym_tags: + other: "Should not contain synonym tags." + cannot_update: + other: "No permission to update." + cannot_set_synonym_as_itself: + other: "You cannot set the synonym of the current tag as itself." + smtp: + config_from_name_cannot_be_email: + other: "The From Name cannot be a email address." + theme: + not_found: + other: "Theme not found." + revision: + review_underway: + other: "Can't edit currently, there is a version in the review queue." + no_permission: + other: "No permission to Revision." + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: "User not found." + suspended: + other: "User has been suspended." + username_invalid: + other: "Username is invalid." + username_duplicate: + other: "Username is already in use." + set_avatar: + other: "Avatar set failed." + cannot_update_your_role: + other: "You cannot modify your role." + not_allowed_registration: + other: "Currently the site is not open for registration" + config: + read_config_failed: + other: "Read config failed" + database: + connection_failed: + other: "Database connection failed" + create_table_failed: + other: "Create table failed" + install: + create_config_failed: + other: "Can't create the config.yaml file." + report: + spam: + name: + other: "spam" + desc: + other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." + rude: + name: + other: "rude or abusive" + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + duplicate: + name: + other: "a duplicate" + desc: + other: "This question has been asked before and already has an answer." + not_answer: + name: + other: "not an answer" + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." + not_need: + name: + other: "no longer needed" + desc: + other: "This comment is outdated, conversational or not relevant to this post." + other: + name: + other: "something else" + desc: + other: "This post requires staff attention for another reason not listed above." + question: + close: + duplicate: + name: + other: "spam" + desc: + other: "This question has been asked before and already has an answer." + guideline: + name: + other: "a community-specific reason" + desc: + other: "This question doesn't meet a community guideline." + multiple: + name: + other: "needs details or clarity" + desc: + other: "This question currently includes multiple questions in one. It should focus on one problem only." + other: + name: + other: "something else" + desc: + other: "This post requires another reason not listed above." + operation_type: + asked: + other: "asked" + answered: + other: "answered" + modified: + other: "modified" + notification: + action: + update_question: + other: "updated question" + answer_the_question: + other: "answered question" + update_answer: + other: "updated answer" + accept_answer: + other: "accepted answer" + comment_question: + other: "commented question" + comment_answer: + other: "commented answer" + reply_to_you: + other: "replied to you" + mention_you: + other: "mentioned you" + your_question_is_closed: + other: "Your question has been closed" + your_question_was_deleted: + other: "Your question has been deleted" + your_answer_was_deleted: + other: "Your answer has been deleted" + your_comment_was_deleted: + other: "Your comment has been deleted" +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comment + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to Answer + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name up to 30 characters + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username up to 30 characters + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to Answer + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: "After you've done that, click “Next” button." + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: display_name must be at 2 - 30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/bs_BA.yaml b/data/i18n/bs_BA.yaml new file mode 100644 index 000000000..4249c5f03 --- /dev/null +++ b/data/i18n/bs_BA.yaml @@ -0,0 +1,1371 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: "Success." + unknown: + other: "Unknown error." + request_format_error: + other: "Request format is not valid." + unauthorized_error: + other: "Unauthorized." + database_error: + other: "Data server error." + role: + name: + user: + other: "User" + admin: + other: "Admin" + moderator: + other: "Moderator" + description: + user: + other: "Default with no special access." + admin: + other: "Have the full power to access the site." + moderator: + other: "Has access to all posts except admin settings." + email: + other: "Email" + password: + other: "Password" + email_or_password_wrong_error: + other: "Email and password do not match." + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: "Answer do not found." + cannot_deleted: + other: "No permission to delete." + cannot_update: + other: "No permission to update." + comment: + edit_without_permission: + other: "Comment are not allowed to edit." + not_found: + other: "Comment not found." + email: + duplicate: + other: "Email already exists." + need_to_be_verified: + other: "Email should be verified." + verify_url_expired: + other: "Email verified URL has expired, please resend the email." + lang: + not_found: + other: "Language file not found." + object: + captcha_verification_failed: + other: "Captcha wrong." + disallow_follow: + other: "You are not allowed to follow." + disallow_vote: + other: "You are not allowed to vote." + disallow_vote_your_self: + other: "You can't vote for your own post." + not_found: + other: "Object not found." + verification_failed: + other: "Verification failed." + email_or_password_incorrect: + other: "Email and password do not match." + old_password_verification_failed: + other: "The old password verification failed" + new_password_same_as_previous_setting: + other: "The new password is the same as the previous one." + question: + not_found: + other: "Question not found." + cannot_deleted: + other: "No permission to delete." + cannot_close: + other: "No permission to close." + cannot_update: + other: "No permission to update." + rank: + fail_to_meet_the_condition: + other: "Rank fail to meet the condition." + report: + handle_failed: + other: "Report handle failed." + not_found: + other: "Report not found." + tag: + not_found: + other: "Tag not found." + recommend_tag_not_found: + other: "Recommend Tag is not exist." + recommend_tag_enter: + other: "Please enter at least one required tag." + not_contain_synonym_tags: + other: "Should not contain synonym tags." + cannot_update: + other: "No permission to update." + cannot_set_synonym_as_itself: + other: "You cannot set the synonym of the current tag as itself." + smtp: + config_from_name_cannot_be_email: + other: "The From Name cannot be a email address." + theme: + not_found: + other: "Theme not found." + revision: + review_underway: + other: "Can't edit currently, there is a version in the review queue." + no_permission: + other: "No permission to Revision." + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: "User not found." + suspended: + other: "User has been suspended." + username_invalid: + other: "Username is invalid." + username_duplicate: + other: "Username is already in use." + set_avatar: + other: "Avatar set failed." + cannot_update_your_role: + other: "You cannot modify your role." + not_allowed_registration: + other: "Currently the site is not open for registration" + config: + read_config_failed: + other: "Read config failed" + database: + connection_failed: + other: "Database connection failed" + create_table_failed: + other: "Create table failed" + install: + create_config_failed: + other: "Can't create the config.yaml file." + report: + spam: + name: + other: "spam" + desc: + other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." + rude: + name: + other: "rude or abusive" + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + duplicate: + name: + other: "a duplicate" + desc: + other: "This question has been asked before and already has an answer." + not_answer: + name: + other: "not an answer" + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." + not_need: + name: + other: "no longer needed" + desc: + other: "This comment is outdated, conversational or not relevant to this post." + other: + name: + other: "something else" + desc: + other: "This post requires staff attention for another reason not listed above." + question: + close: + duplicate: + name: + other: "spam" + desc: + other: "This question has been asked before and already has an answer." + guideline: + name: + other: "a community-specific reason" + desc: + other: "This question doesn't meet a community guideline." + multiple: + name: + other: "needs details or clarity" + desc: + other: "This question currently includes multiple questions in one. It should focus on one problem only." + other: + name: + other: "something else" + desc: + other: "This post requires another reason not listed above." + operation_type: + asked: + other: "asked" + answered: + other: "answered" + modified: + other: "modified" + notification: + action: + update_question: + other: "updated question" + answer_the_question: + other: "answered question" + update_answer: + other: "updated answer" + accept_answer: + other: "accepted answer" + comment_question: + other: "commented question" + comment_answer: + other: "commented answer" + reply_to_you: + other: "replied to you" + mention_you: + other: "mentioned you" + your_question_is_closed: + other: "Your question has been closed" + your_question_was_deleted: + other: "Your question has been deleted" + your_answer_was_deleted: + other: "Your answer has been deleted" + your_comment_was_deleted: + other: "Your comment has been deleted" +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comment + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to Answer + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name up to 30 characters + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username up to 30 characters + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to Answer + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: "After you've done that, click “Next” button." + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: display_name must be at 2 - 30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/ca_ES.yaml b/data/i18n/ca_ES.yaml new file mode 100644 index 000000000..25c086f11 --- /dev/null +++ b/data/i18n/ca_ES.yaml @@ -0,0 +1,1384 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: Success. + unknown: + other: Unknown error. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + email: + other: Email + password: + other: Password + email_or_password_wrong_error: + other: Email and password do not match. + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + question: + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + rank: + fail_to_meet_the_condition: + other: Rank fail to meet the condition. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend Tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + smtp: + config_from_name_cannot_be_email: + other: The From Name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to Revision. + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + report: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude: + name: + other: rude or abusive + desc: + other: A reasonable person would find this content inappropriate for respectful discourse. + duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + not_answer: + name: + other: not an answer + desc: + other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. + not_need: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + other: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comments + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to {{site_name}} + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to {{site_name}} + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/cs_CZ.yaml b/data/i18n/cs_CZ.yaml new file mode 100644 index 000000000..dbb217faf --- /dev/null +++ b/data/i18n/cs_CZ.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Úspěch. + unknown: + other: Neznámá chyba. + request_format_error: + other: Formát požadavku není platný. + unauthorized_error: + other: Neautorizováno. + database_error: + other: Chyba datového serveru. + forbidden_error: + other: Zakázáno. + duplicate_request_error: + other: Duplicitní odeslání. + action: + report: + other: Nahlásit + edit: + other: Upravit + delete: + other: Smazat + close: + other: Zavřít + reopen: + other: Znovu otevřít + forbidden_error: + other: Zakázáno. + pin: + other: Připnout + hide: + other: Skrýt + unpin: + other: Odepnout + show: + other: Zobrazit + invite_someone_to_answer: + other: Upravit + undelete: + other: Obnovit + merge: + other: Sloučit + role: + name: + user: + other: Uživatel + admin: + other: Administrátor + moderator: + other: Moderátor + description: + user: + other: Výchozí bez zvláštního přístupu. + admin: + other: Má plnou kontrolu nad stránkou. + moderator: + other: Má přístup ke všem příspěvkům kromě admin nastavení. + privilege: + level_1: + description: + other: Úroveň 1 (méně reputace je vyžadováno pro soukromý tým, skupinu) + level_2: + description: + other: Úroveň 2 (nízká reputace je vyžadována pro startovací komunitu) + level_3: + description: + other: Úroveň 3 (vysoká reputace je vyžadována pro vyspělou komunitu) + level_custom: + description: + other: Vlastní úroveň + rank_question_add_label: + other: Položit dotaz + rank_answer_add_label: + other: Napsat odpověď + rank_comment_add_label: + other: Napsat komentář + rank_report_add_label: + other: Nahlásit + rank_comment_vote_up_label: + other: Hlasovat pro komentář + rank_link_url_limit_label: + other: Zveřejnit více než 2 odkazy najednou + rank_question_vote_up_label: + other: Hlasovat pro dotaz + rank_answer_vote_up_label: + other: Hlasovat pro odpověď + rank_question_vote_down_label: + other: Hlasovat proti otázce + rank_answer_vote_down_label: + other: Hlasovat proti odpovědi + rank_invite_someone_to_answer_label: + other: Pozvěte někoho, aby odpověděl + rank_tag_add_label: + other: Vytvořit nový štítek + rank_tag_edit_label: + other: Upravit popis štítku (vyžaduje kontrolu) + rank_question_edit_label: + other: Upravit dotaz někoho jiného (vyžaduje kontrolu) + rank_answer_edit_label: + other: Upravit odpověď někoho jiného (vyžaduje kontrolu) + rank_question_edit_without_review_label: + other: Upravit dotaz někoho jiného (bez kontroly) + rank_answer_edit_without_review_label: + other: Upravit odpověď někoho jiného (bez kontroly) + rank_question_audit_label: + other: Zkontrolovat úpravy dotazu + rank_answer_audit_label: + other: Zkontrolovat úpravy odpovědí + rank_tag_audit_label: + other: Zkontrolovat úpravy štítků + rank_tag_edit_without_review_label: + other: Upravit popis štítku (bez kontroly) + rank_tag_synonym_label: + other: Správa synonym štítků + email: + other: Email + e_mail: + other: Email + password: + other: Heslo + pass: + other: Heslo + old_pass: + other: Current password + original_text: + other: Tento příspěvek + email_or_password_wrong_error: + other: Email a heslo nesouhlasí. + error: + common: + invalid_url: + other: Neplatná URL. + status_invalid: + other: Neplatný stav. + password: + space_invalid: + other: Heslo nesmí obsahovat mezery. + admin: + cannot_update_their_password: + other: Nemůžete změnit své heslo. + cannot_edit_their_profile: + other: Nemůžete upravovat svůj profil. + cannot_modify_self_status: + other: Nemůžete změnit svůj stav. + email_or_password_wrong: + other: Email a heslo nesouhlasí. + answer: + not_found: + other: Odpověď nebyla nalezena. + cannot_deleted: + other: Nemáte právo mazat. + cannot_update: + other: Nemáte právo aktualizovat. + question_closed_cannot_add: + other: Dotazy jsou uzavřené a není možno je přidávat. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Nejsou povoleny úpravy komentáře. + not_found: + other: Komentář nebyl nalezen. + cannot_edit_after_deadline: + other: Tento komentář byl pro úpravy příliš dlouhý. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: Email už existuje. + need_to_be_verified: + other: Email musí být ověřen. + verify_url_expired: + other: Platnost ověřovacího URL vypršela, pošlete si ověřovací email znovu. + illegal_email_domain_error: + other: Email z této domény není povolen. Použijte jinou doménu. + lang: + not_found: + other: Jazykový soubor nenalezen. + object: + captcha_verification_failed: + other: Nesprávně vyplněná Captcha. + disallow_follow: + other: Nemáte oprávnění sledovat. + disallow_vote: + other: Nemáte oprávnění hlasovat. + disallow_vote_your_self: + other: Nemůžete hlasovat pro svůj vlastní příspěvek. + not_found: + other: Objekt nenalezen. + verification_failed: + other: Ověření se nezdařilo. + email_or_password_incorrect: + other: Email a heslo nesouhlasí. + old_password_verification_failed: + other: Ověření starého hesla selhalo + new_password_same_as_previous_setting: + other: Nové heslo je stejné jako předchozí. + already_deleted: + other: Tento příspěvek byl odstraněn. + meta: + object_not_found: + other: Meta objekt nenalezen + question: + already_deleted: + other: Tento příspěvek byl odstraněn. + under_review: + other: Váš příspěvek čeká na kontrolu. Bude viditelný po jeho schválení. + not_found: + other: Dotaz nenalezen. + cannot_deleted: + other: Nemáte oprávnění k mazání. + cannot_close: + other: Nemáte oprávnění k uzavření. + cannot_update: + other: Nemáte oprávnění pro aktualizaci. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Hodnost reputace nesplňuje podmínku. + vote_fail_to_meet_the_condition: + other: Děkujeme za zpětnou vazbu. Potřebujete alespoň úroveň {{.Rank}}, abyste mohli hlasovat. + no_enough_rank_to_operate: + other: Potřebujete alespoň úroveň {{.Rank}} k provedení této akce. + report: + handle_failed: + other: Report selhal. + not_found: + other: Report nebyl nalezen. + tag: + already_exist: + other: Štítek již existuje. + not_found: + other: Štítek nebyl nalezen. + recommend_tag_not_found: + other: Doporučený štítek nebyl nalezen. + recommend_tag_enter: + other: Zadejte prosím alespoň jeden povinný štítek. + not_contain_synonym_tags: + other: Nemělo by obsahovat synonyma štítků. + cannot_update: + other: Nemáte oprávnění pro aktualizaci. + is_used_cannot_delete: + other: Nemůžete odstranit štítek, který se používá. + cannot_set_synonym_as_itself: + other: Aktuální štítek nelze jako synonymum stejného štítku. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: Jméno odesílatele nemůže být emailová adresa. + theme: + not_found: + other: Motiv nebyl nalezen. + revision: + review_underway: + other: V současné době nelze upravit, čeká na kontrolu. + no_permission: + other: Nemáte oprávnění k revizi. + user: + external_login_missing_user_id: + other: Platforma třetí strany neposkytuje unikátní UserID, takže se nemůžete přihlásit, kontaktujte prosím správce webových stránek. + external_login_unbinding_forbidden: + other: Před odebráním tohoto typu přihlášení nastavte přihlašovací heslo pro svůj účet. + email_or_password_wrong: + other: + other: Email a heslo nesouhlasí. + not_found: + other: Uživatel nebyl nalezen. + suspended: + other: Uživatelský účet byl pozastaven. + username_invalid: + other: Uživatelské jméno je neplatné. + username_duplicate: + other: Uživatelské jméno je již použito. + set_avatar: + other: Nastavení avataru se nezdařilo. + cannot_update_your_role: + other: Nemůžete upravovat svoji roli. + not_allowed_registration: + other: Registrace nejsou povolené. + not_allowed_login_via_password: + other: Přihlášení přes heslo není povolené. + access_denied: + other: Přístup zamítnut + page_access_denied: + other: Nemáte přístup k této stránce. + add_bulk_users_format_error: + other: "Chyba formátu pole {{.Field}} poblíž '{{.Content}}' na řádku {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "Počet uživatelů, které přidáte najednou, by měl být v rozsahu 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Načtení konfigurace selhalo + database: + connection_failed: + other: Spojení s databází selhalo + create_table_failed: + other: Vytvoření tabulky selhalo + install: + create_config_failed: + other: Soubor config.yaml nelze vytvořit. + upload: + unsupported_file_format: + other: Nepodporovaný formát souboru. + site_info: + config_not_found: + other: Konfigurace webu nebyla nalezena. + badge: + object_not_found: + other: Objekt odznaku nebyl nalezen + reason: + spam: + name: + other: spam + desc: + other: Tento příspěvek je reklama nebo vandalismus. Není užitečný ani relevantní pro aktuální téma. + rude_or_abusive: + name: + other: hrubý nebo zneužívající + desc: + other: "Rozumný člověk by tento obsah považoval za nevhodný pro slušnou konverzaci." + a_duplicate: + name: + other: duplicita + desc: + other: Tento dotaz byl položen dříve a již má odpověď. + placeholder: + other: Zadejte existující odkaz na dotaz + not_a_answer: + name: + other: není odpověď + desc: + other: "Toto bylo zveřejněno jako odpověď, ale nesnaží se odpovědět na dotaz. Měla by to být úprava, komentář, nebo úplně jiný dotaz." + no_longer_needed: + name: + other: již není potřeba + desc: + other: Tento komentář je zastaralý, konverzační nebo není relevantní pro tento příspěvek. + something: + name: + other: jiný důvod + desc: + other: Tento příspěvek vyžaduje pozornost moderátorů z jiného důvodu, který není uveden výše. + placeholder: + other: Dejte nám vědět konkrétně, v čem je problém + community_specific: + name: + other: důvod specifický pro komunitu + desc: + other: Tento dotaz nesplňuje pravidla komunity. + not_clarity: + name: + other: vyžaduje detaily nebo upřesnění + desc: + other: Tento dotaz v současné době obsahuje více otázek. Měl by se zaměřit pouze na jeden problém. + looks_ok: + name: + other: vypadá v pořádku + desc: + other: Tento příspěvek je dobrý tak jak je, nemá nízkou kvalitu. + needs_edit: + name: + other: potřebuje úpravu, kterou jsem udělal(a) + desc: + other: Zlepšete a opravte problémy s tímto příspěvkem. + needs_close: + name: + other: potřebuje zavřít + desc: + other: Na uzavřený dotaz není možné odpovídat, ale stále může být upraven a je možné pro něj hlasovat a komentovat jej. + needs_delete: + name: + other: potřebuje smazat + desc: + other: Tento příspěvek bude odstraněn. + question: + close: + duplicate: + name: + other: spam + desc: + other: Tento dotaz byl položena dříve a již má odpověď. + guideline: + name: + other: důvod specifický pro komunitu + desc: + other: Tento dotaz nesplňuje pravidla komunity. + multiple: + name: + other: vyžaduje detaily nebo upřesnění + desc: + other: Tento dotaz v současné době obsahuje více otázek. Měla by se zaměřit pouze na jeden problém. + other: + name: + other: jiný důvod + desc: + other: Tento příspěvek vyžaduje pozornost moderátorů z jiného důvodu, který není uveden výše. + operation_type: + asked: + other: dotázáno + answered: + other: zodpovězeno + modified: + other: upraveno + deleted_title: + other: Smazat dotaz + questions_title: + other: Dotazy + tag: + tags_title: + other: Štítky + no_description: + other: Štítek nemá žádný popis. + notification: + action: + update_question: + other: upravený dotaz + answer_the_question: + other: položil(a) dotaz + update_answer: + other: upravil(a) odpověď + accept_answer: + other: přijal(a) odpověď + comment_question: + other: okomentoval(a) dotaz + comment_answer: + other: okomentoval(a) odpověď + reply_to_you: + other: vám odpověděl(a) + mention_you: + other: vás zmínil(a) + your_question_is_closed: + other: Váš dotaz byl uzavřen + your_question_was_deleted: + other: Váš dotaz byl odstraněn + your_answer_was_deleted: + other: Vaše odpověď byla smazána + your_comment_was_deleted: + other: Váš komentář byl odstraněn + up_voted_question: + other: hlasoval(a) pro dotaz + down_voted_question: + other: hlasoval(a) proti dotazu + up_voted_answer: + other: hlasoval(a) pro odpověď + down_voted_answer: + other: hlasoval(a) proti odpovědi + up_voted_comment: + other: hlasoval(a) pro komentář + invited_you_to_answer: + other: vás pozval, abyste odpověděl(a) + earned_badge: + other: Získali jste odznak "{{.BadgeName}}" + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Potvrďte svůj nový email" + body: + other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} odpověděl(a) na váš dotaz" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_question: + title: + other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Obnova hesla" + body: + other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + register: + title: + other: "[{{.SiteName}}] Potvrďte svůj nový účet" + body: + other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + test: + title: + other: "[{{.SiteName}}] Zkušební email" + body: + other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + action_activity_type: + upvote: + other: hlasovat pro + upvoted: + other: hlasováno pro + downvote: + other: hlasovat proti + downvoted: + other: hlasováno proti + accept: + other: přijmout + accepted: + other: přijato + edit: + other: upravit + review: + queued_post: + other: Příspěvek ve frontě + flagged_post: + other: Nahlášený příspěvek + suggested_post_edit: + other: Navrhované úpravy + reaction: + tooltip: + other: "{{ .Names }} a {{ .Count }} dalších..." + badge: + default_badges: + autobiographer: + name: + other: Životopisec + desc: + other: Profil vyplněn. + certified: + name: + other: Certifikovaný + desc: + other: Tutoriál pro nové uživatele dokončen. + editor: + name: + other: Editor + desc: + other: První úprava příspěvku. + first_flag: + name: + other: První nahlášení + desc: + other: První nahlášení příspěvku. + first_upvote: + name: + other: První hlas pro + desc: + other: První hlas pro příspěvek. + first_link: + name: + other: První odkaz + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: První sdílení + desc: + other: První sdílení příspěvku. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Napište 5 komentářů. + new_user_of_the_month: + name: + other: Nový uživatel měsíce + desc: + other: Výjimečný přínos ve svém prvním měsíci na stránce. + read_guidelines: + name: + other: Přečíst pravidla + desc: + other: Přečtěte si [pravidla komunity]. + reader: + name: + other: Čtenář + desc: + other: Přečtěte si všechny odpovědi v tématu s více než 10 odpověďmi. + welcome: + name: + other: Vítejte + desc: + other: Obdržel(a) hlas. + nice_share: + name: + other: Povedené sdílení + desc: + other: Sdílel(a) příspěvek s 25 unikátními návštěvníky. + good_share: + name: + other: Dobré sdílení + desc: + other: Sdílel(a) příspěvek s 300 unikátními návštěvníky. + great_share: + name: + other: Skvělé sdílení + desc: + other: Sdílel(a) příspěvek s 1000 unikátními návštěvníky. + out_of_love: + name: + other: Optimista + desc: + other: Využito 50 hlasů pro za den. + higher_love: + name: + other: Vytrvalý optimista + desc: + other: 5 krát využito 50 hlasů pro za den. + crazy_in_love: + name: + other: Bláznivý optimista + desc: + other: 20 krát využito 50 hlasů pro za den. + promoter: + name: + other: Promotér + desc: + other: Pozval(a) uživatele. + campaigner: + name: + other: Campaigner + desc: + other: Pozval(a) 3 uživatele. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: Thank You + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Active member for a year, posted at least once. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + create_tag: Create Tag + edit_tag: Edit Tag + ask_a_question: Create Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + oauth_callback: Processing + http_404: HTTP Error 404 + http_50X: HTTP Error 500 + http_403: HTTP Error 403 + logout: Log Out + posts: Posts + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + new_alerts: New alerts + all_read: Mark all as read + show_more: Show more + someone: Someone + inbox_type: + all: All + posts: Posts + invites: Invites + votes: Votes + answer: Answer + question: Question + badge_award: Badge + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + contact_us: Contact us + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image file + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed {{size}} MB. + desc: + label: Description + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered list + unordered_list: + text: Bulleted list + table: + text: Table + heading: Heading + cell: Cell + file: + text: Attach files + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + not_a_url: URL format is incorrect. + url_not_match: URL origin does not match the current website. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description + revision: + label: Revision + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_cancel: Cancel + btn_submit: Submit + btn_post: Post new tag + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + tip_with_posts: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + tip_with_synonyms: >- +

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        + tip: Are you sure you wish to delete? + close: Close + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + default_first_reason: Add tag + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + hours: hours + days: days + month: month + months: months + year: year + reaction: + heart: heart + smile: smile + frown: frown + btn_label: add or remove reactions + undo_emoji: undo {{ emoji }} reaction + react_emoji: react with {{ emoji }} + unreact_emoji: unreact with {{ emoji }} + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: "{{count}} more comments" + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + tip_vote: It adds something useful to the post + edit_answer: + title: Edit Answer + default_reason: Edit answer + default_first_reason: Add answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: Newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + wiki: Wiki + ask: + title: Create Question + edit_title: Edit Question + default_reason: Edit question + default_first_reason: Create question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: What's your topic? Be specific. + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + badges: Badges + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + bookmark: Bookmarks + moderation: Moderation + search: + placeholder: Search + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + resend_email: + url_label: Are you sure you want to resend the activation email? + url_text: You can also give the activation link above to the user. + login: + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New email + msg: + empty: Email cannot be empty. + oauth: + connect: Connect with {{ auth_name }} + remove: Remove {{ auth_name }} + oauth_bind_email: + subtitle: Add a recovery email to your account. + btn_update: Update email address + email: + label: Email + msg: + empty: Email cannot be empty. + modal_title: Email already existes. + modal_content: This email address already registered. Are you sure you want to connect to the existing account? + modal_cancel: Change email + modal_confirm: Connect to the existing account + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm new password + settings: + page_title: Settings + goto_modify: Go to modify + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile image + gravatar: Gravatar + gravatar_text: You can change image on + custom: Custom + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About me + website: + label: Website + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location + placeholder: "City, Country" + notification: + heading: Email Notifications + turn_on: Turn on + inbox: + label: Inbox notifications + description: Answers to your questions, comments, invites, and more. + all_new_question: + label: All new questions + description: Get notified of all new questions. Up to 50 questions per week. + all_new_question_for_following_tags: + label: All new questions for following tags + description: Get notified of new questions for following tags. + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + pass: + label: Current password + msg: Password cannot be empty. + password_title: Password + current_pass: + label: Current password + msg: + empty: Current password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New password + pass_confirm: + label: Confirm new password + interface: + heading: Interface + lang: + label: Interface language + text: User interface language. It will change when you refresh the page. + my_logins: + title: My logins + label: Log in or sign up on this site using these accounts. + modal_title: Remove login + modal_content: Are you sure you want to remove this login from your account? + modal_confirm_btn: Remove + remove_success: Removed successfully + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + sent_success: Sent successfully + related_question: + title: Related + answers: answers + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Pozvěte další uživatele + desc: Pozvěte lidi, o kterých si myslíte, že mohou odpovědět. + invite: Invite to answer + add: Add people + search: Search people + question_detail: + action: Action + created: Created + Asked: Asked + asked: asked + update: Modified + Edited: Edited + edit: edited + commented: commented + Views: Viewed + Follow: Follow + Following: Following + follow_tip: Follow this question to receive notifications + answered: answered + closed_in: Closed in + show_exist: Show existing question. + useful: Useful + question_useful: It is useful and clear + question_un_useful: It is unclear or not useful + question_bookmark: Bookmark this question + answer_useful: It is useful + answer_un_useful: It is not useful + answers: + title: Answers + score: Score + newest: Newest + oldest: Oldest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + edit_answer: Edit my existing answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + tips: + header_1: Thanks for your answer + li1_1: Please be sure to answer the question. Provide details and share your research. + li1_2: Back up any statements you make with references or personal experience. + header_2: But avoid ... + li2_1: Asking for help, seeking clarification, or responding to other answers. + reopen: + confirm_btn: Reopen + title: Reopen this post + content: Are you sure you want to reopen? + list: + confirm_btn: List + title: List this post + content: Are you sure you want to list? + unlist: + confirm_btn: Unlist + title: Unlist this post + content: Are you sure you want to unlist? + pin: + title: Pin this post + content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. + confirm_btn: Pin + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_answer_deleted: This answer has been deleted + undelete_title: Undelete this post + undelete_desc: Are you sure you wish to undelete? + btns: + confirm: Confirm + cancel: Cancel + edit: Edit + save: Save + delete: Delete + undelete: Undelete + list: List + unlist: Unlist + unlisted: Unlisted + login: Log in + signup: Sign up + logout: Log out + verify: Verify + create: Create + approve: Approve + reject: Reject + skip: Skip + discard_draft: Discard draft + pinned: Pinned + all: All + question: Question + answer: Answer + comment: Comment + refresh: Refresh + resend: Resend + deactivate: Deactivate + active: Active + suspend: Suspend + unsuspend: Unsuspend + close: Close + reopen: Reopen + ok: OK + light: Light + dark: Dark + system_setting: System setting + default: Default + reset: Reset + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignore + submit: Submit + normal: Normal + closed: Closed + deleted: Deleted + deleted_permanently: Deleted permanently + pending: Pending + more: More + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + counts_loading: "... Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post. + modal_confirm: + title: Error... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + x_posts: "{{ count }} Posts" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + frequent: Frequent + recommend: Recommend + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + badges: Badges + newest: Newest + score: Score + edit_profile: Edit profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + comma: "," + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + content_empty: No posts found. + accepted: Accepted + answered: answered + asked: asked + downvoted: downvoted + mod_short: MOD + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + recent_badges: Recent Badges + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please choose a language + db_type: + label: Database engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database host + placeholder: "db:3306" + msg: Database host cannot be empty. + db_name: + label: Database name + placeholder: answer + msg: Database name cannot be empty. + db_file: + label: Database file + placeholder: /data/answer.db + msg: Database file cannot be empty. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site name + msg: Site name cannot be empty. + msg_max_length: Site name must be at maximum 30 characters in length. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + max_length: Site URL must be at maximum 512 characters in length. + contact_email: + label: Contact email + text: Email address of key contact responsible for this site. + msg: + empty: Contact email cannot be empty. + incorrect: Contact email incorrect format. + login_required: + label: Private + switch: Login required + text: Only logged in users can access this community. + admin_name: + label: Name + msg: Name cannot be empty. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + msg_min_length: Password must be at least 8 characters in length. + msg_max_length: Password must be at maximum 32 characters in length. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_error: + http_error: HTTP Error {{ code }} + desc_403: You don't have permission to access this page. + desc_404: Unfortunately, this page doesn't exist. + desc_50X: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + badges: Badges + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + terms: Terms + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + login: Login + privileges: Privileges + plugins: Plugins + installed_plugins: Installed Plugins + apperance: Appearance + website_welcome: Welcome to {{site_name}} + user_center: + login: Login + qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. + login_failed_email_tip: Login failed, please allow this app to access your email information before try again. + badges: + modal: + title: Congratulations + content: You've earned a new badge. + close: Close + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site statistics + questions: "Questions:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + users: "Users:" + flags: "Flags:" + reviews: "Reviews:" + site_health: Site health + version: "Version:" + https: "HTTPS:" + upload_folder: "Upload folder:" + run_mode: "Running mode:" + private: Private + public: Public + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System info + go_version: "Go version:" + database: "Database:" + database_size: "Database size:" + storage_used: "Storage used:" + uptime: "Uptime:" + links: Links + plugins: Plugins + github: GitHub + blog: Blog + contact: Contact + forum: Forum + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + writable: Writable + not_writable: Not writable + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + flagged_type: Flagged {{ type }} + created: Created + action: Action + review: Review + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + edit_profile_modal: + title: Edit profile + form: + fields: + display_name: + label: Display name + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Invalid Email Address. + edit_success: Edited successfully + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + users: + label: Bulk add user + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separate “name, email, password” with commas. One user per line. + msg: "Please enter the user's email, one per line." + display_name: + label: Display name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + more: More + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + edit_profile: Edit profile + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + deactivate_user: + title: Deactivate user + content: An inactive user must re-validate their email. + delete_user: + title: Delete this user + content: Are you sure you want to delete this user? This is permanent! + remove: Remove their content + label: Remove all questions, answers, comments, etc. + text: Don’t check this if you wish to only delete the user’s account. + suspend_user: + title: Suspend this user + content: A suspended user can't log in. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Questions + unlisted: Unlisted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + pending: Pending + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short site description + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site description + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + check_update: + label: Software updates + text: Automatically check for updates + interface: + page_title: Interface + language: + label: Interface language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: From email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + tls: TLS + none: None + smtp_port: + label: SMTP port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test email recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile logo + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square icon + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Write + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Každý uživatel může napsat pouze jednu odpověď na stejný dotaz + text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Recommend tags + text: "Recommend tags will show in the dropdown list by default." + msg: + contain_reserved: "recommended tags cannot contain reserved tags" + required_tag: + title: Set required tags + label: Set “Recommend tags” as required tags + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved tags + text: "Reserved tags can only be used by moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + color_scheme: + label: Color scheme + navbar_style: + label: Navbar background style + primary_color: + label: Primary color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: > + + head: + label: Head + text: > + + header: + label: Header + text: > + + footer: + label: Footer + text: This will insert before </body>. + sidebar: + label: Sidebar + text: This will insert in sidebar. + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + email_registration: + title: Email registration + label: Allow email registration + text: Turn off to prevent anyone creating new account through email. + allowed_email_domains: + title: Allowed email domains + text: Email domains that users must register accounts with. One domain per line. Ignored when empty. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + password_login: + title: Password login + label: Allow email and password login + text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." + installed_plugins: + title: Installed Plugins + plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + filter: + all: All + active: Active + inactive: Inactive + outdated: Outdated + plugins: + label: Plugins + text: Select an existing plugin. + name: Name + version: Version + status: Status + action: Action + deactivate: Deactivate + activate: Activate + settings: Settings + settings_users: + title: Users + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: URL základny Gravatar + text: URL of the Gravatar provider's API base. Ignored when empty. + profile_editable: + title: Profile editable + allow_update_display_name: + label: Allow users to change their display name + allow_update_username: + label: Allow users to change their username + allow_update_avatar: + label: Allow users to change their profile image + allow_update_bio: + label: Allow users to change their about me + allow_update_website: + label: Allow users to change their website + allow_update_location: + label: Allow users to change their location + privilege: + title: Privileges + level: + label: Reputation required level + text: Choose the reputation required for the privileges + msg: + should_be_number: the input should be number + number_larger_1: number should be equal or larger than 1 + badges: + action: Action + active: Active + activate: Activate + all: All + awards: Awards + deactivate: Deactivate + filter: + placeholder: Filter by name, badge:id + group: Group + inactive: Inactive + name: Name + show_logs: Show logs + status: Status + title: Badges + form: + optional: (optional) + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + select: Select + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + approve_revision_tip: Do you approve this revision? + approve_flag_tip: Do you approve this flag? + approve_post_tip: Do you approve this post? + approve_user_tip: Do you approve this user? + suggest_edits: Suggested edits + flag_post: Flag post + flag_user: Flag user + queued_post: Queued post + queued_user: Queued user + filter_label: Type + reputation: reputation + flag_post_type: Flagged this post as {{ type }}. + flag_user_type: Flagged this user as {{ type }}. + edit_post: Edit post + list_post: List post + unlist_post: Unlist post + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + pin: pinned + unpin: unpinned + show: listed + hide: unlisted + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores this week + users_with_the_most_vote: Users who voted the most this week + staffs: Our community staff + reputation: reputation + votes: votes + prompt: + leave_page: Are you sure you want to leave the page? + changes_not_save: Your changes may not be saved. + draft: + discard_confirm: Are you sure you want to discard your draft? + messages: + post_deleted: This post has been deleted. + post_cancel_deleted: This post has been undeleted. + post_pin: This post has been pinned. + post_unpin: This post has been unpinned. + post_hide_list: This post has been hidden from list. + post_show_list: This post has been shown to list. + post_reopen: This post has been reopened. + post_list: This post has been listed. + post_unlist: This post has been unlisted. + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/cy_GB.yaml b/data/i18n/cy_GB.yaml new file mode 100644 index 000000000..6f27a61f5 --- /dev/null +++ b/data/i18n/cy_GB.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Llwyddiant. + unknown: + other: Gwall anhysbys. + request_format_error: + other: Nid yw fformat y cais yn ddilys. + unauthorized_error: + other: Anawdurdodedig. + database_error: + other: Gwall gweinydd data. + forbidden_error: + other: Forbidden. + duplicate_request_error: + other: Duplicate submission. + action: + report: + other: Tynnu sylw + edit: + other: Golygu + delete: + other: Dileu + close: + other: Cau + reopen: + other: Ailagor + forbidden_error: + other: Forbidden. + pin: + other: Pinio + hide: + other: Dad-restru + unpin: + other: Dadbinio + show: + other: Rhestr + invite_someone_to_answer: + other: Edit + undelete: + other: Undelete + merge: + other: Merge + role: + name: + user: + other: Defnyddiwr + admin: + other: Gweinyddwr + moderator: + other: Cymedrolwr + description: + user: + other: Diofyn heb unrhyw fynediad arbennig. + admin: + other: Bod â'r pŵer llawn i gael mynediad i'r safle. + moderator: + other: Mae ganddo fynediad i bob post ac eithrio gosodiadau gweinyddol. + privilege: + level_1: + description: + other: Level 1 (less reputation required for private team, group) + level_2: + description: + other: Level 2 (low reputation required for startup community) + level_3: + description: + other: Level 3 (high reputation required for mature community) + level_custom: + description: + other: Custom Level + rank_question_add_label: + other: Ask question + rank_answer_add_label: + other: Write answer + rank_comment_add_label: + other: Write comment + rank_report_add_label: + other: Flag + rank_comment_vote_up_label: + other: Upvote comment + rank_link_url_limit_label: + other: Post more than 2 links at a time + rank_question_vote_up_label: + other: Upvote question + rank_answer_vote_up_label: + other: Upvote answer + rank_question_vote_down_label: + other: Downvote question + rank_answer_vote_down_label: + other: Downvote answer + rank_invite_someone_to_answer_label: + other: Invite someone to answer + rank_tag_add_label: + other: Create new tag + rank_tag_edit_label: + other: Edit tag description (need to review) + rank_question_edit_label: + other: Edit other's question (need to review) + rank_answer_edit_label: + other: Edit other's answer (need to review) + rank_question_edit_without_review_label: + other: Edit other's question without review + rank_answer_edit_without_review_label: + other: Edit other's answer without review + rank_question_audit_label: + other: Review question edits + rank_answer_audit_label: + other: Review answer edits + rank_tag_audit_label: + other: Review tag edits + rank_tag_edit_without_review_label: + other: Edit tag description without review + rank_tag_synonym_label: + other: Manage tag synonyms + email: + other: Ebost + e_mail: + other: Email + password: + other: Cyfrinair + pass: + other: Password + old_pass: + other: Current password + original_text: + other: This post + email_or_password_wrong_error: + other: Nid yw e-bost a chyfrinair yn cyfateb. + error: + common: + invalid_url: + other: Invalid URL. + status_invalid: + other: Invalid status. + password: + space_invalid: + other: Password cannot contain spaces. + admin: + cannot_update_their_password: + other: Ni allwch addasu eich cyfrinair. + cannot_edit_their_profile: + other: You cannot modify your profile. + cannot_modify_self_status: + other: Ni allwch addasu eich statws. + email_or_password_wrong: + other: Nid yw e-bost a chyfrinair yn cyfateb. + answer: + not_found: + other: Ni cheir yr ateb. + cannot_deleted: + other: Dim caniatâd i ddileu. + cannot_update: + other: Dim caniatâd i ddiweddaru. + question_closed_cannot_add: + other: Mae cwestiynau ar gau ac ni ellir eu hychwanegu. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Nid oes modd golygu sylwadau. + not_found: + other: Sylw heb ei ganfod. + cannot_edit_after_deadline: + other: Mae'r amser sylwadau wedi bod yn rhy hir i'w addasu. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: E-bost yn bodoli eisoes. + need_to_be_verified: + other: Dylid gwirio e-bost. + verify_url_expired: + other: Mae'r URL wedi'i wirio gan e-bost wedi dod i ben, anfonwch yr e-bost eto. + illegal_email_domain_error: + other: Email is not allowed from that email domain. Please use another one. + lang: + not_found: + other: Ffeil iaith heb ei chanfod. + object: + captcha_verification_failed: + other: Captcha anghywir. + disallow_follow: + other: Ni chaniateir i chi ddilyn. + disallow_vote: + other: Ni chaniateir i chi pleidleisio. + disallow_vote_your_self: + other: Ni allwch bleidleisio dros eich post eich hun. + not_found: + other: Heb ganfod y gwrthrych. + verification_failed: + other: Methodd y dilysu. + email_or_password_incorrect: + other: Nid yw e-bost a chyfrinair yn cyfateb. + old_password_verification_failed: + other: Methodd yr hen ddilysiad cyfrinair + new_password_same_as_previous_setting: + other: Mae'r cyfrinair newydd yr un fath â'r un blaenorol. + already_deleted: + other: This post has been deleted. + meta: + object_not_found: + other: Meta object not found + question: + already_deleted: + other: Mae'r postiad hwn wedi'i ddileu. + under_review: + other: Your post is awaiting review. It will be visible after it has been approved. + not_found: + other: Cwestiwn heb ei ganfod. + cannot_deleted: + other: Dim caniatâd i ddileu. + cannot_close: + other: Dim caniatâd i cau. + cannot_update: + other: Dim caniatâd i ddiweddaru. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Reputation rank fail to meet the condition. + vote_fail_to_meet_the_condition: + other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. + no_enough_rank_to_operate: + other: You need at least {{.Rank}} reputation to do this. + report: + handle_failed: + other: Methodd handlen yr adroddiad. + not_found: + other: Heb ganfod yr adroddiad. + tag: + already_exist: + other: Mae tag eisoes yn bodoli. + not_found: + other: Tag heb ei ddarganfod. + recommend_tag_not_found: + other: Recommend tag is not exist. + recommend_tag_enter: + other: Rhowch o leiaf un tag gofynnol. + not_contain_synonym_tags: + other: Ni ddylai gynnwys tagiau cyfystyr. + cannot_update: + other: Dim caniatâd i ddiweddaru. + is_used_cannot_delete: + other: You cannot delete a tag that is in use. + cannot_set_synonym_as_itself: + other: Ni allwch osod cyfystyr y tag cyfredol fel ei hun. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: The from name cannot be a email address. + theme: + not_found: + other: Thema heb ei ddarganfod. + revision: + review_underway: + other: Methu â golygu ar hyn o bryd, mae fersiwn yn y ciw adolygu. + no_permission: + other: No permission to revise. + user: + external_login_missing_user_id: + other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. + external_login_unbinding_forbidden: + other: Please set a login password for your account before you remove this login. + email_or_password_wrong: + other: + other: Nid yw e-bost a chyfrinair yn cyfateb. + not_found: + other: Defnyddwr heb ei ddarganfod. + suspended: + other: Mae'r defnyddiwr hwn wedi'i atal. + username_invalid: + other: Mae'r enw defnyddiwr yn annilys. + username_duplicate: + other: Cymerwyd yr enw defnyddiwr eisoes. + set_avatar: + other: Methodd set avatar. + cannot_update_your_role: + other: Ni allwch addasu eich rôl. + not_allowed_registration: + other: Currently the site is not open for registration. + not_allowed_login_via_password: + other: Currently the site is not allowed to login via password. + access_denied: + other: Access denied + page_access_denied: + other: You do not have access to this page. + add_bulk_users_format_error: + other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Wedi methu darllen y ffurfwedd + database: + connection_failed: + other: Methodd cysylltiad cronfa ddata + create_table_failed: + other: Methwyd creu tabl + install: + create_config_failed: + other: Methu creu'r ffeil config.yaml. + upload: + unsupported_file_format: + other: Fformat ffeil heb ei gefnogi. + site_info: + config_not_found: + other: Site config not found. + badge: + object_not_found: + other: Badge object not found + reason: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude_or_abusive: + name: + other: rude or abusive + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + a_duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + placeholder: + other: Enter the existing question link + not_a_answer: + name: + other: not an answer + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." + no_longer_needed: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + something: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + placeholder: + other: Let us know specifically what you are concerned about + community_specific: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + not_clarity: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + looks_ok: + name: + other: looks OK + desc: + other: This post is good as-is and not low quality. + needs_edit: + name: + other: needs edit, and I did it + desc: + other: Improve and correct problems with this post yourself. + needs_close: + name: + other: needs close + desc: + other: A closed question can't answer, but still can edit, vote and comment. + needs_delete: + name: + other: needs delete + desc: + other: This post will be deleted. + question: + close: + duplicate: + name: + other: sbam + desc: + other: Mae'r cwestiwn hwn wedi'i ofyn o'r blaen ac mae ganddo ateb yn barod. + guideline: + name: + other: rheswm cymunedol-benodol + desc: + other: Nid yw'r cwestiwn hwn yn bodloni canllaw cymunedol. + multiple: + name: + other: angen manylion neu eglurder + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: rhywbeth arall + desc: + other: Mae'r swydd hon angen reswm arall nad yw wedi'i restru uchod. + operation_type: + asked: + other: gofynnodd + answered: + other: atebodd + modified: + other: wedi newid + deleted_title: + other: Deleted question + questions_title: + other: Questions + tag: + tags_title: + other: Tags + no_description: + other: The tag has no description. + notification: + action: + update_question: + other: cwestiwn wedi'i ddiweddaru + answer_the_question: + other: cwestiwn wedi ei ateb + update_answer: + other: ateb wedi'i ddiweddaru + accept_answer: + other: ateb derbyniol + comment_question: + other: cwestiwn a wnaed + comment_answer: + other: ateb a wnaed + reply_to_you: + other: atebodd i chi + mention_you: + other: wedi sôn amdanoch + your_question_is_closed: + other: Mae eich cwestiwn wedi’i gau + your_question_was_deleted: + other: Mae eich cwestiwn wedi’i dileu + your_answer_was_deleted: + other: Mae eich ateb wedi’i dileu + your_comment_was_deleted: + other: Mae eich sylw wedi’i dileu + up_voted_question: + other: upvoted question + down_voted_question: + other: downvoted question + up_voted_answer: + other: upvoted answer + down_voted_answer: + other: downvoted answer + up_voted_comment: + other: upvoted comment + invited_you_to_answer: + other: invited you to answer + earned_badge: + other: You've earned the "{{.BadgeName}}" badge + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Confirm your new email address" + body: + other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} answered your question" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_question: + title: + other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Password reset" + body: + other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + register: + title: + other: "[{{.SiteName}}] Confirm your new account" + body: + other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + test: + title: + other: "[{{.SiteName}}] Test Email" + body: + other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + action_activity_type: + upvote: + other: upvote + upvoted: + other: upvoted + downvote: + other: downvote + downvoted: + other: downvoted + accept: + other: accept + accepted: + other: accepted + edit: + other: edit + review: + queued_post: + other: Queued post + flagged_post: + other: Flagged post + suggested_post_edit: + other: Suggested edits + reaction: + tooltip: + other: "{{ .Names }} and {{ .Count }} more..." + badge: + default_badges: + autobiographer: + name: + other: Autobiographer + desc: + other: Filled out profile information. + certified: + name: + other: Certified + desc: + other: Completed our new user tutorial. + editor: + name: + other: Editor + desc: + other: First post edit. + first_flag: + name: + other: First Flag + desc: + other: First flagged a post. + first_upvote: + name: + other: First Upvote + desc: + other: First up voted a post. + first_link: + name: + other: First Link + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: First Share + desc: + other: First shared a post. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Leave 5 comments. + new_user_of_the_month: + name: + other: New User of the Month + desc: + other: Outstanding contributions in their first month. + read_guidelines: + name: + other: Read Guidelines + desc: + other: Read the [community guidelines]. + reader: + name: + other: Reader + desc: + other: Read every answers in a topic with more than 10 answers. + welcome: + name: + other: Welcome + desc: + other: Received a up vote. + nice_share: + name: + other: Nice Share + desc: + other: Shared a post with 25 unique visitors. + good_share: + name: + other: Good Share + desc: + other: Shared a post with 300 unique visitors. + great_share: + name: + other: Great Share + desc: + other: Shared a post with 1000 unique visitors. + out_of_love: + name: + other: Out of Love + desc: + other: Used 50 up votes in a day. + higher_love: + name: + other: Higher Love + desc: + other: Used 50 up votes in a day 5 times. + crazy_in_love: + name: + other: Crazy in Love + desc: + other: Used 50 up votes in a day 20 times. + promoter: + name: + other: Promoter + desc: + other: Invited a user. + campaigner: + name: + other: Campaigner + desc: + other: Invited 3 basic users. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: Thank You + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Active member for a year, posted at least once. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Sut i Fformatio + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Cynt + next: Nesaf + page_title: + question: Cwestiwn + questions: Cwestiynau + tag: Tag + tags: Tagiau + tag_wiki: tag wiki + create_tag: Creu Tag + edit_tag: Golygu Tag + ask_a_question: Create Question + edit_question: Golygu Cwestiwn + edit_answer: Golygu Ateb + search: Chwiliwch + posts_containing: Postiadau yn cynnwys + settings: Gosodiadau + notifications: Hysbysiadau + login: Mewngofnodi + sign_up: Cofrestru + account_recovery: Adfer Cyfrif + account_activation: Ysgogi Cyfrif + confirm_email: Cadarnhau e-bost + account_suspended: Cyfrif wedi'i atal + admin: Gweinyddu + change_email: Addasu E-bost + install: Ateb Gosod + upgrade: Ateb Uwchraddio + maintenance: Cynnal a Chadw Gwefan + users: Defnyddwyr + oauth_callback: Processing + http_404: Gwall HTTP 404 + http_50X: Gwall HTTP 500 + http_403: Gwall HTTP 403 + logout: Log Out + posts: Posts + notifications: + title: Hysbysiadau + inbox: Mewnflwch + achievement: Llwyddiannau + new_alerts: New alerts + all_read: Marciwch y cyfan fel wedi'i ddarllen + show_more: Dangos mwy + someone: Someone + inbox_type: + all: All + posts: Posts + invites: Invites + votes: Votes + answer: Answer + question: Question + badge_award: Badge + suspended: + title: Mae'ch Cyfrif wedi'i Atal + until_time: "Cafodd eich cyfrif ei atal tan {{ time }}." + forever: Cafodd y defnyddiwr hwn ei atal am byth. + end: Nid ydych yn arwain cymunedol. + contact_us: Contact us + editor: + blockquote: + text: Dyfyniad + bold: + text: Cryf + chart: + text: Siart + flow_chart: Siart llif + sequence_diagram: Diagram dilyniant + class_diagram: Diagram dosbarth + state_diagram: Diagram cyflwr + entity_relationship_diagram: Diagram perthynas endid + user_defined_diagram: Diagram wedi'i ddiffinio gan y defnyddiwr + gantt_chart: Siart Gantt + pie_chart: Siart cylch + code: + text: Sampl côd + add_code: Ychwanegu sampl côd + form: + fields: + code: + label: Côd + msg: + empty: Ni all côd fod yn wag. + language: + label: Iaith + placeholder: Synhwyriad awtomatig + btn_cancel: Canslo + btn_confirm: Ychwanegu + formula: + text: Fformiwla + options: + inline: Fformiwla mewn-lein + block: Fformiwla bloc + heading: + text: Pennawd + options: + h1: Pennawd 1 + h2: Pennawd 2 + h3: Pennawd 3 + h4: Pennawd 4 + h5: Pennawd 5 + h6: Pennawd 6 + help: + text: Cymorth + hr: + text: Horizontal rule + image: + text: Delwedd + add_image: Ychwanegu delwedd + tab_image: Uwchlwytho delwedd + form_image: + fields: + file: + label: Image file + btn: Dewis delwedd + msg: + empty: Ni all ffeil fod yn wag. + only_image: Dim ond ffeiliau delwedd a ganiateir. + max_size: File size cannot exceed {{size}} MB. + desc: + label: Disgrifiad + tab_url: URL delwedd + form_url: + fields: + url: + label: URL delwedd + msg: + empty: Ni all URL delwedd fod yn wag. + name: + label: Disgrifiad + btn_cancel: Canslo + btn_confirm: Ychwanegu + uploading: Wrthi'n uwchlwytho + indent: + text: Mewnoliad + outdent: + text: Alloliad + italic: + text: Pwyslais + link: + text: Hypergyswllt + add_link: Ychwanegu hypergyswllt + form: + fields: + url: + label: URL + msg: + empty: Ni all URL fod yn wag. + name: + label: Disgrifiad + btn_cancel: Canslo + btn_confirm: Ychwanegu + ordered_list: + text: Numbered list + unordered_list: + text: Bulleted list + table: + text: Tabl + heading: Pennawd + cell: Cell + file: + text: Attach files + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: Rwy'n cau'r post hon fel... + btn_cancel: Canslo + btn_submit: Cyflwyno + remark: + empty: Ni all fod yn wag. + msg: + empty: Dewis rheswm. + report_modal: + flag_title: Dwi'n tynnu sylw i adrodd y swydd hon fel... + close_title: Rwy'n cau'r post hon fel... + review_question_title: Adolygu cwestiwn + review_answer_title: Adolygu ateb + review_comment_title: Adolygu sylwad + btn_cancel: Canslo + btn_submit: Cyflwyno + remark: + empty: Ni all fod yn wag. + msg: + empty: Dewis rheswm. + not_a_url: URL format is incorrect. + url_not_match: URL origin does not match the current website. + tag_modal: + title: Creu tag newydd + form: + fields: + display_name: + label: Display name + msg: + empty: Ni all fod enw dangos yn wag. + range: Enw arddangos hyd at 35 nod. + slug_name: + label: URL slug + desc: Slug URL hyd at 35 nod. + msg: + empty: Ni all Slug URL fod yn wag. + range: Slug URL hyd at 35 nod. + character: Mae slug URL yn cynnwys set nodau na caniateir. + desc: + label: Disgrifiad + revision: + label: Revision + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_cancel: Canslo + btn_submit: Cyflwyno + btn_post: Post tag newydd + tag_info: + created_at: Creuwyd + edited_at: Golygwyd + history: Hanes + synonyms: + title: Cyfystyron + text: Bydd y tagiau canlynol yn cael eu hail-fapio i + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + tip_with_posts: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + tip_with_synonyms: >- +

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        + tip: Are you sure you wish to delete? + close: Close + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + default_first_reason: Add tag + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + hours: hours + days: days + month: month + months: months + year: year + reaction: + heart: heart + smile: smile + frown: frown + btn_label: add or remove reactions + undo_emoji: undo {{ emoji }} reaction + react_emoji: react with {{ emoji }} + unreact_emoji: unreact with {{ emoji }} + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: "{{count}} more comments" + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + tip_vote: It adds something useful to the post + edit_answer: + title: Edit Answer + default_reason: Edit answer + default_first_reason: Add answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Canslo + tags: + title: Tagiau + sort_buttons: + popular: Poblogaidd + name: Enw + newest: Newest + button_follow: Dilyn + button_following: Yn dilyn + tag_label: cwestiynau + search_placeholder: Hidlo yn ôl enw tag + no_desc: Nid oes gan y tag unrhyw ddisgrifiad. + more: Mwy + wiki: Wiki + ask: + title: Create Question + edit_title: Golygu Cwestiwn + default_reason: Golygu Cwestiwn + default_first_reason: Create question + similar_questions: Cwestiynau tebyg + form: + fields: + revision: + label: Diwygiad + title: + label: Teitl + placeholder: What's your topic? Be specific. + msg: + empty: Ni all teitl fod yn wag. + range: Teitl hyd at 20 nod + body: + label: Corff + msg: + empty: Ni all corff fod yn wag. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Tagiau + msg: + empty: Ni all tagiau fod yn wag. + answer: + label: Ateb + msg: + empty: Ni all ateb fod yn wag. + edit_summary: + label: Edit summary + placeholder: >- + Eglurwch yn fyr eich newidiadau (sillafu wedi'i gywiro, gramadeg sefydlog, fformatio gwell) + btn_post_question: Post cweistiwn + btn_save_edits: Cadw golygiadau + answer_question: Atebwch eich cwestiwn eich hun + post_question&answer: Postiwch eich cwestiwn ac ateb + tag_selector: + add_btn: Ychwanegu tag + create_btn: Creu tag newydd + search_tag: Chwilio tag + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + badges: Badges + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + bookmark: Bookmarks + moderation: Moderation + search: + placeholder: Search + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + resend_email: + url_label: Are you sure you want to resend the activation email? + url_text: You can also give the activation link above to the user. + login: + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New email + msg: + empty: Email cannot be empty. + oauth: + connect: Connect with {{ auth_name }} + remove: Remove {{ auth_name }} + oauth_bind_email: + subtitle: Add a recovery email to your account. + btn_update: Update email address + email: + label: Email + msg: + empty: Email cannot be empty. + modal_title: Email already existes. + modal_content: This email address already registered. Are you sure you want to connect to the existing account? + modal_cancel: Change email + modal_confirm: Connect to the existing account + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm new password + settings: + page_title: Settings + goto_modify: Go to modify + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile image + gravatar: Gravatar + gravatar_text: You can change image on + custom: Custom + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About me + website: + label: Website + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location + placeholder: "City, Country" + notification: + heading: Email Notifications + turn_on: Turn on + inbox: + label: Inbox notifications + description: Answers to your questions, comments, invites, and more. + all_new_question: + label: All new questions + description: Get notified of all new questions. Up to 50 questions per week. + all_new_question_for_following_tags: + label: All new questions for following tags + description: Get notified of new questions for following tags. + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + pass: + label: Current password + msg: Password cannot be empty. + password_title: Password + current_pass: + label: Current password + msg: + empty: Current password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New password + pass_confirm: + label: Confirm new password + interface: + heading: Interface + lang: + label: Interface language + text: User interface language. It will change when you refresh the page. + my_logins: + title: My logins + label: Log in or sign up on this site using these accounts. + modal_title: Remove login + modal_content: Are you sure you want to remove this login from your account? + modal_confirm_btn: Remove + remove_success: Removed successfully + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + sent_success: Sent successfully + related_question: + title: Related + answers: answers + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: People Asked + desc: Select people who you think might know the answer. + invite: Invite to answer + add: Add people + search: Search people + question_detail: + action: Action + created: Created + Asked: Asked + asked: asked + update: Modified + Edited: Edited + edit: edited + commented: commented + Views: Viewed + Follow: Follow + Following: Following + follow_tip: Follow this question to receive notifications + answered: answered + closed_in: Closed in + show_exist: Show existing question. + useful: Useful + question_useful: It is useful and clear + question_un_useful: It is unclear or not useful + question_bookmark: Bookmark this question + answer_useful: It is useful + answer_un_useful: It is not useful + answers: + title: Answers + score: Score + newest: Newest + oldest: Oldest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + edit_answer: Edit my existing answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + tips: + header_1: Thanks for your answer + li1_1: Please be sure to answer the question. Provide details and share your research. + li1_2: Back up any statements you make with references or personal experience. + header_2: But avoid ... + li2_1: Asking for help, seeking clarification, or responding to other answers. + reopen: + confirm_btn: Reopen + title: Reopen this post + content: Are you sure you want to reopen? + list: + confirm_btn: List + title: List this post + content: Are you sure you want to list? + unlist: + confirm_btn: Unlist + title: Unlist this post + content: Are you sure you want to unlist? + pin: + title: Pin this post + content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. + confirm_btn: Pin + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_answer_deleted: This answer has been deleted + undelete_title: Undelete this post + undelete_desc: Are you sure you wish to undelete? + btns: + confirm: Confirm + cancel: Cancel + edit: Edit + save: Save + delete: Delete + undelete: Undelete + list: List + unlist: Unlist + unlisted: Unlisted + login: Log in + signup: Sign up + logout: Log out + verify: Verify + create: Create + approve: Approve + reject: Reject + skip: Skip + discard_draft: Discard draft + pinned: Pinned + all: All + question: Question + answer: Answer + comment: Comment + refresh: Refresh + resend: Resend + deactivate: Deactivate + active: Active + suspend: Suspend + unsuspend: Unsuspend + close: Close + reopen: Reopen + ok: OK + light: Light + dark: Dark + system_setting: System setting + default: Default + reset: Reset + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignore + submit: Submit + normal: Normal + closed: Closed + deleted: Deleted + deleted_permanently: Deleted permanently + pending: Pending + more: More + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + counts_loading: "... Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post. + modal_confirm: + title: Error... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + x_posts: "{{ count }} Posts" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + frequent: Frequent + recommend: Recommend + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + badges: Badges + newest: Newest + score: Score + edit_profile: Edit profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + comma: "," + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + content_empty: No posts found. + accepted: Accepted + answered: answered + asked: asked + downvoted: downvoted + mod_short: MOD + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + recent_badges: Recent Badges + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please choose a language + db_type: + label: Database engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database host + placeholder: "db:3306" + msg: Database host cannot be empty. + db_name: + label: Database name + placeholder: answer + msg: Database name cannot be empty. + db_file: + label: Database file + placeholder: /data/answer.db + msg: Database file cannot be empty. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site name + msg: Site name cannot be empty. + msg_max_length: Site name must be at maximum 30 characters in length. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + max_length: Site URL must be at maximum 512 characters in length. + contact_email: + label: Contact email + text: Email address of key contact responsible for this site. + msg: + empty: Contact email cannot be empty. + incorrect: Contact email incorrect format. + login_required: + label: Private + switch: Login required + text: Only logged in users can access this community. + admin_name: + label: Name + msg: Name cannot be empty. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + msg_min_length: Password must be at least 8 characters in length. + msg_max_length: Password must be at maximum 32 characters in length. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_error: + http_error: HTTP Error {{ code }} + desc_403: You don't have permission to access this page. + desc_404: Unfortunately, this page doesn't exist. + desc_50X: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + badges: Badges + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + terms: Terms + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + login: Login + privileges: Privileges + plugins: Plugins + installed_plugins: Installed Plugins + apperance: Appearance + website_welcome: Welcome to {{site_name}} + user_center: + login: Login + qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. + login_failed_email_tip: Login failed, please allow this app to access your email information before try again. + badges: + modal: + title: Congratulations + content: You've earned a new badge. + close: Close + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site statistics + questions: "Questions:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + users: "Users:" + flags: "Flags:" + reviews: "Reviews:" + site_health: Site health + version: "Version:" + https: "HTTPS:" + upload_folder: "Upload folder:" + run_mode: "Running mode:" + private: Private + public: Public + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System info + go_version: "Go version:" + database: "Database:" + database_size: "Database size:" + storage_used: "Storage used:" + uptime: "Uptime:" + links: Links + plugins: Plugins + github: GitHub + blog: Blog + contact: Contact + forum: Forum + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + writable: Writable + not_writable: Not writable + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + flagged_type: Flagged {{ type }} + created: Created + action: Action + review: Review + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + edit_profile_modal: + title: Edit profile + form: + fields: + display_name: + label: Display name + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Invalid Email Address. + edit_success: Edited successfully + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + users: + label: Bulk add user + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separate “name, email, password” with commas. One user per line. + msg: "Please enter the user's email, one per line." + display_name: + label: Display name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + more: More + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + edit_profile: Edit profile + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + deactivate_user: + title: Deactivate user + content: An inactive user must re-validate their email. + delete_user: + title: Delete this user + content: Are you sure you want to delete this user? This is permanent! + remove: Remove their content + label: Remove all questions, answers, comments, etc. + text: Don’t check this if you wish to only delete the user’s account. + suspend_user: + title: Suspend this user + content: A suspended user can't log in. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Questions + unlisted: Unlisted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + pending: Pending + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short site description + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site description + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + check_update: + label: Software updates + text: Automatically check for updates + interface: + page_title: Interface + language: + label: Interface language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: From email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + tls: TLS + none: None + smtp_port: + label: SMTP port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test email recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile logo + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square icon + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Write + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Each user can only write one answer for each question + text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Recommend tags + text: "Recommend tags will show in the dropdown list by default." + msg: + contain_reserved: "recommended tags cannot contain reserved tags" + required_tag: + title: Set required tags + label: Set “Recommend tags” as required tags + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved tags + text: "Reserved tags can only be used by moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + color_scheme: + label: Color scheme + navbar_style: + label: Navbar background style + primary_color: + label: Primary color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: > + + head: + label: Head + text: > + + header: + label: Header + text: > + + footer: + label: Footer + text: This will insert before </body>. + sidebar: + label: Sidebar + text: This will insert in sidebar. + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + email_registration: + title: Email registration + label: Allow email registration + text: Turn off to prevent anyone creating new account through email. + allowed_email_domains: + title: Allowed email domains + text: Email domains that users must register accounts with. One domain per line. Ignored when empty. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + password_login: + title: Password login + label: Allow email and password login + text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." + installed_plugins: + title: Installed Plugins + plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + filter: + all: All + active: Active + inactive: Inactive + outdated: Outdated + plugins: + label: Plugins + text: Select an existing plugin. + name: Name + version: Version + status: Status + action: Action + deactivate: Deactivate + activate: Activate + settings: Settings + settings_users: + title: Users + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar Base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + profile_editable: + title: Profile editable + allow_update_display_name: + label: Allow users to change their display name + allow_update_username: + label: Allow users to change their username + allow_update_avatar: + label: Allow users to change their profile image + allow_update_bio: + label: Allow users to change their about me + allow_update_website: + label: Allow users to change their website + allow_update_location: + label: Allow users to change their location + privilege: + title: Privileges + level: + label: Reputation required level + text: Choose the reputation required for the privileges + msg: + should_be_number: the input should be number + number_larger_1: number should be equal or larger than 1 + badges: + action: Action + active: Active + activate: Activate + all: All + awards: Awards + deactivate: Deactivate + filter: + placeholder: Filter by name, badge:id + group: Group + inactive: Inactive + name: Name + show_logs: Show logs + status: Status + title: Badges + form: + optional: (optional) + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + select: Select + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + approve_revision_tip: Do you approve this revision? + approve_flag_tip: Do you approve this flag? + approve_post_tip: Do you approve this post? + approve_user_tip: Do you approve this user? + suggest_edits: Suggested edits + flag_post: Flag post + flag_user: Flag user + queued_post: Queued post + queued_user: Queued user + filter_label: Type + reputation: reputation + flag_post_type: Flagged this post as {{ type }}. + flag_user_type: Flagged this user as {{ type }}. + edit_post: Edit post + list_post: List post + unlist_post: Unlist post + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + pin: pinned + unpin: unpinned + show: listed + hide: unlisted + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores this week + users_with_the_most_vote: Users who voted the most this week + staffs: Our community staff + reputation: reputation + votes: votes + prompt: + leave_page: Are you sure you want to leave the page? + changes_not_save: Your changes may not be saved. + draft: + discard_confirm: Are you sure you want to discard your draft? + messages: + post_deleted: This post has been deleted. + post_cancel_deleted: This post has been undeleted. + post_pin: This post has been pinned. + post_unpin: This post has been unpinned. + post_hide_list: This post has been hidden from list. + post_show_list: This post has been shown to list. + post_reopen: This post has been reopened. + post_list: This post has been listed. + post_unlist: This post has been unlisted. + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/da_DK.yaml b/data/i18n/da_DK.yaml new file mode 100644 index 000000000..63da094c4 --- /dev/null +++ b/data/i18n/da_DK.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Gennemført. + unknown: + other: Ukendt fejl. + request_format_error: + other: Forespørgselsformat er ikke gyldigt. + unauthorized_error: + other: Uautoriseret. + database_error: + other: Data-server fejl. + forbidden_error: + other: Forbudt. + duplicate_request_error: + other: Duplilkeret indenselse. + action: + report: + other: Anmeld + edit: + other: Rediger + delete: + other: Slet + close: + other: Luk + reopen: + other: Genåbn + forbidden_error: + other: Forbudt. + pin: + other: Fastgør + hide: + other: Afliste + unpin: + other: Frigør + show: + other: Liste + invite_someone_to_answer: + other: Rediger + undelete: + other: Genopret + merge: + other: Merge + role: + name: + user: + other: Bruger + admin: + other: Administrator + moderator: + other: Moderator + description: + user: + other: Standard uden særlig adgang. + admin: + other: Hav den fulde magt til at få adgang til webstedet. + moderator: + other: Har adgang til alle indlæg undtagen administratorindstillinger. + privilege: + level_1: + description: + other: Niveau 1 (mindre omdømme kræves for private team, gruppe) + level_2: + description: + other: Niveau 2 (lav omdømme kræves for opstart fællesskab) + level_3: + description: + other: Niveau 3 (højt omdømme kræves for moden fællesskab) + level_custom: + description: + other: Brugerdefineret Niveau + rank_question_add_label: + other: Stil spørgsmål + rank_answer_add_label: + other: Skriv svar + rank_comment_add_label: + other: Skriv kommentar + rank_report_add_label: + other: Anmeld + rank_comment_vote_up_label: + other: Op-stem kommentar + rank_link_url_limit_label: + other: Skriv mere end 2 links ad gangen + rank_question_vote_up_label: + other: Op-stem spørgsmål + rank_answer_vote_up_label: + other: Op-stem svar + rank_question_vote_down_label: + other: Ned-stem spørgsmål + rank_answer_vote_down_label: + other: Ned-stem svar + rank_invite_someone_to_answer_label: + other: Inviter nogen til at svare + rank_tag_add_label: + other: Opret et nyt tag + rank_tag_edit_label: + other: Rediger tag beskrivelse (skal gennemgås) + rank_question_edit_label: + other: Rediger andres spørgsmål (skal gennemgås) + rank_answer_edit_label: + other: Redigere andres svar (skal gennemgås) + rank_question_edit_without_review_label: + other: Rediger andres spørgsmål uden gennemgang + rank_answer_edit_without_review_label: + other: Rediger andres svar uden gennemgang + rank_question_audit_label: + other: Gennemse spørgsmål redigeringer + rank_answer_audit_label: + other: Gennemgå svar redigeringer + rank_tag_audit_label: + other: Gennemse tag redigeringer + rank_tag_edit_without_review_label: + other: Rediger tag beskrivelse uden gennemgang + rank_tag_synonym_label: + other: Administrer tag synonymer + email: + other: E-mail + e_mail: + other: E-mail + password: + other: Adgangskode + pass: + other: Adgangskode + old_pass: + other: Current password + original_text: + other: Dette indlæg + email_or_password_wrong_error: + other: E-mail og adgangskode stemmer ikke overens. + error: + common: + invalid_url: + other: Ugyldig URL. + status_invalid: + other: Invalid status. + password: + space_invalid: + other: Adgangskoden må ikke indeholde mellemrum. + admin: + cannot_update_their_password: + other: Du kan ikke ændre din adgangskode. + cannot_edit_their_profile: + other: Du kan ikke ændre din profil. + cannot_modify_self_status: + other: Du kan ikke ændre din status. + email_or_password_wrong: + other: E-mail og adgangskode stemmer ikke overens. + answer: + not_found: + other: Svar ikke fundet. + cannot_deleted: + other: Ingen tilladelser til at slette. + cannot_update: + other: Ingen tilladelse til at opdatere. + question_closed_cannot_add: + other: Spørgsmål er lukket og kan ikke tilføjes. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Kommentar er ikke tilladt at redigere. + not_found: + other: Kommentar ikke fundet. + cannot_edit_after_deadline: + other: Kommentaren er for gammel til at blive redigeret. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: Email eksisterer allerede. + need_to_be_verified: + other: E-mail skal bekræftes. + verify_url_expired: + other: Email bekræftet URL er udløbet. Send venligst e-mailen igen. + illegal_email_domain_error: + other: E-mail er ikke tilladt fra dette e-mail-domæne. Brug venligst et andet. + lang: + not_found: + other: Sprog-fil kunne ikke findes. + object: + captcha_verification_failed: + other: Captcha er forkert. + disallow_follow: + other: Du har ikke tilladelse til at følge. + disallow_vote: + other: Du har ikke tilladelse til at stemme. + disallow_vote_your_self: + other: Du kan ikke stemme på dit eget indlæg. + not_found: + other: Objekt ikke fundet. + verification_failed: + other: Verifikation mislykkedes. + email_or_password_incorrect: + other: E-mail og adgangskode stemmer ikke overens. + old_password_verification_failed: + other: Den gamle adgangskodebekræftelse mislykkedes + new_password_same_as_previous_setting: + other: Den nye adgangskode er den samme som den foregående. + already_deleted: + other: Dette indlæg er blevet slettet. + meta: + object_not_found: + other: Metaobjekt ikke fundet + question: + already_deleted: + other: Dette indlæg er blevet slettet. + under_review: + other: Dit indlæg afventer gennemgang. Det vil være synligt, når det er blevet godkendt. + not_found: + other: Spørgsmål ikke fundet. + cannot_deleted: + other: Ingen tilladelser til at slette. + cannot_close: + other: Ingen tilladelse til at lukke. + cannot_update: + other: Ingen tilladelse til at opdatere. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Omdømmelse rang opfylder ikke betingelsen. + vote_fail_to_meet_the_condition: + other: Tak for feedback. Du skal mindst have {{.Rank}} ry for at afgive en stemme. + no_enough_rank_to_operate: + other: Du skal mindst {{.Rank}} omdømme for at gøre dette. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Rapport ikke fundet. + tag: + already_exist: + other: Tag findes allerede. + not_found: + other: Tag blev ikke fundet. + recommend_tag_not_found: + other: Anbefal tag eksisterer ikke. + recommend_tag_enter: + other: Indtast mindst et påkrævet tag. + not_contain_synonym_tags: + other: Må ikke indeholde synonym tags. + cannot_update: + other: Ingen tilladelse til at opdatere. + is_used_cannot_delete: + other: Du kan ikke slette et tag, der er i brug. + cannot_set_synonym_as_itself: + other: Du kan ikke indstille synonymet for det nuværende tag som sig selv. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: Fra-navnet kan ikke være en e-mail-adresse. + theme: + not_found: + other: Tema ikke fundet. + revision: + review_underway: + other: Kan ikke redigere i øjeblikket, der er en version i revisionskøen. + no_permission: + other: Ingen tilladelse til at revidere. + user: + external_login_missing_user_id: + other: Den tredjepartsplatform giver ikke et unikt UserID, så du kan ikke logge ind, kontakt venligst webstedsadministratoren. + external_login_unbinding_forbidden: + other: Angiv en adgangskode til din konto, før du fjerner dette login. + email_or_password_wrong: + other: + other: E-mail og adgangskode stemmer ikke overens. + not_found: + other: Bruger ikke fundet. + suspended: + other: Brugeren er suspenderet. + username_invalid: + other: Brugernavn er ugyldigt. + username_duplicate: + other: Brugernavn er allerede i brug. + set_avatar: + other: Avatar sæt mislykkedes. + cannot_update_your_role: + other: Du kan ikke ændre din rolle. + not_allowed_registration: + other: Webstedet er ikke åbent for registrering. + not_allowed_login_via_password: + other: I øjeblikket er det ikke tilladt at logge ind via adgangskode. + access_denied: + other: Adgang nægtet + page_access_denied: + other: Du har ikke adgang til denne side. + add_bulk_users_format_error: + other: "Fejl {{.Field}} format nær '{{.Content}}' i linje {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "Antallet af brugere du tilføjer på én gang skal være i intervallet 1 -{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Kunne ikke læse konfigurationen + database: + connection_failed: + other: Database forbindelse mislykkedes + create_table_failed: + other: Tabellen kunne ikke oprettes + install: + create_config_failed: + other: Kan ikke oprette filen config.yaml. + upload: + unsupported_file_format: + other: Ikke understøttet filformat. + site_info: + config_not_found: + other: Site config ikke fundet. + badge: + object_not_found: + other: Badge object not found + reason: + spam: + name: + other: spam + desc: + other: Dette indlæg er en annonce eller vandalisme. Det er ikke nyttigt eller relevant for det aktuelle emne. + rude_or_abusive: + name: + other: uhøflig eller misbrug + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + a_duplicate: + name: + other: en duplikering + desc: + other: Dette spørgsmål er blevet stillet før og har allerede et svar. + placeholder: + other: Indtast linket til eksisterende spørgsmål + not_a_answer: + name: + other: ikke et svar + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." + no_longer_needed: + name: + other: ikke længere nødvendigt + desc: + other: Denne kommentar er forældet, samtale-agtig eller ikke relevant for dette indlæg. + something: + name: + other: noget andet + desc: + other: Dette indlæg kræver personalets opmærksomhed af en anden grund, som ikke er nævnt ovenfor. + placeholder: + other: Lad os vide specifikt, hvad du er bekymret over + community_specific: + name: + other: en fællesskabsspecifik årsag + desc: + other: Dette spørgsmål opfylder ikke en fællesskabsretningslinje. + not_clarity: + name: + other: kræver detaljer eller klarhed + desc: + other: Dette spørgsmål indeholder i øjeblikket flere spørgsmål i én. Det bør kun fokusere på ét problem. + looks_ok: + name: + other: ser OK ud + desc: + other: Dette indlæg er godt som er og ikke lav kvalitet. + needs_edit: + name: + other: har brug for redigering, og jeg gjorde det + desc: + other: Forbedre og ret selv problemer med dette indlæg. + needs_close: + name: + other: skal lukkes + desc: + other: Et lukket spørgsmål kan ikke besvares, men du kan stadig redigere, stemme og kommentere. + needs_delete: + name: + other: skal slettes + desc: + other: Dette indlæg bliver slettet. + question: + close: + duplicate: + name: + other: spam + desc: + other: Dette spørgsmål er blevet stillet før og har allerede et svar. + guideline: + name: + other: en fællesskabsspecifik årsag + desc: + other: Dette spørgsmål opfylder ikke en fællesskabsretningslinje. + multiple: + name: + other: kræver detaljer eller klarhed + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: noget andet + desc: + other: Dette indlæg kræver en anden grund som ikke er nævnt ovenfor. + operation_type: + asked: + other: spurgt + answered: + other: besvaret + modified: + other: ændret + deleted_title: + other: Slettet spørgsmål + questions_title: + other: Spørgsmål + tag: + tags_title: + other: Tags + no_description: + other: Tag har ingen beskrivelse. + notification: + action: + update_question: + other: opdateret spørgsmål + answer_the_question: + other: besvaret spørgsmål + update_answer: + other: opdateret svar + accept_answer: + other: accepteret svar + comment_question: + other: kommenteret spørgsmål + comment_answer: + other: kommenteret svar + reply_to_you: + other: svarede dig + mention_you: + other: nævnte dig + your_question_is_closed: + other: Dit spørgsmål er blevet lukket + your_question_was_deleted: + other: Dit spørgsmål er blevet slettet + your_answer_was_deleted: + other: Dit svar er blevet slettet + your_comment_was_deleted: + other: Din kommentar er slettet + up_voted_question: + other: op-stemt spørgsmål + down_voted_question: + other: ned-stemt spørgsmål + up_voted_answer: + other: op-stemt svar + down_voted_answer: + other: ned-stemt svar + up_voted_comment: + other: op-stemt kommentar + invited_you_to_answer: + other: inviterede dig til at svare + earned_badge: + other: You've earned the "{{.BadgeName}}" badge + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Bekræft din nye e-mailadresse" + body: + other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} besvarede dit spørgsmål" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} inviterede dig til at svare" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} kommenterede dit indlæg" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_question: + title: + other: "[{{.SiteName}}] Nyt spørgsmål: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Nulstilling af adgangskode" + body: + other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + register: + title: + other: "[{{.SiteName}}] Bekræft din nye konto" + body: + other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + test: + title: + other: "[{{.SiteName}}] Test E-Mail" + body: + other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + action_activity_type: + upvote: + other: stem op + upvoted: + other: stemt op + downvote: + other: stem ned + downvoted: + other: stemt ned + accept: + other: acceptér + accepted: + other: accepteret + edit: + other: rediger + review: + queued_post: + other: Indlæg i kø + flagged_post: + other: Anmeldt indlæg + suggested_post_edit: + other: Foreslåede redigeringer + reaction: + tooltip: + other: "{{ .Names }} og {{ .Count }} mere..." + badge: + default_badges: + autobiographer: + name: + other: Autobiographer + desc: + other: Filled out profile information. + certified: + name: + other: Certified + desc: + other: Completed our new user tutorial. + editor: + name: + other: Editor + desc: + other: First post edit. + first_flag: + name: + other: First Flag + desc: + other: First flagged a post. + first_upvote: + name: + other: First Upvote + desc: + other: First up voted a post. + first_link: + name: + other: First Link + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: First Share + desc: + other: First shared a post. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Leave 5 comments. + new_user_of_the_month: + name: + other: New User of the Month + desc: + other: Outstanding contributions in their first month. + read_guidelines: + name: + other: Read Guidelines + desc: + other: Read the [community guidelines]. + reader: + name: + other: Reader + desc: + other: Read every answers in a topic with more than 10 answers. + welcome: + name: + other: Welcome + desc: + other: Received a up vote. + nice_share: + name: + other: Nice Share + desc: + other: Shared a post with 25 unique visitors. + good_share: + name: + other: Good Share + desc: + other: Shared a post with 300 unique visitors. + great_share: + name: + other: Great Share + desc: + other: Shared a post with 1000 unique visitors. + out_of_love: + name: + other: Out of Love + desc: + other: Used 50 up votes in a day. + higher_love: + name: + other: Higher Love + desc: + other: Used 50 up votes in a day 5 times. + crazy_in_love: + name: + other: Crazy in Love + desc: + other: Used 50 up votes in a day 20 times. + promoter: + name: + other: Promoter + desc: + other: Invited a user. + campaigner: + name: + other: Campaigner + desc: + other: Invited 3 basic users. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: Thank You + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Active member for a year, posted at least once. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Sådan formaterer du + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Forrige + next: Næste + page_title: + question: Spørgsmål + questions: Spørgsmål + tag: Tag + tags: Tags + tag_wiki: tag wiki + create_tag: Opret tag + edit_tag: Rediger tag + ask_a_question: Create Question + edit_question: Rediger spørgsmål + edit_answer: Rediger Svar + search: Søg + posts_containing: Indlæg som indeholder + settings: Indstillinger + notifications: Notifikationer + login: Log Ind + sign_up: Tilmeld dig + account_recovery: Konto-gendannelse + account_activation: Aktivering af konto + confirm_email: Bekræft e-mail + account_suspended: Konto suspenderet + admin: Administrator + change_email: Ændre E-Mail + install: Answer Installation + upgrade: Answer Opgradering + maintenance: Vedligeholdelse af websted + users: Brugere + oauth_callback: Behandler + http_404: HTTP Fejl 404 + http_50X: Http Fejl 500 + http_403: HTTP Fejl 403 + logout: Log Ud + posts: Posts + notifications: + title: Notifikationer + inbox: Indbakke + achievement: Bedrifter + new_alerts: Nye adviseringer + all_read: Markér alle som læst + show_more: Vis mere + someone: Nogen + inbox_type: + all: Alle + posts: Indlæg + invites: Invitationer + votes: Stemmer + answer: Answer + question: Question + badge_award: Badge + suspended: + title: Din konto er blevet suspenderet + until_time: "Din konto blev suspenderet indtil {{ time }}." + forever: Denne bruger blev suspenderet for evigt. + end: Du opfylder ikke en fællesskabsretningslinje. + contact_us: Kontakt os + editor: + blockquote: + text: Citatblok + bold: + text: Fed + chart: + text: Diagram + flow_chart: Flow- diagram + sequence_diagram: Sekvensdiagram + class_diagram: Klassediagram + state_diagram: Tilstands-diagram + entity_relationship_diagram: Enheds-forhold-diagram + user_defined_diagram: Brugerdefineret diagram + gantt_chart: Gantt- diagram + pie_chart: Cirkeldiagram + code: + text: Kode-eksempel + add_code: Tilføj kodeeksempel + form: + fields: + code: + label: Kode + msg: + empty: Kode skal udfyldes. + language: + label: Sprog + placeholder: Automatisk detektering + btn_cancel: Annuller + btn_confirm: Tilføj + formula: + text: Formel + options: + inline: Indlejret formel + block: Formel blok + heading: + text: Overskrift + options: + h1: Overskrift 1 + h2: Overskrift 2 + h3: Overskrift 3 + h4: Overskrift 4 + h5: Overskrift 5 + h6: Overskrift 6 + help: + text: Hjælp + hr: + text: Vandret streg + image: + text: Billede + add_image: Tilføj billede + tab_image: Upload billede + form_image: + fields: + file: + label: Billedfil + btn: Vælg billede + msg: + empty: Filen skal udfyldes. + only_image: Kun billedfiler er tilladt. + max_size: File size cannot exceed {{size}} MB. + desc: + label: Beskriveslse + tab_url: Billede-URL + form_url: + fields: + url: + label: Billede-URL + msg: + empty: Billede-URL skal udfyldes. + name: + label: Beskriveslse + btn_cancel: Annuller + btn_confirm: Tilføj + uploading: Uploader + indent: + text: Indrykning + outdent: + text: Udrykning + italic: + text: Fremhævning + link: + text: Link + add_link: Tilføj link + form: + fields: + url: + label: URL + msg: + empty: URL må ikke være tom. + name: + label: Beskriveslse + btn_cancel: Annuller + btn_confirm: Tilføj + ordered_list: + text: Nummereret liste + unordered_list: + text: Punktliste + table: + text: Tabel + heading: Overskrift + cell: Celle + file: + text: Attach files + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: Jeg lukker dette indlæg fordi... + btn_cancel: Annuller + btn_submit: Indsend + remark: + empty: skal udfyldes. + msg: + empty: Vælg en grund. + report_modal: + flag_title: Jeg markerer for at rapportere dette indlæg som... + close_title: Jeg lukker dette indlæg fordi... + review_question_title: Gennemgå spørgsmål + review_answer_title: Gennemgå svar + review_comment_title: Gennemgå kommentar + btn_cancel: Annuller + btn_submit: Indsend + remark: + empty: skal udfyldes. + msg: + empty: Vælg en grund. + not_a_url: URL-format er forkert. + url_not_match: URL oprindelsen matcher ikke det aktuelle websted. + tag_modal: + title: Opret et nyt tag + form: + fields: + display_name: + label: Visnings-navn + msg: + empty: Visnings-navn skal udfyldes. + range: Visnings-navn på op til 35 tegn. + slug_name: + label: URL-slug + desc: URL slug op til 35 tegn. + msg: + empty: URL slug må ikke være tom. + range: URL slug op til 35 tegn. + character: URL slug indeholder ikke tilladte tegn. + desc: + label: Beskriveslse + revision: + label: Revision + edit_summary: + label: Rediger resumé + placeholder: >- + Forklar kort dine ændringer (korrigeret stavning, fast grammatik, forbedret formatering) + btn_cancel: Annuller + btn_submit: Indsend + btn_post: Send nyt tag + tag_info: + created_at: Oprettet + edited_at: Redigeret + history: Historik + synonyms: + title: Synonymer + text: Følgende tags vil blive genmappet til + empty: Ingen synonymer fundet. + btn_add: Tilføj et synonym + btn_edit: Rediger + btn_save: Gem + synonyms_text: Følgende tags vil blive genmappet til + delete: + title: Slet dette tag + tip_with_posts: >- +

        Vi tillader ikke at slette tag med indlæg.

        Fjern venligst dette tag fra indlæggene først.

        + tip_with_synonyms: >- +

        Vi tillader ikke at slette tag med indlæg.

        Fjern venligst dette tag fra indlæggene først.

        + tip: Er du sikker på, at du vil slette? + close: Luk + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Rediger tag + default_reason: Rediger tag + default_first_reason: Tilføj tag + btn_save_edits: Gem ændringer + btn_cancel: Annuller + dates: + long_date: MMM D + long_date_with_year: "D MMMM, YYYY" + long_date_with_time: "MMM D, ÅÅÅÅ [at] HH:mm" + now: nu + x_seconds_ago: "{{count}}s siden" + x_minutes_ago: "{{count}}s siden" + x_hours_ago: "{{count}}t siden" + hour: time + day: dag + hours: timer + days: dag + month: month + months: months + year: year + reaction: + heart: hjerte + smile: smil + frown: rynke panden + btn_label: tilføj eller fjern reaktioner + undo_emoji: fortryd {{ emoji }} reaktion + react_emoji: reager med {{ emoji }} + unreact_emoji: ikke reager med {{ emoji }} + comment: + btn_add_comment: Tilføj kommentar + reply_to: Svar til + btn_reply: Svar + btn_edit: Rediger + btn_delete: Slet + btn_flag: Anmeld + btn_save_edits: Gem ændringer + btn_cancel: Annuller + show_more: "{{count}} flere kommentarer" + tip_question: >- + Brug kommentarer til at bede om mere information eller foreslå forbedringer. Undgå at besvare spørgsmål i kommentarer. + tip_answer: >- + Brug kommentarer til at svare andre brugere eller give dem besked om ændringer. Hvis du tilføjer nye oplysninger, skal du redigere dit indlæg i stedet for at kommentere. + tip_vote: Det tilføjer noget nyttigt til indlægget + edit_answer: + title: Rediger Svar + default_reason: Rediger svar + default_first_reason: Tilføj svar + form: + fields: + revision: + label: Revision + answer: + label: Svar + feedback: + characters: indhold skal være mindst 6 tegn. + edit_summary: + label: Rediger resumé + placeholder: >- + Forklar kort dine ændringer (korrigeret stavning, fast grammatik, forbedret formatering) + btn_save_edits: Gem ændringer + btn_cancel: Annuller + tags: + title: Tags + sort_buttons: + popular: Populære + name: Navn + newest: Nyeste + button_follow: Følg + button_following: Følger + tag_label: spørgsmål + search_placeholder: Filtrer efter tag-navn + no_desc: Tag har ingen beskrivelse. + more: Mere + wiki: Wiki + ask: + title: Create Question + edit_title: Rediger spørgsmål + default_reason: Rediger spørgsmål + default_first_reason: Create question + similar_questions: Lignende spørgsmål + form: + fields: + revision: + label: Revision + title: + label: Titel + placeholder: What's your topic? Be specific. + msg: + empty: Titel må ikke være tom. + range: Titel på op til 150 tegn + body: + label: Brødtekst + msg: + empty: Brødtekst skal udfyldes. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Tags + msg: + empty: Tags må ikke være tom. + answer: + label: Svar + msg: + empty: Svar må ikke være tomt. + edit_summary: + label: Rediger resumé + placeholder: >- + Forklar kort dine ændringer (korrigeret stavning, fast grammatik, forbedret formatering) + btn_post_question: Indsend dit spørgsmål + btn_save_edits: Gem ændringer + answer_question: Besvar dit eget spørgsmål + post_question&answer: Send dit spørgsmål og svar + tag_selector: + add_btn: Tilføj tag + create_btn: Opret et nyt tag + search_tag: Søg tag + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: Ingen tags matchede + tag_required_text: Påkrævet tag (mindst én) + header: + nav: + question: Spørgsmål + tag: Tags + user: Brugere + badges: Badges + profile: Profil + setting: Indstillinger + logout: Log Ud + admin: Administrator + review: Gennemgå + bookmark: Bogmærker + moderation: Moderering + search: + placeholder: Søg + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Skift + loading: indlæser... + pic_auth_code: + title: Captcha + placeholder: Skriv teksten ovenfor + msg: + empty: Captcha må ikke være tomt. + inactive: + first: >- + Du er næsten færdig! Vi har sendt en aktiveringsmail til {{mail}}. Følg venligst instruktionerne i mailen for at aktivere din konto. + info: "Hvis det ikke ankommer, tjek din spam-mappe." + another: >- + Vi har sendt endnu en aktiverings-e-mail til dig på {{mail}}. Det kan tage nogen få minutter før den når frem; kontrollér også din spam-mappe. + btn_name: Send aktiverings-e-mail igen + change_btn_name: Ændre e-mail + msg: + empty: skal udfyldes. + resend_email: + url_label: Er du sikker på, at du vil sende aktiveringse-mailen? + url_text: Du kan også give aktiveringslinket ovenfor til brugeren. + login: + login_to_continue: Log ind for at fortsætte + info_sign: Har du ikke en konto? <1>Tilmeld dig + info_login: Har du allerede en konto? <1>Log ind + agreements: Ved at registrere dig accepterer du <1>privacy policy og <3>terms of service . + forgot_pass: Glemt adgangskode? + name: + label: Navn + msg: + empty: Navn må ikke være tomt. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: E-mail + msg: + empty: E-mail skal udfyldes. + password: + label: Adgangskode + msg: + empty: Adgangskoden skal udfyldes. + different: De indtastede adgangskoder er ikke ens + account_forgot: + page_title: Glemt adgangskode + btn_name: Send mig gendannelsesmail + send_success: >- + Hvis en konto matcher {{mail}}, vil du modtage en e-mail med instruktioner om, hvordan du nulstiller din adgangskode. + email: + label: E-mail + msg: + empty: E-mail skal udfyldes. + change_email: + btn_cancel: Annuller + btn_update: Opdater e-mailadresse + send_success: >- + Hvis en konto matcher {{mail}}, vil du modtage en e-mail med instruktioner om, hvordan du nulstiller din adgangskode. + email: + label: Ny e-mail + msg: + empty: E-mail skal udfyldes. + oauth: + connect: Forbind med {{ auth_name }} + remove: Fjern {{ auth_name }} + oauth_bind_email: + subtitle: Tilføj en gendannelsese-mail til din konto. + btn_update: Opdater e-mailadresse + email: + label: E-mail + msg: + empty: E-mail skal udfyldes. + modal_title: Email eksisterer allerede. + modal_content: Denne e-mailadresse er allerede registreret. Er du sikker på, at du vil oprette forbindelse til den eksisterende konto? + modal_cancel: Ændre e-mail + modal_confirm: Opret forbindelse til den eksisterende konto + password_reset: + page_title: Nulstil adgangskode + btn_name: Nulstil min adgangskode + reset_success: >- + Du har ændret din adgangskode. Du vil blive omdirigeret til siden log ind. + link_invalid: >- + Beklager, dette link til nulstilling af adgangskode er ikke længere gyldigt. Måske er din adgangskode allerede nulstillet? + to_login: Fortsæt til log-ind siden + password: + label: Adgangskode + msg: + empty: Adgangskoden skal udfyldes. + length: Længden skal være mellem 8 og 32 tegn + different: De indtastede adgangskoder er ikke ens + password_confirm: + label: Bekræft den nye adgangskode + settings: + page_title: Indstillinger + goto_modify: Gå til at ændre + nav: + profile: Profil + notification: Notifikationer + account: Konto + interface: Grænseflade + profile: + heading: Profil + btn_name: Gem + display_name: + label: Visnings-navn + msg: Visnings-navn skal udfyldes. + msg_range: Display name must be 2-30 characters in length. + username: + label: Brugernavn + caption: Man kan nævne dig som "@username". + msg: Brugernavn skal udfyldes. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profilbillede + gravatar: Gravatar + gravatar_text: Du kan ændre billede på + custom: Brugerdefineret + custom_text: Du kan uploade dit billede. + default: System + msg: Upload en avatar + bio: + label: Om mig + website: + label: Websted + placeholder: "https://example.com" + msg: Forkert format på websted + location: + label: Placering + placeholder: "By, land" + notification: + heading: Email-notifikationer + turn_on: Slå til + inbox: + label: Notifikationer i indbakken + description: Svar på dine spørgsmål, kommentarer, invitationer og mere. + all_new_question: + label: Alle nye spørgsmål + description: Få besked om alle nye spørgsmål. Op til 50 spørgsmål om ugen. + all_new_question_for_following_tags: + label: Alle nye spørgsmål til følgende tags + description: Få besked om nye spørgsmål til følgende tags. + account: + heading: Konto + change_email_btn: Ændre e-mail + change_pass_btn: Skift adgangskode + change_email_info: >- + Vi har sendt en e-mail til denne adresse. Følg venligst bekræftelsesinstruktionerne. + email: + label: E-mail + new_email: + label: Ny e-mail + msg: Ny e-mail skal udfyldes. + pass: + label: Nuværende adgangskode + msg: Adgangskoden skal udfyldes. + password_title: Adgangskode + current_pass: + label: Nuværende adgangskode + msg: + empty: Nuværende adgangskode skal udfyldes. + length: Længden skal være mellem 8 og 32 tegn. + different: De to indtastede adgangskoder er ikke ens. + new_pass: + label: Ny adgangskode + pass_confirm: + label: Bekræft den nye adgangskode + interface: + heading: Grænseflade + lang: + label: Grænseflade sprog + text: Brugergrænseflade sprog. Det vil ændres, når du opdaterer siden. + my_logins: + title: Mine log ind + label: Log ind eller tilmeld dig på dette websted ved hjælp af disse konti. + modal_title: Fjern login + modal_content: Er du sikker på, at du vil fjerne dette login fra din konto? + modal_confirm_btn: Slet + remove_success: Fjernet + toast: + update: opdatering gennemført + update_password: Adgangskoden er ændret. + flag_success: Tak for at anmelde. + forbidden_operate_self: Forbudt at operere på dig selv + review: Din revision vil blive vist efter gennemgang. + sent_success: Sendt + related_question: + title: Related + answers: svar + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Inviter personer + desc: Invitér personer, som du tror, kan svare. + invite: Inviter til at svare + add: Tilføj personer + search: Søg personer + question_detail: + action: Handling + created: Created + Asked: Spurgt + asked: spurgt + update: Ændret + Edited: Edited + edit: redigeret + commented: kommenteret + Views: Set + Follow: Følg + Following: Følger + follow_tip: Følg dette spørgsmål for at modtage notifikationer + answered: besvaret + closed_in: Lukket om + show_exist: Vis eksisterende spørgsmål. + useful: Nyttigt + question_useful: Det er nyttigt og klart + question_un_useful: Det er uklart eller ikke nyttigt + question_bookmark: Bogmærk dette spørgsmål + answer_useful: Det er nyttigt + answer_un_useful: Det er ikke nyttigt + answers: + title: Svar + score: Bedømmelse + newest: Nyeste + oldest: Ældste + btn_accept: Acceptér + btn_accepted: Accepteret + write_answer: + title: Dit Svar + edit_answer: Redigér mit eksisterende svar + btn_name: Indsend dit svar + add_another_answer: Tilføj endnu et svar + confirm_title: Fortsæt med at svare + continue: Forsæt + confirm_info: >- +

        Er du sikker på, at du vil tilføje et andet svar?

        Du kan i stedet bruge redigeringslinket til at forfine og forbedre dit eksisterende svar.

        + empty: Svar skal udfyldes. + characters: indhold skal være mindst 6 tegn. + tips: + header_1: Tak for dit svar + li1_1: Vær sikker på at besvare spørgsmålet. Giv oplysninger og del din forskning. + li1_2: Begrund eventuelle udsagn med referencer eller personlige erfaringer. + header_2: Men undgå... + li2_1: Spørger om hjælp, søger afklaring, eller reagerer på andre svar. + reopen: + confirm_btn: Genåbn + title: Genåbn dette indlæg + content: Er du sikker på, at du vil genåbne? + list: + confirm_btn: Liste + title: Sæt dette indlæg på listen + content: Er du sikker på du vil sætte på listen? + unlist: + confirm_btn: Fjern fra listen + title: Fjern dette indlæg fra listen + content: Er du sikker på at du vil fjerne fra listen? + pin: + title: Fastgør dette indlæg + content: Er du sikker på, at du ønsker at fastgøre globalt? Dette indlæg vises øverst på alle indlægs-lister. + confirm_btn: Fastgør + delete: + title: Slet dette indlæg + question: >- + Vi anbefaler ikke, at sletter spørgsmål med svar, fordi det fratager fremtidige læsere denne viden.

        Gentaget sletning af besvarede spørgsmål kan resultere i, at din konto bliver blokeret fra at spørge. Er du sikker på, at du ønsker at slette? + answer_accepted: >- +

        Vi anbefaler ikke at slette accepteret svar fordi det fratager fremtidige læsere denne viden.

        Gentagen sletning af accepterede svar kan resultere i, at din konto bliver blokeret fra besvarelse. Er du sikker på, at du ønsker at slette? + other: Er du sikker på, at du vil slette? + tip_answer_deleted: Dette svar er blevet slettet + undelete_title: Genopret dette indlæg + undelete_desc: Er du sikker på du ønsker at genoprette? + btns: + confirm: Bekræft + cancel: Annuller + edit: Rediger + save: Gem + delete: Slet + undelete: Genopret + list: Sæt på liste + unlist: Fjern fra liste + unlisted: Fjernet fra liste + login: Log ind + signup: Opret konto + logout: Log Ud + verify: Verificér + create: Create + approve: Godkend + reject: Afvis + skip: Spring Over + discard_draft: Kassér udkast + pinned: Fastgjort + all: Alle + question: Spørgsmål + answer: Svar + comment: Kommentar + refresh: Genopfrisk + resend: Send igen + deactivate: Deaktiver + active: Aktiv + suspend: Suspendér + unsuspend: Ophæv suspendering + close: Luk + reopen: Genåbn + ok: Ok + light: Lys + dark: Mørk + system_setting: Systemindstilling + default: Standard + reset: Nulstil + tag: Tag + post_lowercase: indlæg + filter: Filtrer + ignore: Ignorér + submit: Indsend + normal: Normal + closed: Lukket + deleted: Slettet + deleted_permanently: Deleted permanently + pending: Ventende + more: Mere + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Søgeresultater + keywords: Nøgleord + options: Muligheder + follow: Følg + following: Følger + counts: "{{count}} Resultater" + counts_loading: "... Results" + more: Mere + sort_btns: + relevance: Relevans + newest: Nyeste + active: Aktiv + score: Bedømmelse + more: Mere + tips: + title: Avancerede Søgetips + tag: "<1>[tag] søgning med et tag" + user: "<1>user:username søgning efter forfatter" + answer: "<1>answers:0 ubesvarede spørgsmål" + score: "<1>score:3 indlæg med 3+ score" + question: "<1>is:question søgespørgsmål" + is_answer: "<1>is:answer søgesvar" + empty: Vi kunne ikke finde noget.
        Prøv forskellige eller mindre specifikke søgeord. + share: + name: Del + copy: Kopiér link + via: Del indlæg via... + copied: Kopieret + facebook: Del på Facebook + twitter: Share to X + cannot_vote_for_self: Du kan ikke stemme på dit eget indlæg. + modal_confirm: + title: Fejl... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Din nye konto er bekræftet. Du vil blive omdirigeret til hjemmesiden. + link: Fortsæt til startside + oops: Hovsa! + invalid: Linket, du brugte, virker ikke længere. + confirm_new_email: Din e-mail er blevet opdateret. + confirm_new_email_invalid: >- + Beklager, dette bekræftelseslink er ikke længere gyldigt. Måske blev din e-mail allerede ændret? + unsubscribe: + page_title: Afmeld + success_title: Afmelding Lykkedes + success_desc: Du er blevet fjernet fra denne abonnentliste og vil ikke modtage yderligere e-mails fra os. + link: Skift indstillinger + question: + following_tags: Følger Tags + edit: Rediger + save: Gem + follow_tag_tip: Følg tags for at udvælge dine spørgsmål. + hot_questions: Populære Spørgsmål + all_questions: Alle Spørgsmål + x_questions: "{{ count }} Spørgsmål" + x_answers: "{{ count }} svar" + x_posts: "{{ count }} Posts" + questions: Spørgsmål + answers: Svar + newest: Nyeste + active: Aktiv + hot: Populært + frequent: Frequent + recommend: Recommend + score: Bedømmelse + unanswered: Ubesvaret + modified: ændret + answered: besvaret + asked: spurgt + closed: lukket + follow_a_tag: Følg et tag + more: Mere + personal: + overview: Oversigt + answers: Svar + answer: svar + questions: Spørgsmål + question: spørgsmål + bookmarks: Bogmærker + reputation: Omdømme + comments: Kommentarer + votes: Stemmer + badges: Badges + newest: Nyeste + score: Bedømmelse + edit_profile: Rediger profil + visited_x_days: "Besøgte {{ count }} dage" + viewed: Set + joined: Tilmeldt + comma: "," + last_login: Set + about_me: Om Mig + about_me_empty: "// Hej, Verden!" + top_answers: Populære Svar + top_questions: Populære Spørgsmål + stats: Statistik + list_empty: Ingen indlæg fundet.
        Måske vil du vælge en anden fane? + content_empty: No posts found. + accepted: Accepteret + answered: besvaret + asked: spurgt + downvoted: nedstemt + mod_short: MOD + mod_long: Moderatorer + x_reputation: omdømme + x_votes: stemmer modtaget + x_answers: svar + x_questions: spørgsmål + recent_badges: Recent Badges + install: + title: Installation + next: Næste + done: Udført + config_yaml_error: Kan ikke oprette filen config.yaml. + lang: + label: Vælg et sprog + db_type: + label: Database type + db_username: + label: Brugernavn + placeholder: rod + msg: Brugernavn skal udfyldes. + db_password: + label: Adgangskode + placeholder: rod + msg: Adgangskoden skal udfyldes. + db_host: + label: Database host + placeholder: "db:3306" + msg: Database host skal udfyldes. + db_name: + label: Database navn + placeholder: answer + msg: Databasenavn skal udfyldes. + db_file: + label: Databasefil + placeholder: /data/answer.db + msg: Databasefil skal udfyldes. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Opret config.yaml + label: Filen config.yaml blev oprettet. + desc: >- + Du kan manuelt oprette filen <1>config.yaml i mappen <1>/var/wwww/xxx/ og indsætte følgende tekst i den. + info: Når du har gjort det, skal du klikke på "Næste" knappen. + site_information: Websted Information + admin_account: Administrator Konto + site_name: + label: Websted navn + msg: Websted-navn skal udfyldes. + msg_max_length: Webstedsnavn kan ikke være længere end 30 tegn. + site_url: + label: Websted URL + text: Adressen på dit websted. + msg: + empty: Webstedets URL skal udfyldes. + incorrect: Websteds URL forkert format. + max_length: WebstedsURL skal højst være 512 tegn. + contact_email: + label: Kontakt e-mail + text: E-mailadresse på nøglekontakt ansvarlig for dette websted. + msg: + empty: Kontakt-e-mail skal udfyldes. + incorrect: Ugyldig kontakt e-mail adresse. + login_required: + label: Privat + switch: Log ind påkrævet + text: Kun brugere som er logget ind har adgang til dette fællesskab. + admin_name: + label: Navn + msg: Navn skal udfyldes. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Adgangskode + text: >- + Du skal bruge denne adgangskode for at logge ind. Opbevar den et sikkert sted. + msg: Adgangskoden skal udfyldes. + msg_min_length: Adgangskoden skal være mindst 8 tegn. + msg_max_length: Adgangskoden skal højst udgøre 32 tegn. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: E-mail + text: Du skal bruge denne e-mail for at logge ind. + msg: + empty: E-mail skal udfyldes. + incorrect: Ugyldig e-mail adresse. + ready_title: Dit websted er klar + ready_desc: >- + Hvis du nogensinde har lyst til at ændre flere indstillinger, kan du besøge <1>admin-sektion; find det i site-menuen. + good_luck: "Hav det sjovt, og held og lykke!" + warn_title: Advarsel + warn_desc: >- + Filen <1>config.yaml findes allerede. Hvis du har brug for at nulstille en af konfigurationselementerne i denne fil, så slet den først. + install_now: Du kan prøve <1>at installere nu. + installed: Allerede installeret + installed_desc: >- + Du synes allerede at være installeret. For at geninstallere skal du først rydde dine gamle databasetabeller. + db_failed: Database forbindelse mislykkedes + db_failed_desc: >- + Det betyder enten, at databaseinformationen i din <1>config. aml fil er forkert eller at kontakt med databaseserveren ikke kunne etableres. Dette kan betyde, at din værts databaseserver er nede. + counts: + views: visninger + votes: stemmer + answers: svar + accepted: Accepteret + page_error: + http_error: HTTP Fejl {{ code }} + desc_403: Du har ikke adgang til denne side. + desc_404: Denne side findes desværre ikke. + desc_50X: Der skete en fejl på serveren og den kunne ikke fuldføre din anmodning. + back_home: Tilbage til forsiden + page_maintenance: + desc: "Vi laver vedligeholdelse, men er snart tilbage igen." + nav_menus: + dashboard: Kontrolpanel + contents: Indhold + questions: Spørgsmål + answers: Svar + users: Brugere + badges: Badges + flags: Anmeldelser + settings: Indstillinger + general: Generelt + interface: Brugerflade + smtp: SMTP + branding: Branding + legal: Jura + write: Skriv + terms: Terms + tos: Betingelser for brug + privacy: Privatliv + seo: SEO + customize: Tilpas + themes: Temaer + login: Log Ind + privileges: Rettigheder + plugins: Plugins + installed_plugins: Installerede Plugins + apperance: Appearance + website_welcome: Velkommen til {{site_name}} + user_center: + login: Log Ind + qrcode_login_tip: Brug {{ agentName }} til at scanne QR-koden og logge ind. + login_failed_email_tip: Log ind mislykkedes, tillad denne app at få adgang til dine e-mail-oplysninger, før du prøver igen. + badges: + modal: + title: Congratulations + content: You've earned a new badge. + close: Close + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + admin: + admin_header: + title: Administrator + dashboard: + title: Kontrolpanel + welcome: Velkommen til Administration! + site_statistics: Statistik for webstedet + questions: "Spørgsmål:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "Svar:" + comments: "Kommentarer:" + votes: "Stemmer:" + users: "Brugere:" + flags: "Anmeldelser:" + reviews: "Gennemgange:" + site_health: Websteds sundhed + version: "Version:" + https: "HTTPS:" + upload_folder: "Upload mappe:" + run_mode: "Kørselstilstand:" + private: Privat + public: Offentlig + smtp: "SMTP:" + timezone: "Tidszone:" + system_info: System information + go_version: "Go version:" + database: "Database:" + database_size: "Database størrelse:" + storage_used: "Anvendt lagerplads:" + uptime: "Oppetid:" + links: Links + plugins: Plugins + github: GitHub + blog: Blog + contact: Kontakt os + forum: Forum + documents: Dokumenter + feedback: Tilbagemelding + support: Support + review: Gennemgå + config: Konfiguration + update_to: Opdatér til + latest: Seneste + check_failed: Tjek mislykkedes + "yes": "Ja" + "no": "Nej" + not_allowed: Ikke tilladt + allowed: Tilladt + enabled: Aktiveret + disabled: Deaktiveret + writable: Skrivbar + not_writable: Ikke skrivbar + flags: + title: Anmeldelser + pending: Ventende + completed: Gennemført + flagged: Anmeldt + flagged_type: Anmeldt{{ type }} + created: Oprettet + action: Handling + review: Gennemgå + user_role_modal: + title: Skift brugerrolle til... + btn_cancel: Annuller + btn_submit: Indsend + new_password_modal: + title: Angiv ny adgangskode + form: + fields: + password: + label: Adgangskode + text: Brugeren vil blive logget ud og skal logge ind igen. + msg: Adgangskoden skal være på 8- 32 tegn. + btn_cancel: Annuller + btn_submit: Indsend + edit_profile_modal: + title: Rediger profil + form: + fields: + display_name: + label: Visnings-navn + msg_range: Display name must be 2-30 characters in length. + username: + label: Brugernavn + msg_range: Username must be 2-30 characters in length. + email: + label: E-mail + msg_invalid: Ugyldig E-Mail Adresse. + edit_success: Redigering lykkedes + btn_cancel: Annuller + btn_submit: Indsend + user_modal: + title: Tilføj ny bruger + form: + fields: + users: + label: Masse-tilføj bruger + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Adskil “navn, e-mail, adgangskode” med kommaer. Én bruger pr. linje. + msg: "Indtast venligst brugerens e-mail, en pr. linje." + display_name: + label: Visnings-navn + msg: Display name must be 2-30 characters in length. + email: + label: E-mail + msg: E-mail er ugyldig. + password: + label: Adgangskode + msg: Adgangskoden skal være 8- 32 tegn. + btn_cancel: Annuller + btn_submit: Indsend + users: + title: Brugere + name: Navn + email: E-mail + reputation: Omdømme + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Status + role: Rolle + action: Handling + change: Ændre + all: Alle + staff: Ansatte + more: Mere + inactive: Inaktiv + suspended: Suspenderet + deleted: Slettet + normal: Normal + Moderator: Moderator + Admin: Administrator + User: Bruger + filter: + placeholder: "Filtrer efter navn, user:id" + set_new_password: Angiv ny adgangskode + edit_profile: Rediger profil + change_status: Ændre status + change_role: Ændre rolle + show_logs: Vis logfiler + add_user: Tilføj bruger + deactivate_user: + title: Deaktiver bruger + content: En inaktiv bruger skal bekræfte deres e-mail igen. + delete_user: + title: Slet denne bruger + content: Er du sikker på, at du vil slette denne bruger? Dette er permanent! + remove: Fjern deres indhold + label: Fjern alle spørgsmål, svar, kommentarer osv. + text: Tjek ikke dette, hvis du kun ønsker at slette brugerens konto. + suspend_user: + title: Suspendér denne bruger + content: En suspenderet bruger kan ikke logge ind. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Spørgsmål + unlisted: Fjernet fra liste + post: Indlæg + votes: Stemmer + answers: Svar + created: Oprettet + status: Status + action: Handling + change: Ændre + pending: Ventende + filter: + placeholder: "Filtrer efter titel, question:id" + answers: + page_title: Svar + post: Indlæg + votes: Stemmer + created: Oprettet + status: Status + action: Handling + change: Ændre + filter: + placeholder: "Filtrer efter titel, answer:id" + general: + page_title: Generelt + name: + label: Websted navn + msg: Websted-navn skal udfyldes. + text: "Navnet på dette websted, som bruges i title-tagget." + site_url: + label: Websted URL + msg: Websted-URL skal udfyldes. + validate: Angiv et gyldigt URL. + text: Adressen på dit websted. + short_desc: + label: Kort beskrivelse af websted + msg: Kort beskrivelse af websted skal udfyldes. + text: "Kort beskrivelse, som anvendt i title-tag på hjemmesiden." + desc: + label: Websted beskrivelse + msg: Webstedsbeskrivelse skal udfyldes. + text: "Beskriv dette websted i en sætning, som bruges i meta description tagget." + contact_email: + label: Kontakt e-mail + msg: Kontakt-e-mail skal udfyldes. + validate: Kontakt-e-mail er ugyldig. + text: E-mailadresse på nøglekontakt ansvarlig for dette websted. + check_update: + label: Opdatering af software + text: Søg automatisk efter opdateringer + interface: + page_title: Brugerflade + language: + label: Brugerflade sprog + msg: Brugerflade-sprog skal udfyldes. + text: Brugergrænseflade sprog. Det vil ændres, når du opdaterer siden. + time_zone: + label: Tidszone + msg: Tidszone skal udfyldes. + text: Vælg en by i samme tidszone som dig selv. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: Fra e-mail + msg: Fra e-mail skal udfyldes. + text: E-mail-adressen som e-mails sendes fra. + from_name: + label: Fra navn + msg: Fra navn skal udfyldes. + text: Navnet som e-mails sendes fra. + smtp_host: + label: SMTP host + msg: SMTP host skal udfyldes. + text: Din mail-server. + encryption: + label: Kryptering + msg: Kryptering skal udfyldes. + text: For de fleste servere er SSL den anbefalede indstilling. + ssl: SSL + tls: TLS + none: Ingen + smtp_port: + label: SMTP port + msg: SMTP port skal være nummer 1 ~ 65535. + text: Porten til din mailserver. + smtp_username: + label: SMTP brugernavn + msg: SMTP brugernavn skal udfyldes. + smtp_password: + label: SMTP adgangskode + msg: SMTP adgangskode skal udfyldes. + test_email_recipient: + label: Test e-mail modtagere + text: Angiv e-mail-adresse, der vil modtage test-beskedder. + msg: Test e-mail modtagere er ugyldige + smtp_authentication: + label: Aktiver autentificering + title: SMTP autentificering + msg: SMTP autentificering skal udfyldes. + "yes": "Ja" + "no": "Nej" + branding: + page_title: Branding + logo: + label: Logo + msg: Logo skal udfyldes. + text: Logoet billede øverst til venstre på dit websted. Brug et bredt rektangulært billede med en højde på 56 og et breddeforhold større end 3:1. Hvis efterladt tom, vil webstedets titeltekst blive vist. + mobile_logo: + label: Mobil logo + text: Logoet bruges på mobile version af dit websted. Brug et bredt rektangulært billede med en højde på 56. Hvis efterladt tom, vil billedet fra indstillingen "logo" blive brugt. + square_icon: + label: Kvadratisk ikon + msg: Kvadratisk ikon skal udfyldes. + text: Billede brugt som basis for metadata-ikoner. Bør være større end 512x512. + favicon: + label: Favicon + text: En favicon til dit websted. For at fungere korrekt over en CDN skal det være en png. Vil blive ændret til 32x32. Hvis efterladt tomt, vil "firkantet ikon" blive brugt. + legal: + page_title: Jura + terms_of_service: + label: Betingelser for brug + text: "Du kan tilføje servicevilkår her. Hvis du allerede har et dokument hostet et andet sted, så angiv den fulde URL her." + privacy_policy: + label: Privatlivspolitik + text: "Du kan tilføje privatlivspolitik indhold her. Hvis du allerede har et dokument hostet et andet sted, så angiv den fulde URL her." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Skriv + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Skriv svar + label: Hver bruger kan kun skrive et svar for det samme spørgsmål + text: "Slå fra for at give brugerne mulighed for at skrive flere svar på det samme spørgsmål, hvilket kan forårsage svar at være ufokuseret." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Anbefal tags + text: "Anbefal tags vil som standard blive vist i dropdown-listen." + msg: + contain_reserved: "anbefalede tags kan ikke indeholde reserverede tags" + required_tag: + title: Angiv påkrævede tags + label: Sæt “Anbefal tags” som påkrævede tags + text: "Hvert nyt spørgsmål skal have mindst et anbefalet tag." + reserved_tags: + label: Reserverede tags + text: "Reserverede tags kan kun bruges af moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: SEO + permalink: + label: Permalink + text: Brugerdefinerede URL-strukturer kan forbedre brugervenlighed og fremadrettet kompatibilitet af dine links. + robots: + label: robots.txt + text: Dette vil permanent tilsidesætte eventuelle relaterede webstedsindstillinger. + themes: + page_title: Temaer + themes: + label: Temaer + text: Vælg et eksisterende tema. + color_scheme: + label: Farveskema + navbar_style: + label: Navbar background style + primary_color: + label: Primær farve + text: Ændre farver, der bruges af dine temaer + css_and_html: + page_title: CSS og HTML + custom_css: + label: Brugerdefineret CSS + text: > + + head: + label: Head + text: > + + header: + label: Overskrift + text: > + + footer: + label: Sidefod + text: Dette indsættes før </body>. + sidebar: + label: Sidebjælke + text: Dette vil indsætte i sidebjælken. + login: + page_title: Log Ind + membership: + title: Medlemskab + label: Tillad nye registreringer + text: Slå fra for at forhindre at nogen opretter en ny konto. + email_registration: + title: E-mail-registrering + label: Tillad e-mail registrering + text: Slå fra for at forhindre, at der oprettes en ny konto via e-mail. + allowed_email_domains: + title: Tilladte e-mail-domæner + text: E-mail-domæner som brugere skal registrere konti med. Et domæne pr. linje. Ignoreres når tomt. + private: + title: Privat + label: Log ind påkrævet + text: Kun brugere som er logget ind har adgang til dette fællesskab. + password_login: + title: Adgangskode log ind + label: Tillad e-mail og adgangskode login + text: "ADVARSEL: Hvis du slår fra, kan du muligvis ikke logge ind, hvis du ikke tidligere har konfigureret en anden loginmetode." + installed_plugins: + title: Installerede Plugins + plugin_link: Plugins udvider og udvider funktionaliteten. Du kan finde plugins i <1>Plugin Repository. + filter: + all: Alle + active: Aktiv + inactive: Inaktiv + outdated: Forældet + plugins: + label: Plugins + text: Vælg et eksisterende plugin. + name: Navn + version: Version + status: Status + action: Handling + deactivate: Deaktiver + activate: Aktivér + settings: Indstillinger + settings_users: + title: Brugere + avatar: + label: Standard avatar + text: For brugere uden en brugerdefineret avatar. + gravatar_base_url: + label: Gravatar base-URL + text: URL for Gravatar-udbyderens API-base. Ignoreres når tom. + profile_editable: + title: Profil redigerbar + allow_update_display_name: + label: Tillad brugere at ændre deres visningsnavn + allow_update_username: + label: Tillad brugere at ændre deres brugernavn + allow_update_avatar: + label: Tillad brugere at ændre deres profilbillede + allow_update_bio: + label: Tillad brugere at ændre deres om-mig + allow_update_website: + label: Tillad brugere at ændre deres hjemmeside + allow_update_location: + label: Tillad brugere at ændre deres placering + privilege: + title: Rettigheder + level: + label: Omdømme påkrævet niveau + text: Vælg det omdømme der kræves for rettighederne + msg: + should_be_number: input skal være et tal + number_larger_1: tal skal være lig med eller større end 1 + badges: + action: Action + active: Active + activate: Activate + all: All + awards: Awards + deactivate: Deactivate + filter: + placeholder: Filter by name, badge:id + group: Group + inactive: Inactive + name: Name + show_logs: Show logs + status: Status + title: Badges + form: + optional: (valgfrit) + empty: skal udfyldes + invalid: er ugyldigt + btn_submit: Gem + not_found_props: "Nødvendig egenskab {{ key }} ikke fundet." + select: Vælg + page_review: + review: Gennemgå + proposed: foreslået + question_edit: Rediger spørgsmål + answer_edit: Svar redigér + tag_edit: Tag redigér + edit_summary: Rediger resumé + edit_question: Rediger spørgsmål + edit_answer: Rediger svar + edit_tag: Rediger tag + empty: Ingen gennemgangsopgaver tilbage. + approve_revision_tip: Godkender du denne revision? + approve_flag_tip: Godkender du denne anmeldelse? + approve_post_tip: Godkender du dette indlæg? + approve_user_tip: Godkender du denne bruger? + suggest_edits: Foreslåede redigeringer + flag_post: Anmeld indlæg + flag_user: Anmeld bruger + queued_post: Indlæg i kø + queued_user: Brugere i kø + filter_label: Type + reputation: omdømme + flag_post_type: Anmeld dette indlæg som {{ type }}. + flag_user_type: Anmeldte dette indlæg som {{ type }}. + edit_post: Rediger opslag + list_post: Sæt indlæg på liste + unlist_post: Fjern indlæg fra liste + timeline: + undeleted: genskabt + deleted: slettet + downvote: stem ned + upvote: stem op + accept: acceptér + cancelled: annulleret + commented: kommenteret + rollback: tilbagerul + edited: redigeret + answered: besvaret + asked: spurgt + closed: lukket + reopened: genåbnet + created: oprettet + pin: fastgjort + unpin: frigjort + show: sat på liste + hide: fjernet fra liste + title: "Historik for" + tag_title: "Tidslinje for" + show_votes: "Vis stemmer" + n_or_a: Ikke Relevant + title_for_question: "Tidslinje for" + title_for_answer: "Tidslinje for svar på {{ title }} af {{ author }}" + title_for_tag: "Tidslinje for tag" + datetime: Datetime + type: Type + by: Af + comment: Kommentar + no_data: "Vi kunne ikke finde noget." + users: + title: Brugere + users_with_the_most_reputation: Brugere med det højeste omdømme scorer denne uge + users_with_the_most_vote: Brugere, der stemte mest i denne uge + staffs: Vores fællesskabs personale + reputation: omdømme + votes: stemmer + prompt: + leave_page: Er du sikker på, at du vil forlade siden? + changes_not_save: Dine ændringer er muligvis ikke gemt. + draft: + discard_confirm: Er du sikker på, at du vil kassere dit udkast? + messages: + post_deleted: Dette indlæg er blevet slettet. + post_cancel_deleted: This post has been undeleted. + post_pin: Dette indlæg er blevet fastgjort. + post_unpin: Dette indlæg er blevet frigjort. + post_hide_list: Dette indlæg er blevet skjult fra listen. + post_show_list: Dette indlæg er blevet vist på listen. + post_reopen: Dette indlæg er blevet genåbnet. + post_list: Dette indlæg er blevet listet. + post_unlist: Dette indlæg er blevet aflistet. + post_pending: Dit indlæg afventer gennemgang. Dette er en forhåndsvisning, det vil være synligt, når det er blevet godkendt. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/de_DE.yaml b/data/i18n/de_DE.yaml new file mode 100644 index 000000000..3e89b8d16 --- /dev/null +++ b/data/i18n/de_DE.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Erfolgreich. + unknown: + other: Unbekannter Fehler. + request_format_error: + other: Format der Anfrage ist ungültig. + unauthorized_error: + other: Nicht autorisiert. + database_error: + other: Datenbank-Fehler. + forbidden_error: + other: Verboten. + duplicate_request_error: + other: Doppelte Einreichung. + action: + report: + other: Melden + edit: + other: Bearbeiten + delete: + other: Löschen + close: + other: Schließen + reopen: + other: Wieder öffnen + forbidden_error: + other: Verboten. + pin: + other: Anpinnen + hide: + other: Von Liste nehmen + unpin: + other: Loslösen + show: + other: Liste + invite_someone_to_answer: + other: Bearbeiten + undelete: + other: Wiederherstellen + merge: + other: Zusammenführen + role: + name: + user: + other: Benutzer + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Standard ohne speziellen Zugriff. + admin: + other: Habe die volle Berechtigung, auf die Seite zuzugreifen. + moderator: + other: Hat Zugriff auf alle Beiträge außer Admin-Einstellungen. + privilege: + level_1: + description: + other: Level 1 (weniger Reputation für privates Team, Gruppen) + level_2: + description: + other: Level 2 (niedrige Reputation für Startup-Community) + level_3: + description: + other: Level 3 (hohe Reputation für eine reife Community) + level_custom: + description: + other: Benutzerdefinierter Level + rank_question_add_label: + other: Fragen stellen + rank_answer_add_label: + other: Antwort schreiben + rank_comment_add_label: + other: Kommentar schreiben + rank_report_add_label: + other: Melden + rank_comment_vote_up_label: + other: Kommentar upvoten + rank_link_url_limit_label: + other: Mehr als 2 Links gleichzeitig posten + rank_question_vote_up_label: + other: Frage upvoten + rank_answer_vote_up_label: + other: Antwort upvoten + rank_question_vote_down_label: + other: Frage downvoten + rank_answer_vote_down_label: + other: Antwort downvoten + rank_invite_someone_to_answer_label: + other: Jemanden zum Antworten einladen + rank_tag_add_label: + other: Neuen Tag erstellen + rank_tag_edit_label: + other: Tag-Beschreibung bearbeiten (muss überprüft werden) + rank_question_edit_label: + other: Frage eines anderen bearbeiten (muss überarbeitet werden) + rank_answer_edit_label: + other: Antwort eines anderen bearbeiten (muss überarbeitet werden) + rank_question_edit_without_review_label: + other: Frage eines anderen ohne Überprüfung bearbeiten + rank_answer_edit_without_review_label: + other: Antwort eines anderen ohne Überprüfung bearbeiten + rank_question_audit_label: + other: Frageänderungen überprüfen + rank_answer_audit_label: + other: Bearbeitete Antworten überprüfen + rank_tag_audit_label: + other: Tag-Bearbeitungen überprüfen + rank_tag_edit_without_review_label: + other: Tag-Beschreibung ohne Überprüfung bearbeiten + rank_tag_synonym_label: + other: Tag-Synonyme verwalten + email: + other: E-Mail + e_mail: + other: E-Mail + password: + other: Passwort + pass: + other: Passwort + old_pass: + other: Aktuelles Passwort + original_text: + other: Dieser Beitrag + email_or_password_wrong_error: + other: E-Mail und Passwort stimmen nicht überein. + error: + common: + invalid_url: + other: Ungültige URL. + status_invalid: + other: Ungültiger Status. + password: + space_invalid: + other: Passwort darf keine Leerzeichen enthalten. + admin: + cannot_update_their_password: + other: Du kannst dein Passwort nicht ändern. + cannot_edit_their_profile: + other: Du kannst dein Profil nicht bearbeiten. + cannot_modify_self_status: + other: Du kannst deinen Status nicht ändern. + email_or_password_wrong: + other: E-Mail und Password stimmen nicht überein. + answer: + not_found: + other: Antwort nicht gefunden. + cannot_deleted: + other: Keine Berechtigung zum Löschen. + cannot_update: + other: Keine Berechtigung zum Aktualisieren. + question_closed_cannot_add: + other: Fragen sind geschlossen und können nicht hinzugefügt werden. + content_cannot_empty: + other: Die Antwort darf nicht leer sein. + comment: + edit_without_permission: + other: Kommentar kann nicht bearbeitet werden. + not_found: + other: Kommentar wurde nicht gefunden. + cannot_edit_after_deadline: + other: Die Kommentarzeit war zu lang, um sie zu ändern. + content_cannot_empty: + other: Der Kommentar darf nicht leer sein. + email: + duplicate: + other: E-Mail existiert bereits. + need_to_be_verified: + other: E-Mail muss überprüft werden. + verify_url_expired: + other: Die verifizierbare E-Mail-URL ist abgelaufen, bitte sende die E-Mail erneut. + illegal_email_domain_error: + other: E-Mails sind von dieser E-Mail-Domäne nicht erlaubt. Bitte verwende eine andere. + lang: + not_found: + other: Sprachdatei nicht gefunden. + object: + captcha_verification_failed: + other: Captcha ist falsch. + disallow_follow: + other: Es ist dir nicht erlaubt zu folgen. + disallow_vote: + other: Es ist dir nicht erlaubt abzustimmen. + disallow_vote_your_self: + other: Du kannst nicht für deinen eigenen Beitrag stimmen. + not_found: + other: Objekt nicht gefunden. + verification_failed: + other: Verifizierung fehlgeschlagen. + email_or_password_incorrect: + other: E-Mail und Passwort stimmen nicht überein. + old_password_verification_failed: + other: Die Überprüfung des alten Passworts ist fehlgeschlagen + new_password_same_as_previous_setting: + other: Das neue Passwort ist das gleiche wie das vorherige Passwort. + already_deleted: + other: Dieser Beitrag wurde gelöscht. + meta: + object_not_found: + other: Metaobjekt nicht gefunden + question: + already_deleted: + other: Dieser Beitrag wurde gelöscht. + under_review: + other: Ihr Beitrag wartet auf Überprüfung. Er wird sichtbar sein, nachdem er genehmigt wurde. + not_found: + other: Frage nicht gefunden. + cannot_deleted: + other: Keine Berechtigung zum Löschen. + cannot_close: + other: Keine Berechtigung zum Schließen. + cannot_update: + other: Keine Berechtigung zum Aktualisieren. + content_cannot_empty: + other: Der Inhalt darf nicht leer sein. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Ansehenssrang erfüllt die Bedingung nicht. + vote_fail_to_meet_the_condition: + other: Danke für dein Feedback. Du brauchst mindestens {{.Rank}} Ansehen, um eine Stimme abzugeben. + no_enough_rank_to_operate: + other: Dafür brauchst du mindestens {{.Rank}} Ansehen. + report: + handle_failed: + other: Bearbeiten der Meldung fehlgeschlagen. + not_found: + other: Meldung nicht gefunden. + tag: + already_exist: + other: Tag existiert bereits. + not_found: + other: Tag nicht gefunden. + recommend_tag_not_found: + other: Das Tag "Empfehlen" ist nicht vorhanden. + recommend_tag_enter: + other: Bitte gib mindestens einen erforderlichen Tag ein. + not_contain_synonym_tags: + other: Sollte keine Synonym-Tags enthalten. + cannot_update: + other: Keine Berechtigung zum Aktualisieren. + is_used_cannot_delete: + other: Du kannst keinen Tag löschen, der in Gebrauch ist. + cannot_set_synonym_as_itself: + other: Du kannst das Synonym des aktuellen Tags nicht als sich selbst festlegen. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: Der Absendername kann keine E-Mail-Adresse sein. + theme: + not_found: + other: Design nicht gefunden. + revision: + review_underway: + other: Kann derzeit nicht bearbeitet werden, es existiert eine Version in der Überprüfungswarteschlange. + no_permission: + other: Keine Berechtigung zum Überarbeiten. + user: + external_login_missing_user_id: + other: Die Plattform des Drittanbieters stellt keine eindeutige UserID zur Verfügung, sodass du dich nicht anmelden kannst. Bitte wende dich an den Administrator der Website. + external_login_unbinding_forbidden: + other: Bitte setze ein Login-Passwort für dein Konto, bevor du dieses Login entfernst. + email_or_password_wrong: + other: + other: E-Mail und Passwort stimmen nicht überein. + not_found: + other: Benutzer nicht gefunden. + suspended: + other: Benutzer wurde gesperrt. + username_invalid: + other: Benutzername ist ungültig. + username_duplicate: + other: Benutzername wird bereits verwendet. + set_avatar: + other: Avatar setzen fehlgeschlagen. + cannot_update_your_role: + other: Du kannst deine Rolle nicht ändern. + not_allowed_registration: + other: Derzeit ist die Seite nicht für die Anmeldung geöffnet. + not_allowed_login_via_password: + other: Zurzeit ist es auf der Seite nicht möglich, sich mit einem Passwort anzumelden. + access_denied: + other: Zugriff verweigert + page_access_denied: + other: Du hast keinen Zugriff auf diese Seite. + add_bulk_users_format_error: + other: "Fehler {{.Field}}-Format in der Nähe von '{{.Content}}' in Zeile {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "Die Anzahl der Benutzer, die du auf einmal hinzufügst, sollte im Bereich von 1-{{.MaxAmount}} liegen." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Lesekonfiguration fehlgeschlagen + database: + connection_failed: + other: Datenbankverbindung fehlgeschlagen + create_table_failed: + other: Tabelle erstellen fehlgeschlagen + install: + create_config_failed: + other: Kann die config.yaml-Datei nicht erstellen. + upload: + unsupported_file_format: + other: Dateiformat nicht unterstützt. + site_info: + config_not_found: + other: Seiten-Konfiguration nicht gefunden. + badge: + object_not_found: + other: Abzeichen-Objekt nicht gefunden + reason: + spam: + name: + other: Spam + desc: + other: Dieser Beitrag ist eine Werbung oder Vandalismus. Er ist nicht nützlich oder relevant für das aktuelle Thema. + rude_or_abusive: + name: + other: unhöflich oder beleidigend + desc: + other: "Eine vernünftige Person würde diesen Inhalt im respektvoll diskutierten Diskurs für unangemessen halten." + a_duplicate: + name: + other: ein Duplikat + desc: + other: Diese Frage wurde schon einmal gestellt und hat bereits eine Antwort. + placeholder: + other: Gib den Link zur bestehenden Frage ein + not_a_answer: + name: + other: keine Antwort + desc: + other: "Die Antwort versucht nicht, die Frage zu beantworten. Sie sollte entweder bearbeitet, kommentiert, als weitere Frage gestellt oder ganz gelöscht werden." + no_longer_needed: + name: + other: nicht mehr benötigt + desc: + other: Dieser Kommentar ist veraltet oder nicht relevant für diesen Beitrag. + something: + name: + other: anderer Grund + desc: + other: Dieser Beitrag erfordert die Aufmerksamkeit der Temmitglieder aus einem anderen, oben nicht genannten Grund. + placeholder: + other: Lass uns wissen, worüber du dir Sorgen machst + community_specific: + name: + other: ein Community-spezifischer Grund + desc: + other: Diese Frage entspricht nicht den Gemeinschaftsrichtlinien. + not_clarity: + name: + other: benötigt Details oder Klarheit + desc: + other: Diese Frage enthält derzeit mehrere Fragen in einer. Sie sollte sich auf ein einziges Problem konzentrieren. + looks_ok: + name: + other: sieht OK aus + desc: + other: Dieser Beitrag ist gut so wie er ist und nicht von schlechter Qualität. + needs_edit: + name: + other: muss bearbeitet werden, und ich habe es getan + desc: + other: Verbessere und korrigiere Probleme mit diesem Beitrag selbst. + needs_close: + name: + other: muss geschlossen werden + desc: + other: Eine geschlossene Frage kann nicht beantwortet werden, aber du kannst sie trotzdem bearbeiten, abstimmen und kommentieren. + needs_delete: + name: + other: muss gelöscht werden + desc: + other: Dieser Beitrag wird gelöscht. + question: + close: + duplicate: + name: + other: Spam + desc: + other: Diese Frage ist bereits gestellt worden und hat bereits eine Antwort. + guideline: + name: + other: ein Community-spezifischer Grund + desc: + other: Diese Frage entspricht nicht einer Gemeinschaftsrichtlinie. + multiple: + name: + other: benötigt Details oder Klarheit + desc: + other: Diese Frage enthält derzeit mehrere Fragen in einer. Sie sollte sich auf ein einziges Problem konzentrieren. + other: + name: + other: etwas anderes + desc: + other: Dieser Beitrag erfordert einen anderen Grund, der oben nicht aufgeführt ist. + operation_type: + asked: + other: gefragt + answered: + other: beantwortet + modified: + other: geändert + deleted_title: + other: Gelöschte Frage + questions_title: + other: Fragen + tag: + tags_title: + other: Schlagwörter + no_description: + other: Diese Kategorie hat keine Beschreibung. + notification: + action: + update_question: + other: aktualisierte Frage + answer_the_question: + other: beantwortete Frage + update_answer: + other: aktualisierte Antwort + accept_answer: + other: akzeptierte Antwort + comment_question: + other: kommentierte Frage + comment_answer: + other: kommentierte Antwort + reply_to_you: + other: hat Ihnen geantwortet + mention_you: + other: hat dich erwähnt + your_question_is_closed: + other: Deine Frage wurde geschlossen + your_question_was_deleted: + other: Deine Frage wurde gelöscht + your_answer_was_deleted: + other: Deine Antwort wurde gelöscht + your_comment_was_deleted: + other: Dein Kommentar wurde gelöscht + up_voted_question: + other: positiv bewertete Frage + down_voted_question: + other: negativ bewertete Frage + up_voted_answer: + other: positiv bewertete Antwort + down_voted_answer: + other: negativ bewertete Antwort + up_voted_comment: + other: positiv bewerteter Kommentar + invited_you_to_answer: + other: hat dich eingeladen, zu antworten + earned_badge: + other: Du hast das "{{.BadgeName}}" Abzeichen verdient + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Bestätige deine neue E-Mail-Adresse" + body: + other: "Bestätigen Sie Ihre neue E-Mail-Adresse für {{.SiteName}} indem Sie auf den folgenden Link klicken:
        \n{{.ChangeEmailUrl}}

        \n\nWenn Sie diese Änderung nicht angefordert haben bitte diese E-Mail ignorieren.

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, Bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht angezeigt wird." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} hat deine Frage beantwortet" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \n\nAuf {{.SiteName}} anschauen

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht angezeigt wird.

        \n\nAbmelden" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} hat dich eingeladen zu antworten" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Ich denke, Sie kennen die Antwort.

        \n {{.SiteName}}

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, Bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht angezeigt wird.

        \n\nAbmelden" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} hat deinen Beitrag kommentiert" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \n\nAuf {{.SiteName}} anschauen

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, Bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht angezeigt wird.

        \n\nAbmelden" + new_question: + title: + other: "[{{.SiteName}}] Neue Frage: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nHinweis: Dies ist eine automatische Systemnachricht, bitte antworten Sie nicht darauf. Antworten werden nicht gelesen oder bearbeitet.

        \n\nBenachrichtigung abbestellen" + pass_reset: + title: + other: "[{{.SiteName }}] Passwort zurücksetzen" + body: + other: "Jemand bat darum, Ihr Passwort auf {{.SiteName}}zurückzusetzen.

        \n\nWenn Sie es nicht waren, können Sie diese E-Mail sicher ignorieren.

        \n\nKlicken Sie auf den folgenden Link, um ein neues Passwort auszuwählen:
        \n{{.PassResetUrl}}\n\n

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, Bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht angezeigt wird." + register: + title: + other: "[{{.SiteName}}] Bestätige dein neues Konto" + body: + other: "Willkommen in {{.SiteName}}!

        \n\nKlicken Sie auf den folgenden Link, um Ihr neues Konto zu bestätigen und zu aktivieren:
        \n{{.RegisterUrl}}

        \n\nWenn der obige Link nicht anklickbar ist kopieren und in die Adressleiste Ihres Webbrowsers einfügen.\n

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, Bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht sichtbar ist." + test: + title: + other: "[{{.SiteName}}] Test-E-Mail" + body: + other: "Dies ist eine Test-E-Mail.\n

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, Bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht angezeigt wird." + action_activity_type: + upvote: + other: positiv bewerten + upvoted: + other: positiv bewertet + downvote: + other: negativ bewerten + downvoted: + other: negativ bewertet + accept: + other: akzeptieren + accepted: + other: akzeptiert + edit: + other: bearbeiten + review: + queued_post: + other: Post in der Warteschlange + flagged_post: + other: Beiträge gemeldet + suggested_post_edit: + other: Änderungsvorschläge + reaction: + tooltip: + other: "{{ .Names }} Und {{ .Count }} mehr..." + badge: + default_badges: + autobiographer: + name: + other: Autobiograph + desc: + other: Gefüllt mit Profil Informationen. + certified: + name: + other: Zertifiziert + desc: + other: Erledigte unser neues Benutzerhandbuch. + editor: + name: + other: Editor + desc: + other: Erster Beitrag bearbeiten. + first_flag: + name: + other: Erste Meldung + desc: + other: Erste Meldung eines Beitrags. + first_upvote: + name: + other: Erster Upvote + desc: + other: Erste Like eines Beitrags. + first_link: + name: + other: Erster Link + desc: + other: Hat erstmals einen Link zu einem anderen Beitrag hinzugefügt. + first_reaction: + name: + other: Erste Reaktion + desc: + other: Zuerst reagierte auf den Beitrag. + first_share: + name: + other: Erstes Teilen + desc: + other: Zuerst einen Beitrag geteilt. + scholar: + name: + other: Gelehrter + desc: + other: Hat eine Frage gestellt und eine Antwort akzeptiert. + commentator: + name: + other: Kommentator + desc: + other: Hinterlassen Sie 5 Kommentare. + new_user_of_the_month: + name: + other: Neuer Benutzer des Monats + desc: + other: Ausstehende Beiträge in ihrem ersten Monat. + read_guidelines: + name: + other: Lesen Sie die Richtlinien + desc: + other: Lesen Sie die [Community-Richtlinien]. + reader: + name: + other: Leser + desc: + other: Lesen Sie alle Antworten in einem Thema mit mehr als 10 Antworten. + welcome: + name: + other: Willkommen + desc: + other: Du hast eine positive Abstimmung erhalten. + nice_share: + name: + other: Schöne teilen + desc: + other: Hat einen Beitrag mit 25 einzigartigen Besuchern freigegeben. + good_share: + name: + other: Gut geteilt + desc: + other: Hat einen Beitrag mit 300 einzigartigen Besuchern freigegeben. + great_share: + name: + other: Großartiges Teilen + desc: + other: Hat einen Beitrag mit 1000 einzigartigen Besuchern freigegeben. + out_of_love: + name: + other: Aus Liebe + desc: + other: Hat an einem Tag 50 Upvotes verwendet. + higher_love: + name: + other: Höhere Liebe + desc: + other: Hat an einem Tag 50 Upvotes 5 Mal verwendet. + crazy_in_love: + name: + other: Im siebten Himmel + desc: + other: Hat an einem Tag 50 Upvotes 20 Mal verwendet. + promoter: + name: + other: Förderer + desc: + other: Hat einen Benutzer eingeladen. + campaigner: + name: + other: Kampagnenleiter + desc: + other: Lade 3 einfache Benutzer ein. + champion: + name: + other: Champion + desc: + other: Hat 5 Mitglieder eingeladen. + thank_you: + name: + other: Vielen Dank + desc: + other: Beitrag mit 20 Upvotes und 10 abgegebenen Upvotes. + gives_back: + name: + other: Feedback geben + desc: + other: Beitrag mit 100 Upvotes und 100 abgegebenen Upvotes. + empathetic: + name: + other: Einfühlsam + desc: + other: Beitrag mit 500 Upvotes und 1000 abgegebenen Upvotes. + enthusiast: + name: + other: Enthusiast + desc: + other: Besucht 10 aufeinander folgende Tage. + aficionado: + name: + other: Aficionado + desc: + other: Besucht 100 aufeinander folgende Tage. + devotee: + name: + other: Anhänger + desc: + other: 365 aufeinander folgende Tage besucht. + anniversary: + name: + other: Jahrestag + desc: + other: Aktives Mitglied für ein Jahr, mindestens einmal veröffentlicht. + appreciated: + name: + other: Gewertschätzt + desc: + other: Erhalten 1 up vote für 20 posts. + respected: + name: + other: Respektiert + desc: + other: Erhalten 2 up vote für 100 posts. + admired: + name: + other: Bewundert + desc: + other: 5 upvotes für 300 posts erhalten. + solved: + name: + other: Gelöst + desc: + other: Eine Antwort wurde akzeptiert. + guidance_counsellor: + name: + other: Anleitungsberater + desc: + other: 10 Antworten wurden akzeptiert. + know_it_all: + name: + other: Alleswisser + desc: + other: 50 Antworten wurden akzeptiert. + solution_institution: + name: + other: Lösungsfinder + desc: + other: 150 Antworten wurden akzeptiert. + nice_answer: + name: + other: Nette Antwort + desc: + other: Die Antwortpunktzahl beträgt mehr als 10 Punkte. + good_answer: + name: + other: Gute Antwort + desc: + other: Die Antwortpunktzahl beträgt mehr als 25 Punkte. + great_answer: + name: + other: Großartige Antwort + desc: + other: Die Antwortpunktzahl beträgt mehr als 50 Punkte. + nice_question: + name: + other: Schöne Frage + desc: + other: Fragenpunktzahl von 10 oder mehr. + good_question: + name: + other: Gute Frage + desc: + other: Fragen mit 25 oder mehr Punkten. + great_question: + name: + other: Große Frage + desc: + other: Frage mit 50 oder mehr Punkten. + popular_question: + name: + other: Populäre Frage + desc: + other: Frage mit 500 Ansichten. + notable_question: + name: + other: Bemerkenswerte Frage + desc: + other: Frage mit 1.000 Ansichten. + famous_question: + name: + other: Erstklassige Frage + desc: + other: Frage mit 5.000 Ansichten. + popular_link: + name: + other: Populärer Link + desc: + other: Hat einen externen Link mit 50 Klicks gepostet. + hot_link: + name: + other: Heißer Link + desc: + other: Geschrieben einen externen Link mit 300 Klicks. + famous_link: + name: + other: Berühmter Link + desc: + other: Geschrieben einen externen Link mit 100 Klicks. + default_badge_groups: + getting_started: + name: + other: Erste Schritte + community: + name: + other: Gemeinschaft + posting: + name: + other: Freigeben +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Wie man formatiert + desc: >- +
        • einen Beitrag erwähnen: #post_id

        • um Links

          <https://url.com>

          [Titel](https://url.com)
        • Zwischen den Absätzen Zeilenumbrüche einfügen

        • _italic_ oder **fett**

        • Code um 4 Leerzeichen einrücken

        • Zitat durch Setzen von > am Anfang der Zeile

        • Backtick-Escapes `wie _this_`

        • Codeumrandungen mit Backticks `

          `
          Code hier
          ``
        + pagination: + prev: Zurück + next: Weiter + page_title: + question: Frage + questions: Fragen + tag: Schlagwort + tags: Schlagwörter + tag_wiki: tag Wiki + create_tag: Tag erstellen + edit_tag: Tag bearbeiten + ask_a_question: Create Question + edit_question: Frage bearbeiten + edit_answer: Antwort bearbeiten + search: Suchen + posts_containing: Beiträge enthalten + settings: Einstellungen + notifications: Benachrichtigungen + login: Anmelden + sign_up: Registrieren + account_recovery: Konto-Wiederherstellung + account_activation: Account Aktivierung + confirm_email: Bestätigungs-E-Mail + account_suspended: Konto gesperrt + admin: Verwaltung + change_email: E-Mails ändern + install: Installation beantworten + upgrade: Antwort-Upgrade + maintenance: Website-Wartung + users: Benutzer + oauth_callback: In Bearbeitung + http_404: HTTP-Fehler 404 + http_50X: HTTP-Fehler 500 + http_403: HTTP Fehler 403 + logout: Ausloggen + posts: Posts + notifications: + title: Benachrichtigungen + inbox: Posteingang + achievement: Erfolge + new_alerts: Neue Benachrichtigungen + all_read: Alle als gelesen markieren + show_more: Mehr anzeigen + someone: Jemand + inbox_type: + all: Alle + posts: Beiträge + invites: Einladungen + votes: Abstimmungen + answer: Antwort + question: Frage + badge_award: Abzeichen + suspended: + title: Dein Konto wurde gesperrt + until_time: "Dein Konto wurde bis zum {{ time }} gesperrt." + forever: Dieser Benutzer wurde für immer gesperrt. + end: Du erfüllst keine Community-Richtlinie. + contact_us: Kontaktiere uns + editor: + blockquote: + text: Blockzitat + bold: + text: Stark + chart: + text: Bestenliste + flow_chart: Flussdiagramm + sequence_diagram: Sequenzdiagramm + class_diagram: Klassen Diagramm + state_diagram: Zustandsdiagramm + entity_relationship_diagram: Entitätsbeziehungsdiagramm + user_defined_diagram: Benutzerdefiniertes Diagramm + gantt_chart: Gantt-Diagramm + pie_chart: Kuchendiagramm + code: + text: Code Beispiel + add_code: Code-Beispiel hinzufügen + form: + fields: + code: + label: Code + msg: + empty: Code kann nicht leer sein. + language: + label: Sprache + placeholder: Automatische Erkennung + btn_cancel: Abbrechen + btn_confirm: Hinzufügen + formula: + text: Formel + options: + inline: Inline Formel + block: Block Formel + heading: + text: Überschrift + options: + h1: Überschrift 1 + h2: Überschrift 2 + h3: Überschrift 3 + h4: Überschrift 4 + h5: Überschrift 5 + h6: Überschrift 6 + help: + text: Hilfe + hr: + text: Horizontale Richtlinie + image: + text: Bild + add_image: Bild hinzufügen + tab_image: Bild hochladen + form_image: + fields: + file: + label: Bilddatei + btn: Bild auswählen + msg: + empty: Datei darf nicht leer sein. + only_image: Nur Bilddateien sind erlaubt. + max_size: Dateigröße darf {{size}} MB nicht überschreiten. + desc: + label: Beschreibung + tab_url: Bild URL + form_url: + fields: + url: + label: Bild URL + msg: + empty: Bild-URL darf nicht leer sein. + name: + label: Beschreibung + btn_cancel: Abbrechen + btn_confirm: Hinzufügen + uploading: Hochladen + indent: + text: Einzug + outdent: + text: Ausrücken + italic: + text: Hervorhebung + link: + text: Hyperlink + add_link: Hyperlink hinzufügen + form: + fields: + url: + label: URL + msg: + empty: URL darf nicht leer sein. + name: + label: Beschreibung + btn_cancel: Abbrechen + btn_confirm: Hinzufügen + ordered_list: + text: Nummerierte Liste + unordered_list: + text: Aufzählungsliste + table: + text: Tabelle + heading: Überschrift + cell: Zelle + file: + text: Datei anhängen + not_supported: "Diesen Dateityp nicht unterstützen. Versuchen Sie es erneut mit {{file_type}}." + max_size: "Dateigröße anhängen darf {{size}} MB nicht überschreiten." + close_modal: + title: Ich schließe diesen Beitrag als... + btn_cancel: Abbrechen + btn_submit: Senden + remark: + empty: Kann nicht leer sein. + msg: + empty: Bitte wähle einen Grund aus. + report_modal: + flag_title: Ich melde diesen Beitrag als... + close_title: Ich schließe diesen Beitrag wegen ... + review_question_title: Frage prüfen + review_answer_title: Antwort prüfen + review_comment_title: Kommentar prüfen + btn_cancel: Abbrechen + btn_submit: Senden + remark: + empty: Kann nicht leer sein. + msg: + empty: Bitte wähle einen Grund aus. + not_a_url: URL hat ein falsches Format. + url_not_match: URL-Ursprung stimmt nicht mit der aktuellen Website überein. + tag_modal: + title: Neuen Tag erstellen + form: + fields: + display_name: + label: Anzeigename + msg: + empty: Anzeigename darf nicht leer sein. + range: Anzeige des Namens mit bis zu 35 Zeichen. + slug_name: + label: URL-Slug + desc: 'Muss den Zeichensatz "a-z", "0-9", "+ # - " verwenden.' + msg: + empty: URL-Slug darf nicht leer sein. + range: URL-Slug mit bis zu 35 Zeichen. + character: URL-Slug enthält nicht erlaubten Zeichensatz. + desc: + label: Beschreibung + revision: + label: Version + edit_summary: + label: Zusammenfassung bearbeiten + placeholder: >- + Erkläre kurz deine Änderungen (korrigierte Rechtschreibung, korrigierte Grammatik, verbesserte Formatierung) + btn_cancel: Abbrechen + btn_submit: Senden + btn_post: Neuen Tag erstellen + tag_info: + created_at: Erstellt + edited_at: Bearbeitet + history: Verlauf + synonyms: + title: Synonyme + text: Die folgenden Tags werden neu zugeordnet zu + empty: Keine Synonyme gefunden. + btn_add: Synonym hinzufügen + btn_edit: Bearbeiten + btn_save: Speichern + synonyms_text: Die folgenden Tags werden neu zugeordnet zu + delete: + title: Diesen Tag löschen + tip_with_posts: >- +

        Wir erlauben es nicht, Tags mit Beiträgenzu löschen.

        Bitte entfernen Sie dieses Tag zuerst aus den Beiträgen.

        + tip_with_synonyms: >- +

        Wir erlauben nicht Tags mit Synonymenzu löschen.

        Bitte entfernen Sie zuerst die Synonyme von diesem Schlagwort.

        + tip: Bist du sicher, dass du löschen möchtest? + close: Schließen + merge: + title: Tags zusammenführen + source_tag_title: Quell-Tag + source_tag_description: Das Quell-Tag und seine zugehörigen Daten werden dem Ziel-Tag zugeordnet. + target_tag_title: Ziel-Tag + target_tag_description: Ein Synonym zwischen diesen beiden Tags wird nach dem Zusammenführen erstellt. + no_results: Keine zusammenpassenden Tags gefunden + btn_submit: Absenden + btn_close: Schließen + edit_tag: + title: Tag bearbeiten + default_reason: Tag bearbeiten + default_first_reason: Tag hinzufügen + btn_save_edits: Änderungen speichern + btn_cancel: Abbrechen + dates: + long_date: DD. MMM + long_date_with_year: "DD. MMM YYYY" + long_date_with_time: "DD. MMM YYYY [at] HH:mm" + now: Gerade eben + x_seconds_ago: "Vor {{count}}s" + x_minutes_ago: "Vor {{count}}m" + x_hours_ago: "Vor {{count}}h" + hour: Stunde + day: tag + hours: Stunden + days: Tage + month: month + months: months + year: year + reaction: + heart: Herz + smile: Lächeln + frown: Stirnrunzeln + btn_label: Reaktionen hinzufügen oder entfernen + undo_emoji: '{{ emoji }} Reaktion rückgängig machen' + react_emoji: mit {{ emoji }} reagieren + unreact_emoji: '{{ emoji }} Reaktion entfernen' + comment: + btn_add_comment: Einen Kommentar hinzufügen + reply_to: Antwort an + btn_reply: Antwort + btn_edit: Bearbeiten + btn_delete: Löschen + btn_flag: Melden + btn_save_edits: Änderungen speichern + btn_cancel: Abbrechen + show_more: "{{count}} mehr Kommentare" + tip_question: >- + Verwende Kommentare, um nach weiteren Informationen zu fragen oder Verbesserungen vorzuschlagen. Vermeide es, Fragen in Kommentaren zu beantworten. + tip_answer: >- + Verwende Stellungsnahmen, um anderen Nutzern zu antworten oder sie über Änderungen zu informieren. Wenn du neue Informationen hinzufügst, bearbeite deinen Beitrag, anstatt zu kommentieren. + tip_vote: Es fügt dem Beitrag etwas Nützliches hinzu + edit_answer: + title: Antwort bearbeiten + default_reason: Antwort bearbeiten + default_first_reason: Antwort hinzufügen + form: + fields: + revision: + label: Version + answer: + label: Antwort + feedback: + characters: der Inhalt muss mindestens 6 Zeichen lang sein. + edit_summary: + label: Zusammenfassung bearbeiten + placeholder: >- + Erkläre kurz deine Änderungen (korrigierte Rechtschreibung, korrigierte Grammatik, verbesserte Formatierung) + btn_save_edits: Änderungen speichern + btn_cancel: Abbrechen + tags: + title: Schlagwörter + sort_buttons: + popular: Beliebt + name: Name + newest: Neueste + button_follow: Folgen + button_following: Folgend + tag_label: fragen + search_placeholder: Nach Tagnamen filtern + no_desc: Der Tag hat keine Beschreibung. + more: Mehr + wiki: Wiki + ask: + title: Create Question + edit_title: Frage bearbeiten + default_reason: Frage bearbeiten + default_first_reason: Create question + similar_questions: Ähnliche Fragen + form: + fields: + revision: + label: Version + title: + label: Titel + placeholder: What's your topic? Be specific. + msg: + empty: Der Titel darf nicht leer sein. + range: Titel bis zu 150 Zeichen + body: + label: Körper + msg: + empty: Körper darf nicht leer sein. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Stichworte + msg: + empty: Tags dürfen nicht leer sein. + answer: + label: Antwort + msg: + empty: Antwort darf nicht leer sein. + edit_summary: + label: Zusammenfassung bearbeiten + placeholder: >- + Erkläre kurz deine Änderungen (korrigierte Rechtschreibung, korrigierte Grammatik, verbesserte Formatierung) + btn_post_question: Poste deine Frage + btn_save_edits: Änderungen speichern + answer_question: Eigene Frage beantworten + post_question&answer: Poste deine Frage und Antwort + tag_selector: + add_btn: Schlagwort hinzufügen + create_btn: Neuen Tag erstellen + search_tag: Tag suchen + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: Keine Tags gefunden + tag_required_text: Benötigter Tag (mindestens eins) + header: + nav: + question: Fragen + tag: Schlagwörter + user: Benutzer + badges: Abzeichen + profile: Profil + setting: Einstellungen + logout: Ausloggen + admin: Administrator + review: Überprüfung + bookmark: Lesezeichen + moderation: Moderation + search: + placeholder: Suchen + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Ändern + loading: wird geladen... + pic_auth_code: + title: Captcha + placeholder: Gib den Text oben ein + msg: + empty: Captcha darf nicht leer sein. + inactive: + first: >- + Du bist fast fertig! Wir haben eine Aktivierungsmail an {{mail}} geschickt. Bitte folge den Anweisungen in der Mail, um dein Konto zu aktivieren. + info: "Wenn sie nicht ankommt, überprüfe deinen Spam-Ordner." + another: >- + Wir haben dir eine weitere Aktivierungs-E-Mail an {{mail}} geschickt. Es kann ein paar Minuten dauern, bis sie ankommt; überprüfe daher deinen Spam-Ordner. + btn_name: Aktivierungs Mail erneut senden + change_btn_name: E-Mail ändern + msg: + empty: Kann nicht leer sein. + resend_email: + url_label: Bist du sicher, dass du die Aktivierungs-E-Mail erneut senden willst? + url_text: Du kannst auch den Aktivierungslink oben an den Nutzer weitergeben. + login: + login_to_continue: Anmelden, um fortzufahren + info_sign: Du verfügst noch nicht über ein Konto? Registrieren + info_login: Du hast bereits ein Konto? <1>Anmelden + agreements: Wenn du dich registrierst, stimmst du der <1>Datenschutzrichtlinie und den <3>Nutzungsbedingungen zu. + forgot_pass: Passwort vergessen? + name: + label: Name + msg: + empty: Der Name darf nicht leer sein. + range: Der Name muss zwischen 2 und 30 Zeichen lang sein. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: E-Mail + msg: + empty: E-Mail-Feld darf nicht leer sein. + password: + label: Passwort + msg: + empty: Passwort-Feld darf nicht leer sein. + different: Die beiden eingegebenen Passwörter stimmen nicht überein + account_forgot: + page_title: Dein Passwort vergessen + btn_name: Schicke mir eine E-Mail zur Wiederherstellung + send_success: >- + Wenn ein Konto mit {{mail}} übereinstimmt, solltest du in Kürze eine E-Mail mit Anweisungen erhalten, wie du dein Passwort zurücksetzen kannst. + email: + label: E-Mail + msg: + empty: E-Mail darf nicht leer sein. + change_email: + btn_cancel: Stornieren + btn_update: E-Mail Adresse aktualisieren + send_success: >- + Wenn ein Konto mit {{mail}} übereinstimmt, solltest du in Kürze eine E-Mail mit Anweisungen erhalten, wie du dein Passwort zurücksetzen kannst. + email: + label: Neue E-Mail + msg: + empty: E-Mail darf nicht leer sein. + oauth: + connect: Mit {{ auth_name }} verbinden + remove: '{{ auth_name }} entfernen' + oauth_bind_email: + subtitle: Wiederherstellungs-E-Mail zu deinem Konto hinzufügen. + btn_update: E-Mail aktualisieren + email: + label: E-Mail + msg: + empty: E-Mail darf nicht leer sein. + modal_title: E-Mail existiert bereits. + modal_content: Diese E-Mail ist bereits registriert. Bist du sicher, dass du dich mit dem bestehenden Konto verbinden möchtest? + modal_cancel: E-Mail ändern + modal_confirm: Mit dem bestehenden Konto verbinden + password_reset: + page_title: Passwort zurücksetzen + btn_name: Setze mein Passwort zurück + reset_success: >- + Du hast dein Passwort erfolgreich geändert; du wirst zur Anmeldeseite weitergeleitet. + link_invalid: >- + Dieser Link zum Zurücksetzen des Passworts ist leider nicht mehr gültig. Vielleicht ist dein Passwort bereits zurückgesetzt? + to_login: Weiter zur Anmeldeseite + password: + label: Passwort + msg: + empty: Passwort kann nicht leer sein. + length: Die Länge muss zwischen 8 und 32 liegen + different: Die auf beiden Seiten eingegebenen Passwörter sind inkonsistent + password_confirm: + label: Neues Passwort bestätigen + settings: + page_title: Einstellungen + goto_modify: Zum Ändern + nav: + profile: Profil + notification: Benachrichtigungen + account: Konto + interface: Benutzeroberfläche + profile: + heading: Profil + btn_name: Speichern + display_name: + label: Anzeigename + msg: Anzeigename darf nicht leer sein. + msg_range: Der Anzeigename muss zwischen 2 und 30 Zeichen lang sein. + username: + label: Nutzername + caption: Leute können dich als "@Benutzername" erwähnen. + msg: Benutzername darf nicht leer sein. + msg_range: Der Benutzername muss zwischen 2 und 30 Zeichen lang sein. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profilbild + gravatar: Gravatar + gravatar_text: Du kannst das Bild ändern auf + custom: Benutzerdefiniert + custom_text: Du kannst dein Bild hochladen. + default: System + msg: Bitte lade einen Avatar hoch + bio: + label: Über mich + website: + label: Webseite + placeholder: "https://example.com" + msg: Website falsches Format + location: + label: Standort + placeholder: "Stadt, Land" + notification: + heading: E-Mail-Benachrichtigungen + turn_on: Aktivieren + inbox: + label: Posteingangsbenachrichtigungen + description: Antworten auf deine Fragen, Kommentare, Einladungen und mehr. + all_new_question: + label: Alle neuen Fragen + description: Lass dich über alle neuen Fragen benachrichtigen. Bis zu 50 Fragen pro Woche. + all_new_question_for_following_tags: + label: Alle neuen Fragen für folgende Tags + description: Lass dich über neue Fragen zu folgenden Tags benachrichtigen. + account: + heading: Konto + change_email_btn: E-Mail ändern + change_pass_btn: Passwort ändern + change_email_info: >- + Wir haben eine E-Mail an diese Adresse geschickt. Bitte befolge die Anweisungen zur Bestätigung. + email: + label: E-Mail + new_email: + label: Neue E-Mail + msg: Neue E-Mail darf nicht leer sein. + pass: + label: Aktuelles Passwort + msg: Passwort kann nicht leer sein. + password_title: Passwort + current_pass: + label: Aktuelles Passwort + msg: + empty: Das aktuelle Passwort darf nicht leer sein. + length: Die Länge muss zwischen 8 und 32 liegen. + different: Die beiden eingegebenen Passwörter stimmen nicht überein. + new_pass: + label: Neues Passwort + pass_confirm: + label: Neues Passwort bestätigen + interface: + heading: Benutzeroberfläche + lang: + label: Sprache der Benutzeroberfläche + text: Sprache der Benutzeroberfläche. Sie ändert sich, wenn du die Seite aktualisierst. + my_logins: + title: Meine Anmeldungen + label: Melde dich mit diesen Konten an oder registriere dich auf dieser Seite. + modal_title: Login entfernen + modal_content: Bist du sicher, dass du dieses Login aus deinem Konto entfernen möchtest? + modal_confirm_btn: Entfernen + remove_success: Erfolgreich entfernt + toast: + update: Aktualisierung erfolgreich + update_password: Das Kennwort wurde erfolgreich geändert. + flag_success: Danke fürs Markieren. + forbidden_operate_self: Verboten, an sich selbst zu operieren + review: Deine Überarbeitung wird nach der Überprüfung angezeigt. + sent_success: Erfolgreich gesendet + related_question: + title: Related + answers: antworten + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Frage jemanden + desc: Lade Leute ein, von denen du glaubst, dass sie die Antwort wissen könnten. + invite: Zur Antwort einladen + add: Personen hinzufügen + search: Personen suchen + question_detail: + action: Aktion + created: Created + Asked: Gefragt + asked: gefragt + update: Geändert + Edited: Edited + edit: bearbeitet + commented: kommentiert + Views: Gesehen + Follow: Folgen + Following: Folgend + follow_tip: Folge dieser Frage, um Benachrichtigungen zu erhalten + answered: beantwortet + closed_in: Abgeschlossen in + show_exist: Bestehende Frage anzeigen. + useful: Nützlich + question_useful: Es ist nützlich und klar + question_un_useful: Es ist unklar oder nicht nützlich + question_bookmark: Lesezeichen für diese Frage + answer_useful: Es ist nützlich + answer_un_useful: Es ist nicht nützlich + answers: + title: Antworten + score: Punkte + newest: Neueste + oldest: Älteste + btn_accept: Akzeptieren + btn_accepted: Akzeptiert + write_answer: + title: Deine Antwort + edit_answer: Meine existierende Antwort bearbeiten + btn_name: Poste deine Antwort + add_another_answer: Weitere Antwort hinzufügen + confirm_title: Antworten fortsetzen + continue: Weitermachen + confirm_info: >- +

        Bist du sicher, dass du eine weitere Antwort hinzufügen willst?

        Du könntest stattdessen den Bearbeiten-Link verwenden, um deine existierende Antwort zu verfeinern und zu verbessern.

        + empty: Antwort darf nicht leer sein. + characters: der Inhalt muss mindestens 6 Zeichen lang sein. + tips: + header_1: Danke für deine Antwort + li1_1: Bitte stelle sicher, dass du die Frage beantwortest. Gib Details an und erzähle von deiner Recherche. + li1_2: Untermauere alle Aussagen, die du erstellst, mit Referenzen oder persönlichen Erfahrungen. + header_2: Aber vermeide... + li2_1: Bitte um Hilfe, um Klarstellung oder um Antwort auf andere Antworten. + reopen: + confirm_btn: Wieder öffnen + title: Diesen Beitrag erneut öffnen + content: Bist du sicher, dass du wieder öffnen willst? + list: + confirm_btn: Liste + title: Diesen Beitrag auflisten + content: Möchten Sie diesen Beitrag wirklich in der Liste anzeigen? + unlist: + confirm_btn: Von Liste nehmen + title: Diesen Beitrag von der Liste nehmen + content: Möchten Sie diesen Beitrag wirklich aus der Liste ausblenden? + pin: + title: Diesen Beitrag anpinnen + content: Bist du sicher, dass du den Beitrag global anheften möchtest? Dieser Beitrag wird in allen Beitragslisten ganz oben erscheinen. + confirm_btn: Anheften + delete: + title: Diesen Beitrag löschen + question: >- + Wir raten davon ab, Fragen mit Antworten zu löschen, weil dadurch zukünftigen Lesern dieses Wissen vorenthalten wird.

        Wiederholtes Löschen von beantworteten Fragen kann dazu führen, dass dein Konto für Fragen gesperrt wird. Bist du sicher, dass du löschen möchtest? + answer_accepted: >- +

        Wir empfehlen nicht, akzeptierte Antworten zu löschen, denn dadurch wird zukünftigen Lesern dieses Wissen vorenthalten.

        Das wiederholte Löschen von akzeptierten Antworten kann dazu führen, dass dein Konto für die Beantwortung gesperrt wird. Bist du sicher, dass du löschen möchtest? + other: Bist du sicher, dass du löschen möchtest? + tip_answer_deleted: Diese Antwort wurde gelöscht + undelete_title: Diesen Beitrag wiederherstellen + undelete_desc: Bist du sicher, dass du die Löschung umkehren willst? + btns: + confirm: Bestätigen + cancel: Abbrechen + edit: Bearbeiten + save: Speichern + delete: Löschen + undelete: Wiederherstellen + list: Liste + unlist: Verstecken + unlisted: Versteckt + login: Einloggen + signup: Registrieren + logout: Ausloggen + verify: Überprüfen + create: Erstellen + approve: Genehmigen + reject: Ablehnen + skip: Überspringen + discard_draft: Entwurf verwerfen + pinned: Angeheftet + all: Alle + question: Frage + answer: Antwort + comment: Kommentar + refresh: Aktualisieren + resend: Erneut senden + deactivate: Deaktivieren + active: Aktiv + suspend: Sperren + unsuspend: Entsperren + close: Schließen + reopen: Wieder öffnen + ok: Okay + light: Hell + dark: Dunkel + system_setting: System-Einstellung + default: Standard + reset: Zurücksetzen + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignorieren + submit: Absenden + normal: Normal + closed: Geschlossen + deleted: Gelöscht + deleted_permanently: Dauerhaft gelöscht + pending: Ausstehend + more: Mehr + view: Betrachten + card: Karte + compact: Kompakt + display_below: Unten anzeigen + always_display: Immer anzeigen + or: oder + back_sites: Zurück zur Website + search: + title: Suchergebnisse + keywords: Schlüsselwörter + options: Optionen + follow: Folgen + following: Folgend + counts: "{{count}} Ergebnisse" + counts_loading: "... Results" + more: Mehr + sort_btns: + relevance: Relevanz + newest: Neueste + active: Aktiv + score: Punktzahl + more: Mehr + tips: + title: Erweiterte Suchtipps + tag: "<1>[tag] Suche mit einem Tag" + user: "<1>user:username Suche nach Autor" + answer: "<1>Antworten:0 unbeantwortete Fragen" + score: "<1>score:3 Beiträge mit einer 3+ Punktzahl" + question: "<1>is:question Suchfragen" + is_answer: "<1>ist:answer Suchantworten" + empty: Wir konnten nichts finden.
        Versuche es mit anderen oder weniger spezifischen Keywords. + share: + name: Teilen + copy: Link kopieren + via: Beitrag teilen über... + copied: Kopiert + facebook: Auf Facebook teilen + twitter: Auf X teilen + cannot_vote_for_self: Du kannst nicht für deinen eigenen Beitrag stimmen. + modal_confirm: + title: Fehler... + delete_permanently: + title: Endgültig löschen + content: Sind Sie sicher, dass Sie den Inhalt endgültig löschen möchten? + account_result: + success: Dein neues Konto ist bestätigt; du wirst zur Startseite weitergeleitet. + link: Weiter zur Startseite + oops: Hoppla! + invalid: Der Link, den Sie verwendet haben, funktioniert nicht mehr. + confirm_new_email: Deine E-Mail wurde aktualisiert. + confirm_new_email_invalid: >- + Dieser Bestätigungslink ist leider nicht mehr gültig. Vielleicht wurde deine E-Mail-Adresse bereits geändert? + unsubscribe: + page_title: Abonnement entfernen + success_title: Erfolgreich vom Abo abgemeldet + success_desc: Du wurdest erfolgreich aus der Abonnentenliste gestrichen und wirst keine weiteren E-Mails von uns erhalten. + link: Einstellungen ändern + question: + following_tags: Folgende Tags + edit: Bearbeiten + save: Speichern + follow_tag_tip: Folge den Tags, um deine Liste mit Fragen zu erstellen. + hot_questions: Angesagte Fragen + all_questions: Alle Fragen + x_questions: "{{ count }} Fragen" + x_answers: "{{ count }} Antworten" + x_posts: "{{ count }} Posts" + questions: Fragen + answers: Antworten + newest: Neueste + active: Aktiv + hot: Heiß + frequent: Häufig + recommend: Empfehlen + score: Punktzahl + unanswered: Unbeantwortet + modified: geändert + answered: beantwortet + asked: gefragt + closed: schließen + follow_a_tag: Einem Tag folgen + more: Mehr + personal: + overview: Übersicht + answers: Antworten + answer: antwort + questions: Fragen + question: frage + bookmarks: Lesezeichen + reputation: Ansehen + comments: Kommentare + votes: Stimmen + badges: Abzeichen + newest: Neueste + score: Punktzahl + edit_profile: Profil bearbeiten + visited_x_days: "{{ count }} Tage besucht" + viewed: Gesehen + joined: Beigetreten + comma: "," + last_login: Gesehen + about_me: Über mich + about_me_empty: "// Hallo Welt !" + top_answers: Top-Antworten + top_questions: Top-Fragen + stats: Statistiken + list_empty: Keine Beiträge gefunden.
        Vielleicht möchtest du einen anderen Reiter auswählen? + content_empty: Keine Posts gefunden. + accepted: Akzeptiert + answered: antwortete + asked: gefragt + downvoted: negativ bewertet + mod_short: MOD + mod_long: Moderatoren + x_reputation: ansehen + x_votes: Stimmen erhalten + x_answers: Antworten + x_questions: Fragen + recent_badges: Neueste Abzeichen + install: + title: Installation + next: Nächste + done: Erledigt + config_yaml_error: Die Datei config.yaml kann nicht erstellt werden. + lang: + label: Bitte wähle eine Sprache + db_type: + label: Datenbank-Engine + db_username: + label: Nutzername + placeholder: wurzel + msg: Benutzername darf nicht leer sein. + db_password: + label: Passwort + placeholder: wurzel + msg: Passwort kann nicht leer sein. + db_host: + label: Datenbank-Host + placeholder: "db:3306" + msg: Datenbank-Host darf nicht leer sein. + db_name: + label: Datenbankname + placeholder: antworten + msg: Der Datenbankname darf nicht leer sein. + db_file: + label: Datenbank-Datei + placeholder: /data/answer.Weder noch + msg: Datenbankdatei kann nicht leer sein. + ssl_enabled: + label: SSL aktivieren + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL-Modus + ssl_root_cert: + placeholder: SSL-Root-Zertifikat Pfad + msg: Pfad zum Ssl-Root-Zertifikat darf nicht leer sein + ssl_cert: + placeholder: SSL-Zertifikat Pfad + msg: Pfad zum SSL-Zertifikat darf nicht leer sein + ssl_key: + placeholder: SSL-Key Pfad + msg: Der Pfad zum SSL-Key darf nicht leer sein + config_yaml: + title: config.yaml erstellen + label: Die erstellte config.yaml-Datei. + desc: >- + Du kannst die Datei <1>config.yaml manuell im Verzeichnis <1>/var/wwww/xxx/ erstellen und den folgenden Text dort einfügen. + info: Nachdem du das getan hast, klickst du auf die Schaltfläche "Weiter". + site_information: Standortinformationen + admin_account: Administratorkonto + site_name: + label: Seitenname + msg: Standortname darf nicht leer sein. + msg_max_length: Der Name der Website darf maximal 30 Zeichen lang sein. + site_url: + label: Seiten-URL + text: Die Adresse deiner Website. + msg: + empty: Die Website-URL darf nicht leer sein. + incorrect: Falsches Format der Website-URL. + max_length: Die URL der Website darf maximal 512 Zeichen lang sein. + contact_email: + label: Kontakt E-Mail + text: E-Mail-Adresse des Hauptkontakts, der für diese Website verantwortlich ist. + msg: + empty: Kontakt-E-Mail kann nicht leer sein. + incorrect: Falsches Format der Kontakt-E-Mail. + login_required: + label: Privat + switch: Anmeldung erforderlich + text: Nur eingeloggte Benutzer können auf diese Community zugreifen. + admin_name: + label: Name + msg: Der Name darf nicht leer sein. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Der Name muss zwischen 2 und 30 Zeichen lang sein. + admin_password: + label: Passwort + text: >- + Du brauchst dieses Passwort, um dich einzuloggen. Bitte bewahre es an einem sicheren Ort auf. + msg: Passwort kann nicht leer sein. + msg_min_length: Passwort muss mindestens 8 Zeichen lang sein. + msg_max_length: Das Passwort darf maximal 32 Zeichen lang sein. + admin_confirm_password: + label: "Passwort bestätigen" + text: "Bitte geben Sie Ihr Passwort erneut ein, um es zu bestätigen." + msg: "Passwortbestätigung stimmt nicht überein!" + admin_email: + label: E-Mail + text: Du brauchst diese E-Mail, um dich einzuloggen. + msg: + empty: E-Mail darf nicht leer sein. + incorrect: E-Mail falsches Format. + ready_title: Ihre Seite ist bereit + ready_desc: >- + Wenn du noch mehr Einstellungen ändern möchtest, besuche den <1>Admin-Bereich; du findest ihn im Seitenmenü. + good_luck: "Viel Spaß und viel Glück!" + warn_title: Warnung + warn_desc: >- + Die Datei <1>config.yaml existiert bereits. Wenn du einen der Konfigurationspunkte in dieser Datei zurücksetzen musst, lösche sie bitte zuerst. + install_now: Du kannst versuchen, <1>jetzt zu installieren. + installed: Bereits installiert + installed_desc: >- + Du scheinst es bereits installiert zu haben. Um neu zu installieren, lösche bitte zuerst deine alten Datenbanktabellen. + db_failed: Datenbankverbindung fehlgeschlagen + db_failed_desc: >- + Das bedeutet entweder, dass die Datenbankinformationen in deiner <1>config.yaml Datei falsch sind oder dass der Kontakt zum Datenbankserver nicht hergestellt werden konnte. Das könnte bedeuten, dass der Datenbankserver deines Hosts ausgefallen ist. + counts: + views: Ansichten + votes: Stimmen + answers: Antworten + accepted: Akzeptiert + page_error: + http_error: HTTP Fehler {{ code }} + desc_403: Du hast keine Berechtigung, auf diese Seite zuzugreifen. + desc_404: Leider existiert diese Seite nicht. + desc_50X: Der Server ist auf einen Fehler gestoßen und konnte deine Anfrage nicht vollständig abschließen. + back_home: Zurück zur Startseite + page_maintenance: + desc: "Wir werden gewartet, wir sind bald wieder da." + nav_menus: + dashboard: Dashboard + contents: Inhalt + questions: Fragen + answers: Antworten + users: Benutzer + badges: Abzeichen + flags: Meldungen + settings: Einstellungen + general: Allgemein + interface: Benutzeroberfläche + smtp: SMTP + branding: Branding + legal: Rechtliches + write: Schreiben + terms: Terms + tos: Nutzungsbedingungen + privacy: Privatsphäre + seo: SEO + customize: Anpassen + themes: Themen + login: Anmeldung + privileges: Berechtigungen + plugins: Erweiterungen (Plugins) + installed_plugins: Installierte Plugins + apperance: Erscheinungsbild + website_welcome: Willkommen auf {{site_name}} + user_center: + login: Anmelden + qrcode_login_tip: Bitte verwende {{ agentName }}, um den QR-Code zu scannen und dich einzuloggen. + login_failed_email_tip: Anmeldung ist fehlgeschlagen. Bitte erlaube dieser App, auf deine E-Mail-Informationen zuzugreifen, bevor du es erneut versuchst. + badges: + modal: + title: Glückwunsch + content: Sie haben sich ein neues Abzeichen verdient. + close: Schließen + confirm: Abzeichen ansehen + title: Abzeichen + awarded: Verliehen + earned_×: Verdiente ×{{ number }} + ×_awarded: "verliehen {{ number }} " + can_earn_multiple: Du kannst das mehrmals verdienen. + earned: Verdient + admin: + admin_header: + title: Administrator + dashboard: + title: Dashboard + welcome: Willkommen im Admin Bereich! + site_statistics: Website-Statistiken + questions: "Fragen:" + resolved: "Belöst:" + unanswered: "Nicht beantwortet:" + answers: "Antworten:" + comments: "Kommentare:" + votes: "Stimmen:" + users: "Nutzer:" + flags: "Meldungen:" + reviews: "Rezension:" + site_health: Gesundheit der Website + version: "Version:" + https: "HTTPS:" + upload_folder: "Hochladeverzeichnis:" + run_mode: "Betriebsmodus:" + private: Privat + public: Öffentlich + smtp: "SMTP:" + timezone: "Zeitzone:" + system_info: Systeminformationen + go_version: "Go Version:" + database: "Datenbank:" + database_size: "Datenbankgröße:" + storage_used: "Verwendeter Speicher:" + uptime: "Betriebszeit:" + links: Links + plugins: Plugins + github: GitHub + blog: Blog + contact: Kontakt + forum: Forum + documents: Dokumentation + feedback: Rückmeldung + support: Unterstützung + review: Überprüfung + config: Konfig + update_to: Aktualisieren zu + latest: Aktuell + check_failed: Prüfung fehlgeschlagen + "yes": "Ja" + "no": "Nein" + not_allowed: Nicht erlaubt + allowed: Erlaubt + enabled: Aktiviert + disabled: Deaktiviert + writable: Schreibbar + not_writable: Nicht schreibbar + flags: + title: Meldungen + pending: Ausstehend + completed: Abgeschlossen + flagged: Gekennzeichnet + flagged_type: '{{ type }} gemeldet' + created: Erstellt + action: Aktion + review: Überprüfung + user_role_modal: + title: Benutzerrolle ändern zu... + btn_cancel: Abbrechen + btn_submit: Senden + new_password_modal: + title: Neues Passwort festlegen + form: + fields: + password: + label: Passwort + text: Der Nutzer wird abgemeldet und muss sich erneut anmelden. + msg: Das Passwort muss mindestens 8-32 Zeichen lang sein. + btn_cancel: Abbrechen + btn_submit: Senden + edit_profile_modal: + title: Profil bearbeiten + form: + fields: + display_name: + label: Anzeigename + msg_range: Der Anzeigename muss zwischen 2 und 30 Zeichen lang sein. + username: + label: Nutzername + msg_range: Der Benutzername muss 2-30 Zeichen lang sein. + email: + label: E-Mail + msg_invalid: Ungültige E-Mail-Adresse. + edit_success: Erfolgreich bearbeitet + btn_cancel: Abbrechen + btn_submit: Absenden + user_modal: + title: Neuen Benutzer hinzufügen + form: + fields: + users: + label: Masse Benutzer hinzufügen + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Trenne "Name, E-Mail, Passwort" mit Kommas. Ein Benutzer pro Zeile. + msg: "Bitte gib die E-Mail des Nutzers ein, eine pro Zeile." + display_name: + label: Anzeigename + msg: Der Anzeigename muss zwischen 2 und 30 Zeichen lang sein. + email: + label: E-Mail + msg: Die E-Mail ist nicht gültig. + password: + label: Passwort + msg: Das Passwort muss mindestens 8-32 Zeichen lang sein. + btn_cancel: Abbrechen + btn_submit: Senden + users: + title: Benutzer + name: Name + email: E-Mail + reputation: Ansehen + created_at: Angelegt am + delete_at: Löschzeit + suspend_at: Sperrzeit + suspend_until: Suspend until + status: Status + role: Rolle + action: Aktion + change: Ändern + all: Alle + staff: Teammitglieder + more: Mehr + inactive: Inaktiv + suspended: Gesperrt + deleted: Gelöscht + normal: Normal + Moderator: Moderation + Admin: Administrator + User: Benutzer + filter: + placeholder: "Nach Namen, user:id filtern" + set_new_password: Neues Passwort festlegen + edit_profile: Profil bearbeiten + change_status: Status ändern + change_role: Rolle wechseln + show_logs: Protokolle anzeigen + add_user: Benutzer hinzufügen + deactivate_user: + title: Benutzer deaktivieren + content: Ein inaktiver Nutzer muss seine E-Mail erneut bestätigen. + delete_user: + title: Diesen Benutzer löschen + content: Bist du sicher, dass du diesen Benutzer löschen willst? Das ist dauerhaft! + remove: Ihren Inhalt entfernen + label: Alle Fragen, Antworten, Kommentare, etc. entfernen + text: Aktiviere diese Option nicht, wenn du nur das Benutzerkonto löschen möchtest. + suspend_user: + title: Diesen Benutzer sperren + content: Ein gesperrter Benutzer kann sich nicht einloggen. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Fragen + unlisted: Nicht gelistet + post: Beitrag + votes: Stimmen + answers: Antworten + created: Erstellt + status: Status + action: Aktion + change: Ändern + pending: Ausstehend + filter: + placeholder: "Filtern nach Titel, Frage:Id" + answers: + page_title: Antworten + post: Beitrag + votes: Stimmen + created: Erstellt + status: Status + action: Aktion + change: Ändern + filter: + placeholder: "Filtern nach Titel, Antwort: id" + general: + page_title: Allgemein + name: + label: Seitenname + msg: Der Site-Name darf nicht leer sein. + text: "Der Name dieser Website, wie er im Titel-Tag verwendet wird." + site_url: + label: Seiten-URL + msg: Die Website-Url darf nicht leer sein. + validate: Bitte gib eine gültige URL ein. + text: Die Adresse deiner Website. + short_desc: + label: Kurze Seitenbeschreibung + msg: Die kurze Website-Beschreibung darf nicht leer sein. + text: "Kurze Beschreibung, wie im Titel-Tag auf der Homepage verwendet." + desc: + label: Seitenbeschreibung + msg: Die Websitebeschreibung darf nicht leer sein. + text: "Beschreibe diese Seite in einem Satz, wie er im Meta Description Tag verwendet wird." + contact_email: + label: Kontakt E-Mail + msg: Kontakt-E-Mail darf nicht leer sein. + validate: Kontakt-E-Mail ist ungültig. + text: E-Mail-Adresse des Hauptkontakts, der für diese Website verantwortlich ist. + check_update: + label: Softwareaktualisierungen + text: Automatisch auf Updates prüfen + interface: + page_title: Benutzeroberfläche + language: + label: Interface Sprache + msg: Sprache der Benutzeroberfläche darf nicht leer sein. + text: Sprache der Benutzeroberfläche. Sie ändert sich, wenn du die Seite aktualisierst. + time_zone: + label: Zeitzone + msg: Die Zeitzone darf nicht leer sein. + text: Wähle eine Stadt in der gleichen Zeitzone wie du. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: Von E-Mail + msg: Von E-Mail darf nicht leer sein. + text: Die E-Mail-Adresse, von der E-Mails gesendet werden. + from_name: + label: Von Name + msg: Absendername darf nicht leer sein. + text: Der Name, von dem E-Mails gesendet werden. + smtp_host: + label: SMTP-Host + msg: Der SMTP-Host darf nicht leer sein. + text: Dein Mailserver. + encryption: + label: Verschlüsselung + msg: Verschlüsselung darf nicht leer sein. + text: Für die meisten Server ist SSL die empfohlene Option. + ssl: SSL + tls: TLS + none: Keine + smtp_port: + label: SMTP-Port + msg: SMTP-Port muss Nummer 1 ~ 65535 sein. + text: Der Port zu deinem Mailserver. + smtp_username: + label: SMTP-Benutzername + msg: Der SMTP-Benutzername darf nicht leer sein. + smtp_password: + label: SMTP-Kennwort + msg: Das SMTP-Passwort darf nicht leer sein. + test_email_recipient: + label: Test-E-Mail-Empfänger + text: Gib die E-Mail-Adresse an, an die Testsendungen gesendet werden sollen. + msg: Test-E-Mail-Empfänger ist ungültig + smtp_authentication: + label: Authentifizierung aktivieren + title: SMTP-Authentifizierung + msg: Die SMTP-Authentifizierung darf nicht leer sein. + "yes": "Ja" + "no": "Nein" + branding: + page_title: Branding + logo: + label: Logo + msg: Logo darf nicht leer sein. + text: Das Logobild oben links auf deiner Website. Verwende ein breites rechteckiges Bild mit einer Höhe von 56 und einem Seitenverhältnis von mehr als 3:1. Wenn du es leer lässt, wird der Text des Website-Titels angezeigt. + mobile_logo: + label: Mobiles Logo + text: Das Logo wird auf der mobilen Version deiner Website verwendet. Verwende ein breites rechteckiges Bild mit einer Höhe von 56. Wenn du nichts angibst, wird das Bild aus der Einstellung "Logo" verwendet. + square_icon: + label: Quadratisches Symbol + msg: Quadratisches Symbol darf nicht leer sein. + text: Bild, das als Basis für Metadatensymbole verwendet wird. Sollte idealerweise größer als 512x512 sein. + favicon: + label: Favicon + text: Ein Favicon für deine Website. Um korrekt über ein CDN zu funktionieren, muss es ein png sein. Es wird auf 32x32 verkleinert. Wenn du es leer lässt, wird das "quadratische Symbol" verwendet. + legal: + page_title: Rechtliches + terms_of_service: + label: Nutzungsbedingungen + text: "Du kannst hier Inhalte zu den Nutzungsbedingungen hinzufügen. Wenn du bereits ein Dokument hast, das anderswo gehostet wird, gib hier die vollständige URL an." + privacy_policy: + label: Datenschutzbestimmungen + text: "Du kannst hier Inhalte zur Datenschutzerklärung hinzufügen. Wenn du bereits ein Dokument hast, das anderswo gehostet wird, gib hier die vollständige URL an." + external_content_display: + label: Externer Inhalt + text: "Inhalte umfassen Bilder, Videos und Medien, die von externen Websites eingebettet sind." + always_display: Externen Inhalt immer anzeigen + ask_before_display: Vor der Anzeige externer Inhalte fragen + write: + page_title: Schreiben + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Antwort bearbeiten + label: Jeder Benutzer kann für jede Frage nur eine Antwort schreiben + text: "Schalten Sie aus, um es Benutzern zu ermöglichen, mehrere Antworten auf dieselbe Frage zu schreiben, was dazu führen kann, dass Antworten nicht im Fokus stehen." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Empfohlene Tags + text: "Empfohlene Tags werden standardmäßig in der Dropdown-Liste angezeigt." + msg: + contain_reserved: "empfohlene Tags dürfen keine reservierten Tags enthalten" + required_tag: + title: Benötigte Tags festlegen + label: '"Empfohlene Tags" als erforderliche Tags festlegen' + text: "Jede neue Frage muss mindestens ein Empfehlungs-Tag haben." + reserved_tags: + label: Reservierte Tags + text: "Reservierte Tags können nur vom Moderator verwendet werden." + image_size: + label: Maximale Bildgröße (MB) + text: "Die maximale Bildladegröße." + attachment_size: + label: Maximale Anhanggröße (MB) + text: "Die maximale Dateigröße für Dateianhänge." + image_megapixels: + label: Max. BildmePixel + text: "Maximale Anzahl an Megapixeln für ein Bild." + image_extensions: + label: Autorisierte Bilderweiterungen + text: "Eine Liste von Dateierweiterungen, die für die Anzeige von Bildern erlaubt sind, getrennt durch Kommata." + attachment_extensions: + label: Autorisierte Anhänge Erweiterungen + text: "Eine Liste von Dateierweiterungen, die für das Hochladen erlaubt sind, getrennt mit Kommas. WARNUNG: Erlaubt Uploads kann Sicherheitsprobleme verursachen." + seo: + page_title: SEO + permalink: + label: Dauerlink + text: Benutzerdefinierte URL-Strukturen können die Benutzerfreundlichkeit und die Vorwärtskompatibilität deiner Links verbessern. + robots: + label: robots.txt + text: Dadurch werden alle zugehörigen Site-Einstellungen dauerhaft überschrieben. + themes: + page_title: Themen + themes: + label: Themen + text: Wähle ein bestehendes Thema aus. + color_scheme: + label: Farbschema + navbar_style: + label: Hintergrundstil der Navigationsleiste + primary_color: + label: Primäre Farbe + text: Ändere die Farben, die von deinen Themes verwendet werden + css_and_html: + page_title: CSS und HTML + custom_css: + label: Benutzerdefinierte CSS + text: > + + head: + label: Kopf + text: > + + header: + label: Header + text: > + + footer: + label: Fusszeile + text: Dies wird vor eingefügt. + sidebar: + label: Seitenleiste + text: Dies wird in die Seitenleiste eingefügt. + login: + page_title: Anmeldung + membership: + title: Mitgliedschaft + label: Neuregistrierungen zulassen + text: Schalte sie ab, um zu verhindern, dass jemand ein neues Konto erstellt. + email_registration: + title: E-Mail Registrierung + label: E-Mail-Registrierung zulassen + text: Abschalten, um zu verhindern, dass jemand ein neues Konto per E-Mail erstellt. + allowed_email_domains: + title: Zugelassene E-Mail-Domänen + text: E-Mail-Domänen, bei denen die Nutzer Konten registrieren müssen. Eine Domäne pro Zeile. Wird ignoriert, wenn leer. + private: + title: Privatgelände + label: Anmeldung erforderlich + text: Nur angemeldete Benutzer können auf diese Community zugreifen. + password_login: + title: Passwort-Login + label: E-Mail-und Passwort-Login erlauben + text: "WARNUNG: Wenn du diese Option abschaltest, kannst du dich möglicherweise nicht mehr anmelden, wenn du zuvor keine andere Anmeldemethode konfiguriert hast." + installed_plugins: + title: Installierte Plugins + plugin_link: Plugins erweitern und ergänzen die Funktionalität. Du kannst Plugins im <1>Pluginverzeichnis finden. + filter: + all: Alle + active: Aktiv + inactive: Inaktiv + outdated: Veraltet + plugins: + label: Erweiterungen + text: Wähle ein bestehendes Plugin aus. + name: Name + version: Version + status: Status + action: Aktion + deactivate: Deaktivieren + activate: Aktivieren + settings: Einstellungen + settings_users: + title: Benutzer + avatar: + label: Standard-Avatar + text: Für Benutzer ohne einen eigenen Avatar. + gravatar_base_url: + label: Gravatar Base URL + text: URL der API-Basis des Gravatar-Anbieters. Wird ignoriert, wenn leer. + profile_editable: + title: Profil bearbeitbar + allow_update_display_name: + label: Benutzern erlauben, ihren Anzeigenamen zu ändern + allow_update_username: + label: Benutzern erlauben, ihren Benutzernamen zu ändern + allow_update_avatar: + label: Benutzern erlauben, ihr Profilbild zu ändern + allow_update_bio: + label: Benutzern erlauben, ihr Über mich zu ändern + allow_update_website: + label: Benutzern erlauben, ihre Website zu ändern + allow_update_location: + label: Benutzern erlauben, ihren Standort zu ändern + privilege: + title: Berechtigungen + level: + label: Benötigtes Reputations-Level + text: Wähle die für die Privilegien erforderliche Reputation aus + msg: + should_be_number: die Eingabe muss numerisch sein + number_larger_1: Zahl muss gleich oder größer als 1 sein + badges: + action: Aktion + active: Aktiv + activate: Aktivieren + all: Alle + awards: Verliehen + deactivate: Deaktivieren + filter: + placeholder: Nach Namen, Abzeichen:id filtern + group: Gruppe + inactive: Inaktiv + name: Name + show_logs: Protokolle anzeigen + status: Status + title: Abzeichen + form: + optional: (optional) + empty: kann nicht leer sein + invalid: ist ungültig + btn_submit: Speichern + not_found_props: "Erforderliche Eigenschaft {{ key }} nicht gefunden." + select: Auswählen + page_review: + review: Überprüfung + proposed: vorgeschlagen + question_edit: Frage bearbeiten + answer_edit: Antwort bearbeiten + tag_edit: Tag bearbeiten + edit_summary: Zusammenfassung bearbeiten + edit_question: Frage bearbeiten + edit_answer: Antwort bearbeiten + edit_tag: Tag bearbeiten + empty: Keine Überprüfungsaufgaben mehr übrig. + approve_revision_tip: Akzeptieren Sie diese Revision? + approve_flag_tip: Sind Sie mit diesem Bericht einverstanden? + approve_post_tip: Bestätigen Sie diesen Beitrag? + approve_user_tip: Bestätigen Sie diesen Benutzer? + suggest_edits: Änderungsvorschläge + flag_post: Beitrag melden + flag_user: Nutzer melden + queued_post: Beitrag in Warteschlange + queued_user: Benutzer in der Warteschlange + filter_label: Typ + reputation: ansehen + flag_post_type: Diesen Beitrag als {{ type }} markiert. + flag_user_type: Diesen Benutzer als {{ type }} markiert. + edit_post: Beitrag bearbeiten + list_post: Ausgestellte Beiträge + unlist_post: Versteckte Beiträge + timeline: + undeleted: ungelöscht + deleted: gelöscht + downvote: ablehnen + upvote: positiv bewerten + accept: akzeptieren + cancelled: abgebrochen + commented: kommentiert + rollback: zurückrollen + edited: bearbeitet + answered: antwortete + asked: gefragt + closed: geschlossen + reopened: wiedereröffnet + created: erstellt + pin: angeheftet + unpin: losgelöst + show: gelistet + hide: nicht gelistet + title: "Verlauf von" + tag_title: "Zeitleiste für" + show_votes: "Stimmen anzeigen" + n_or_a: Keine Angaben + title_for_question: "Zeitleiste für" + title_for_answer: "Zeitachse für die Antwort auf {{ title }} von {{ author }}" + title_for_tag: "Zeitachse für Tag" + datetime: Terminzeit + type: Typ + by: Von + comment: Kommentar + no_data: "Wir konnten nichts finden." + users: + title: Benutzer + users_with_the_most_reputation: Benutzer mit den höchsten Reputationspunkten dieser Woche + users_with_the_most_vote: Benutzer, die diese Woche am meisten gestimmt haben + staffs: Unsere Community Teammitglieder + reputation: Ansehen + votes: Stimmen + prompt: + leave_page: Bist du sicher, dass du die Seite verlassen willst? + changes_not_save: Deine Änderungen werden möglicherweise nicht gespeichert. + draft: + discard_confirm: Bist du sicher, dass du deinen Entwurf verwerfen willst? + messages: + post_deleted: Dieser Beitrag wurde gelöscht. + post_cancel_deleted: Dieser Beitrag wurde wiederhergestellt. + post_pin: Dieser Beitrag wurde angepinnt. + post_unpin: Dieser Beitrag wurde losgelöst. + post_hide_list: Dieser Beitrag wurde aus der Liste verborgen. + post_show_list: Dieser Beitrag wird in der Liste angezeigt. + post_reopen: Dieser Beitrag wurde wieder geöffnet. + post_list: Dieser Beitrag wurde angezeigt. + post_unlist: Dieser Beitrag wurde ausgeblendet. + post_pending: Dein Beitrag wartet auf eine Überprüfung. Dies ist eine Vorschau, sie wird nach der Genehmigung sichtbar sein. + post_closed: Dieser Beitrag wurde gelöscht. + answer_deleted: Diese Antwort wurde gelöscht. + answer_cancel_deleted: Diese Antwort wurde wiederhergestellt. + change_user_role: Die Rolle dieses Benutzers wurde geändert. + user_inactive: Dieser Benutzer ist bereits inaktiv. + user_normal: Dieser Benutzer ist bereits normal. + user_suspended: Dieser Nutzer wurde gesperrt. + user_deleted: Benutzer wurde gelöscht. + badge_activated: Dieses Abzeichen wurde aktiviert. + badge_inactivated: Dieses Abzeichen wurde deaktiviert. + users_deleted: Der Benutzer wurde gelöscht. + posts_deleted: Deine Frage wurde gelöscht. + answers_deleted: Deine Antwort wurde gelöscht. + copy: In die Zwischenablage kopieren + copied: Kopiert + external_content_warning: Externe Bilder/Medien werden nicht angezeigt. + + diff --git a/data/i18n/el_GR.yaml b/data/i18n/el_GR.yaml new file mode 100644 index 000000000..25c086f11 --- /dev/null +++ b/data/i18n/el_GR.yaml @@ -0,0 +1,1384 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: Success. + unknown: + other: Unknown error. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + email: + other: Email + password: + other: Password + email_or_password_wrong_error: + other: Email and password do not match. + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + question: + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + rank: + fail_to_meet_the_condition: + other: Rank fail to meet the condition. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend Tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + smtp: + config_from_name_cannot_be_email: + other: The From Name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to Revision. + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + report: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude: + name: + other: rude or abusive + desc: + other: A reasonable person would find this content inappropriate for respectful discourse. + duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + not_answer: + name: + other: not an answer + desc: + other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. + not_need: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + other: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comments + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to {{site_name}} + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to {{site_name}} + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/en_US.yaml b/data/i18n/en_US.yaml new file mode 100644 index 000000000..eac322dac --- /dev/null +++ b/data/i18n/en_US.yaml @@ -0,0 +1,2395 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end + +backend: + base: + success: + other: Success. + unknown: + other: Unknown error. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + forbidden_error: + other: Forbidden. + duplicate_request_error: + other: Duplicate submission. + action: + report: + other: Flag + edit: + other: Edit + delete: + other: Delete + close: + other: Close + reopen: + other: Reopen + forbidden_error: + other: Forbidden. + pin: + other: Pin + hide: + other: Unlist + unpin: + other: Unpin + show: + other: List + invite_someone_to_answer: + other: Edit + undelete: + other: Undelete + merge: + other: Merge + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + privilege: + level_1: + description: + other: Level 1 (less reputation required for private team, group) + level_2: + description: + other: Level 2 (low reputation required for startup community) + level_3: + description: + other: Level 3 (high reputation required for mature community) + level_custom: + description: + other: Custom Level + rank_question_add_label: + other: Ask question + rank_answer_add_label: + other: Write answer + rank_comment_add_label: + other: Write comment + rank_report_add_label: + other: Flag + rank_comment_vote_up_label: + other: Upvote comment + rank_link_url_limit_label: + other: Post more than 2 links at a time + rank_question_vote_up_label: + other: Upvote question + rank_answer_vote_up_label: + other: Upvote answer + rank_question_vote_down_label: + other: Downvote question + rank_answer_vote_down_label: + other: Downvote answer + rank_invite_someone_to_answer_label: + other: Invite someone to answer + rank_tag_add_label: + other: Create new tag + rank_tag_edit_label: + other: Edit tag description (need to review) + rank_question_edit_label: + other: Edit other's question (need to review) + rank_answer_edit_label: + other: Edit other's answer (need to review) + rank_question_edit_without_review_label: + other: Edit other's question without review + rank_answer_edit_without_review_label: + other: Edit other's answer without review + rank_question_audit_label: + other: Review question edits + rank_answer_audit_label: + other: Review answer edits + rank_tag_audit_label: + other: Review tag edits + rank_tag_edit_without_review_label: + other: Edit tag description without review + rank_tag_synonym_label: + other: Manage tag synonyms + email: + other: Email + e_mail: + other: Email + password: + other: Password + pass: + other: Password + old_pass: + other: Current password + original_text: + other: This post + email_or_password_wrong_error: + other: Email and password do not match. + error: + common: + invalid_url: + other: Invalid URL. + status_invalid: + other: Invalid status. + password: + space_invalid: + other: Password cannot contain spaces. + admin: + cannot_update_their_password: + other: You cannot modify your password. + cannot_edit_their_profile: + other: You cannot modify your profile. + cannot_modify_self_status: + other: You cannot modify your status. + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + question_closed_cannot_add: + other: Questions are closed and cannot be added. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + illegal_email_domain_error: + other: Email is not allowed from that email domain. Please use another one. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + already_deleted: + other: This post has been deleted. + meta: + object_not_found: + other: Meta object not found + question: + already_deleted: + other: This post has been deleted. + under_review: + other: Your post is awaiting review. It will be visible after it has been approved. + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Reputation rank fail to meet the condition. + vote_fail_to_meet_the_condition: + other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. + no_enough_rank_to_operate: + other: You need at least {{.Rank}} reputation to do this. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + already_exist: + other: Tag already exists. + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + is_used_cannot_delete: + other: You cannot delete a tag that is in use. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: The from name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to revise. + user: + external_login_missing_user_id: + other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. + external_login_unbinding_forbidden: + other: Please set a login password for your account before you remove this login. + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration. + not_allowed_login_via_password: + other: Currently the site is not allowed to login via password. + access_denied: + other: Access denied + page_access_denied: + other: You do not have access to this page. + add_bulk_users_format_error: + other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + site_info: + config_not_found: + other: Site config not found. + badge: + object_not_found: + other: Badge object not found + reason: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude_or_abusive: + name: + other: rude or abusive + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + a_duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + placeholder: + other: Enter the existing question link + not_a_answer: + name: + other: not an answer + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." + no_longer_needed: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + something: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + placeholder: + other: Let us know specifically what you are concerned about + community_specific: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + not_clarity: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + looks_ok: + name: + other: looks OK + desc: + other: This post is good as-is and not low quality. + needs_edit: + name: + other: needs edit, and I did it + desc: + other: Improve and correct problems with this post yourself. + needs_close: + name: + other: needs close + desc: + other: A closed question can't answer, but still can edit, vote and comment. + needs_delete: + name: + other: needs delete + desc: + other: This post will be deleted. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + deleted_title: + other: Deleted question + questions_title: + other: Questions + tag: + tags_title: + other: Tags + no_description: + other: The tag has no description. + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted + up_voted_question: + other: upvoted question + down_voted_question: + other: downvoted question + up_voted_answer: + other: upvoted answer + down_voted_answer: + other: downvoted answer + up_voted_comment: + other: upvoted comment + invited_you_to_answer: + other: invited you to answer + earned_badge: + other: You've earned the "{{.BadgeName}}" badge + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Confirm your new email address" + body: + other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} answered your question" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_question: + title: + other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Password reset" + body: + other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + register: + title: + other: "[{{.SiteName}}] Confirm your new account" + body: + other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + test: + title: + other: "[{{.SiteName}}] Test Email" + body: + other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + action_activity_type: + upvote: + other: upvote + upvoted: + other: upvoted + downvote: + other: downvote + downvoted: + other: downvoted + accept: + other: accept + accepted: + other: accepted + edit: + other: edit + review: + queued_post: + other: Queued post + flagged_post: + other: Flagged post + suggested_post_edit: + other: Suggested edits + reaction: + tooltip: + other: "{{ .Names }} and {{ .Count }} more..." + badge: + default_badges: + autobiographer: + name: + other: Autobiographer + desc: + other: Filled out profile information. + certified: + name: + other: Certified + desc: + other: Completed our new user tutorial. + editor: + name: + other: Editor + desc: + other: First post edit. + first_flag: + name: + other: First Flag + desc: + other: First flagged a post. + first_upvote: + name: + other: First Upvote + desc: + other: First up voted a post. + first_link: + name: + other: First Link + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: First Share + desc: + other: First shared a post. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Leave 5 comments. + new_user_of_the_month: + name: + other: New User of the Month + desc: + other: Outstanding contributions in their first month. + read_guidelines: + name: + other: Read Guidelines + desc: + other: Read the [community guidelines]. + reader: + name: + other: Reader + desc: + other: Read every answers in a topic with more than 10 answers. + welcome: + name: + other: Welcome + desc: + other: Received a up vote. + nice_share: + name: + other: Nice Share + desc: + other: Shared a post with 25 unique visitors. + good_share: + name: + other: Good Share + desc: + other: Shared a post with 300 unique visitors. + great_share: + name: + other: Great Share + desc: + other: Shared a post with 1000 unique visitors. + out_of_love: + name: + other: Out of Love + desc: + other: Used 50 up votes in a day. + higher_love: + name: + other: Higher Love + desc: + other: Used 50 up votes in a day 5 times. + crazy_in_love: + name: + other: Crazy in Love + desc: + other: Used 50 up votes in a day 20 times. + promoter: + name: + other: Promoter + desc: + other: Invited a user. + campaigner: + name: + other: Campaigner + desc: + other: Invited 3 basic users. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: Thank You + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Active member for a year, posted at least once. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting + +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • mention a post: #post_id

        • +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by + placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + create_tag: Create Tag + edit_tag: Edit Tag + ask_a_question: Create Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + oauth_callback: Processing + http_404: HTTP Error 404 + http_50X: HTTP Error 500 + http_403: HTTP Error 403 + logout: Log Out + posts: Posts + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + new_alerts: New alerts + all_read: Mark all as read + show_more: Show more + someone: Someone + inbox_type: + all: All + posts: Posts + invites: Invites + votes: Votes + answer: Answer + question: Question + badge_award: Badge + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + contact_us: Contact us + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image file + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed {{size}} MB. + desc: + label: Description + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered list + unordered_list: + text: Bulleted list + table: + text: Table + heading: Heading + cell: Cell + file: + text: Attach files + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + not_a_url: URL format is incorrect. + url_not_match: URL origin does not match the current website. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description + revision: + label: Revision + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, + improved formatting) + btn_cancel: Cancel + btn_submit: Submit + btn_post: Post new tag + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + tip_with_posts: >- +

        We do not allow deleting tag with posts.

        +

        Please remove this tag from the posts first.

        + tip_with_synonyms: >- +

        We do not allow deleting tag with synonyms.

        +

        Please remove the synonyms from this tag first.

        + tip: Are you sure you wish to delete? + close: Close + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + default_first_reason: Add tag + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + hours: hours + days: days + month: month + months: months + year: year + reaction: + heart: heart + smile: smile + frown: frown + btn_label: add or remove reactions + undo_emoji: undo {{ emoji }} reaction + react_emoji: react with {{ emoji }} + unreact_emoji: unreact with {{ emoji }} + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: "{{count}} more comments" + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid + answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are + adding new information, edit your post instead of commenting. + tip_vote: It adds something useful to the post + edit_answer: + title: Edit Answer + default_reason: Edit answer + default_first_reason: Add answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, + improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: Newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + wiki: Wiki + ask: + title: Create Question + edit_title: Edit Question + default_reason: Edit question + default_first_reason: Create question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: What's your topic? Be specific. + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, + improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + badges: Badges + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + bookmark: Bookmarks + moderation: Moderation + search: + placeholder: Search + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. + Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might + take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + resend_email: + url_label: Are you sure you want to resend the activation email? + url_text: You can also give the activation link above to the user. + login: + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email + with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email + with instructions on how to reset your password shortly. + email: + label: New email + msg: + empty: Email cannot be empty. + oauth: + connect: Connect with {{ auth_name }} + remove: Remove {{ auth_name }} + oauth_bind_email: + subtitle: Add a recovery email to your account. + btn_update: Update email address + email: + label: Email + msg: + empty: Email cannot be empty. + modal_title: Email already existes. + modal_content: This email address already registered. Are you sure you want to connect to the existing account? + modal_cancel: Change email + modal_confirm: Connect to the existing account + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in + page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is + already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm new password + settings: + page_title: Settings + goto_modify: Go to modify + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile image + gravatar: Gravatar + gravatar_text: You can change image on + custom: Custom + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About me + website: + label: Website + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location + placeholder: "City, Country" + notification: + heading: Email Notifications + turn_on: Turn on + inbox: + label: Inbox notifications + description: Answers to your questions, comments, invites, and more. + all_new_question: + label: All new questions + description: Get notified of all new questions. Up to 50 questions per week. + all_new_question_for_following_tags: + label: All new questions for following tags + description: Get notified of new questions for following tags. + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation + instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + pass: + label: Current password + msg: Password cannot be empty. + password_title: Password + current_pass: + label: Current password + msg: + empty: Current password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New password + pass_confirm: + label: Confirm new password + interface: + heading: Interface + lang: + label: Interface language + text: User interface language. It will change when you refresh the page. + my_logins: + title: My logins + label: Log in or sign up on this site using these accounts. + modal_title: Remove login + modal_content: Are you sure you want to remove this login from your account? + modal_confirm_btn: Remove + remove_success: Removed successfully + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + sent_success: Sent successfully + related_question: + title: Related + answers: answers + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Invite People + desc: Invite people you think can answer. + invite: Invite to answer + add: Add people + search: Search people + question_detail: + action: Action + created: Created + Asked: Asked + asked: asked + update: Modified + Edited: Edited + edit: edited + commented: commented + Views: Viewed + Follow: Follow + Following: Following + follow_tip: Follow this question to receive notifications + answered: answered + closed_in: Closed in + show_exist: Show existing question. + useful: Useful + question_useful: It is useful and clear + question_un_useful: It is unclear or not useful + question_bookmark: Bookmark this question + answer_useful: It is useful + answer_un_useful: It is not useful + answers: + title: Answers + score: Score + newest: Newest + oldest: Oldest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + edit_answer: Edit my existing answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the + edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + tips: + header_1: Thanks for your answer + li1_1: Please be sure to answer the question. Provide details and share your research. + li1_2: Back up any statements you make with references or personal experience. + header_2: But avoid ... + li2_1: Asking for help, seeking clarification, or responding to other answers. + reopen: + confirm_btn: Reopen + title: Reopen this post + content: Are you sure you want to reopen? + list: + confirm_btn: List + title: List this post + content: Are you sure you want to list? + unlist: + confirm_btn: Unlist + title: Unlist this post + content: Are you sure you want to unlist? + pin: + title: Pin this post + content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. + confirm_btn: Pin + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because + doing so deprives future readers of this knowledge.

        Repeated deletion + of answered questions can result in your account being blocked from asking. + Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because + doing so deprives future readers of this knowledge.

        Repeated deletion + of accepted answers can result in your account being blocked from answering. + Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_answer_deleted: This answer has been deleted + undelete_title: Undelete this post + undelete_desc: Are you sure you wish to undelete? + btns: + confirm: Confirm + cancel: Cancel + edit: Edit + save: Save + delete: Delete + undelete: Undelete + list: List + unlist: Unlist + unlisted: Unlisted + login: Log in + signup: Sign up + logout: Log out + verify: Verify + create: Create + approve: Approve + reject: Reject + skip: Skip + discard_draft: Discard draft + pinned: Pinned + all: All + question: Question + answer: Answer + comment: Comment + refresh: Refresh + resend: Resend + deactivate: Deactivate + active: Active + suspend: Suspend + unsuspend: Unsuspend + close: Close + reopen: Reopen + ok: OK + light: Light + dark: Dark + system_setting: System setting + default: Default + reset: Reset + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignore + submit: Submit + normal: Normal + closed: Closed + deleted: Deleted + deleted_permanently: Deleted permanently + pending: Pending + more: More + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + counts_loading: "... Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post. + modal_confirm: + title: Error... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was + already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + x_posts: "{{ count }} Posts" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + frequent: Frequent + recommend: Recommend + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + badges: Badges + newest: Newest + score: Score + edit_profile: Edit profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + comma: "," + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + content_empty: No posts found. + accepted: Accepted + answered: answered + asked: asked + downvoted: downvoted + mod_short: MOD + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + recent_badges: Recent Badges + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please choose a language + db_type: + label: Database engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database host + placeholder: "db:3306" + msg: Database host cannot be empty. + db_name: + label: Database name + placeholder: answer + msg: Database name cannot be empty. + db_file: + label: Database file + placeholder: /data/answer.db + msg: Database file cannot be empty. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the + <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site name + msg: Site name cannot be empty. + msg_max_length: Site name must be at maximum 30 characters in length. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + max_length: Site URL must be at maximum 512 characters in length. + contact_email: + label: Contact email + text: Email address of key contact responsible for this site. + msg: + empty: Contact email cannot be empty. + incorrect: Contact email incorrect format. + login_required: + label: Private + switch: Login required + text: Only logged in users can access this community. + admin_name: + label: Name + msg: Name cannot be empty. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure + location. + msg: Password cannot be empty. + msg_min_length: Password must be at least 8 characters in length. + msg_max_length: Password must be at maximum 32 characters in length. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; + find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the + configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old + database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_error: + http_error: HTTP Error {{ code }} + desc_403: You don't have permission to access this page. + desc_404: Unfortunately, this page doesn't exist. + desc_50X: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + badges: Badges + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + terms: Terms + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + login: Login + privileges: Privileges + plugins: Plugins + installed_plugins: Installed Plugins + apperance: Appearance + website_welcome: Welcome to {{site_name}} + user_center: + login: Login + qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. + login_failed_email_tip: Login failed, please allow this app to access your email information before try again. + badges: + modal: + title: Congratulations + content: You've earned a new badge. + close: Close + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site statistics + questions: "Questions:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + users: "Users:" + flags: "Flags:" + reviews: "Reviews:" + site_health: Site health + version: "Version:" + https: "HTTPS:" + upload_folder: "Upload folder:" + run_mode: "Running mode:" + private: Private + public: Public + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System info + go_version: "Go version:" + database: "Database:" + database_size: "Database size:" + storage_used: "Storage used:" + uptime: "Uptime:" + links: Links + plugins: Plugins + github: GitHub + blog: Blog + contact: Contact + forum: Forum + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + writable: Writable + not_writable: Not writable + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + flagged_type: Flagged {{ type }} + created: Created + action: Action + review: Review + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + edit_profile_modal: + title: Edit profile + form: + fields: + display_name: + label: Display name + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Invalid Email Address. + edit_success: Edited successfully + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + users: + label: Bulk add user + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separate “name, email, password” with commas. One user per line. + msg: "Please enter the user's email, one per line." + display_name: + label: Display name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + more: More + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + edit_profile: Edit profile + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + deactivate_user: + title: Deactivate user + content: An inactive user must re-validate their email. + delete_user: + title: Delete this user + content: Are you sure you want to delete this user? This is permanent! + remove: Remove their content + label: Remove all questions, answers, comments, etc. + text: Don’t check this if you wish to only delete the user’s account. + suspend_user: + title: Suspend this user + content: A suspended user can't log in. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Questions + unlisted: Unlisted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + pending: Pending + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short site description + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site description + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + check_update: + label: Software updates + text: Automatically check for updates + interface: + page_title: Interface + language: + label: Interface language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: From email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + tls: TLS + none: None + smtp_port: + label: SMTP port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test email recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile logo + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square icon + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Write + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Each user can only write one answer for the same question + text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Recommend tags + text: "Recommend tags will show in the dropdown list by default." + msg: + contain_reserved: "recommended tags cannot contain reserved tags" + required_tag: + title: Set required tags + label: Set “Recommend tags” as required tags + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved tags + text: "Reserved tags can only be used by moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + color_scheme: + label: Color scheme + navbar_style: + label: Navbar background style + primary_color: + label: Primary color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as <link> + head: + label: Head + text: This will insert before </head> + header: + label: Header + text: This will insert after <body> + footer: + label: Footer + text: This will insert before </body>. + sidebar: + label: Sidebar + text: This will insert in sidebar. + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + email_registration: + title: Email registration + label: Allow email registration + text: Turn off to prevent anyone creating new account through email. + allowed_email_domains: + title: Allowed email domains + text: Email domains that users must register accounts with. One domain per line. Ignored when empty. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + password_login: + title: Password login + label: Allow email and password login + text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." + installed_plugins: + title: Installed Plugins + plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + filter: + all: All + active: Active + inactive: Inactive + outdated: Outdated + plugins: + label: Plugins + text: Select an existing plugin. + name: Name + version: Version + status: Status + action: Action + deactivate: Deactivate + activate: Activate + settings: Settings + settings_users: + title: Users + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + profile_editable: + title: Profile editable + allow_update_display_name: + label: Allow users to change their display name + allow_update_username: + label: Allow users to change their username + allow_update_avatar: + label: Allow users to change their profile image + allow_update_bio: + label: Allow users to change their about me + allow_update_website: + label: Allow users to change their website + allow_update_location: + label: Allow users to change their location + privilege: + title: Privileges + level: + label: Reputation required level + text: Choose the reputation required for the privileges + msg: + should_be_number: the input should be number + number_larger_1: number should be equal or larger than 1 + badges: + action: Action + active: Active + activate: Activate + all: All + awards: Awards + deactivate: Deactivate + filter: + placeholder: Filter by name, badge:id + group: Group + inactive: Inactive + name: Name + show_logs: Show logs + status: Status + title: Badges + form: + optional: (optional) + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + select: Select + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + approve_revision_tip: Do you approve this revision? + approve_flag_tip: Do you approve this flag? + approve_post_tip: Do you approve this post? + approve_user_tip: Do you approve this user? + suggest_edits: Suggested edits + flag_post: Flag post + flag_user: Flag user + queued_post: Queued post + queued_user: Queued user + filter_label: Type + reputation: reputation + flag_post_type: Flagged this post as {{ type }}. + flag_user_type: Flagged this user as {{ type }}. + edit_post: Edit post + list_post: List post + unlist_post: Unlist post + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + pin: pinned + unpin: unpinned + show: listed + hide: unlisted + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores this week + users_with_the_most_vote: Users who voted the most this week + staffs: Our community staff + reputation: reputation + votes: votes + prompt: + leave_page: Are you sure you want to leave the page? + changes_not_save: Your changes may not be saved. + draft: + discard_confirm: Are you sure you want to discard your draft? + messages: + post_deleted: This post has been deleted. + post_cancel_deleted: This post has been undeleted. + post_pin: This post has been pinned. + post_unpin: This post has been unpinned. + post_hide_list: This post has been hidden from list. + post_show_list: This post has been shown to list. + post_reopen: This post has been reopened. + post_list: This post has been listed. + post_unlist: This post has been unlisted. + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/es_ES.yaml b/data/i18n/es_ES.yaml new file mode 100644 index 000000000..171c143d3 --- /dev/null +++ b/data/i18n/es_ES.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Completado. + unknown: + other: Error desconocido. + request_format_error: + other: Formato de la solicitud inválido. + unauthorized_error: + other: No autorizado. + database_error: + other: Error en el servidor de datos. + forbidden_error: + other: Prohibido. + duplicate_request_error: + other: Solicitud duplicada. + action: + report: + other: Reportar + edit: + other: Editar + delete: + other: Eliminar + close: + other: Cerrar + reopen: + other: Reabrir + forbidden_error: + other: Prohibido. + pin: + other: Fijar + hide: + other: Retirar + unpin: + other: Desfijar + show: + other: Lista + invite_someone_to_answer: + other: Editar + undelete: + other: Recuperar + merge: + other: Merge + role: + name: + user: + other: Usuario + admin: + other: Administrador + moderator: + other: Moderador + description: + user: + other: Predeterminado sin acceso especial. + admin: + other: Dispone de acceso total al sitio web y sus ajustes. + moderator: + other: Dispone de acceso a todas las publicaciones pero no a los ajustes de administrador. + privilege: + level_1: + description: + other: Nivel 1 (reputación menor requerida para un equipo privado, grupo) + level_2: + description: + other: Nivel 2 (reputación baja requerida para una comunidad de Startup) + level_3: + description: + other: Nivel 3 (reputación alta requerida para una comunidad madura) + level_custom: + description: + other: Nivel personalizado + rank_question_add_label: + other: Hacer una pregunta + rank_answer_add_label: + other: Escribir respuesta + rank_comment_add_label: + other: Escribir comentario + rank_report_add_label: + other: Reportar + rank_comment_vote_up_label: + other: Votar comentario a favor + rank_link_url_limit_label: + other: Publica más de 2 enlaces a la vez + rank_question_vote_up_label: + other: Votar pregunta a favor + rank_answer_vote_up_label: + other: Votar respuesta a favor + rank_question_vote_down_label: + other: Votar pregunta en contra + rank_answer_vote_down_label: + other: Votar respuesta en contra + rank_invite_someone_to_answer_label: + other: Invitar a alguien a responder + rank_tag_add_label: + other: Crear nueva etiqueta + rank_tag_edit_label: + other: Editar descripción de etiqueta (revisión necesaria) + rank_question_edit_label: + other: Editar pregunta ajena (revisión necesaria) + rank_answer_edit_label: + other: Editar respuesta ajena (revisión necesaria) + rank_question_edit_without_review_label: + other: Editar pregunta ajena sin revisión + rank_answer_edit_without_review_label: + other: Editar respuesta ajena sin revisión + rank_question_audit_label: + other: Revisar ediciones de pregunta + rank_answer_audit_label: + other: Revisar ediciones de respuesta + rank_tag_audit_label: + other: Revisar ediciones de etiqueta + rank_tag_edit_without_review_label: + other: Editar descripción de etiqueta sin revisión + rank_tag_synonym_label: + other: Administrar sinónimos de etiqueta + email: + other: Correo electrónico + e_mail: + other: Correo electrónico + password: + other: Contraseña + pass: + other: Contraseña + old_pass: + other: Current password + original_text: + other: Esta publicación + email_or_password_wrong_error: + other: Contraseña o correo incorrecto. + error: + common: + invalid_url: + other: URL no válido. + status_invalid: + other: Estado inválido. + password: + space_invalid: + other: La contraseña no puede contener espacios. + admin: + cannot_update_their_password: + other: No puede modificar su contraseña. + cannot_edit_their_profile: + other: No puede modificar su perfil. + cannot_modify_self_status: + other: No puede modificar su contraseña. + email_or_password_wrong: + other: Contraseña o correo incorrecto. + answer: + not_found: + other: Respuesta no encontrada. + cannot_deleted: + other: Sin permiso para eliminar. + cannot_update: + other: Sin permiso para actualizar. + question_closed_cannot_add: + other: Las preguntas están cerradas y no pueden añadirse. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Edición del comentario no permitida. + not_found: + other: Comentario no encontrado. + cannot_edit_after_deadline: + other: El tiempo del comentario ha sido demasiado largo para modificarlo. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: Correo electrónico ya en uso. + need_to_be_verified: + other: El correo debe ser verificado. + verify_url_expired: + other: La URL verificada del correo electrónico ha caducado. Por favor, vuelva a enviar el correo electrónico. + illegal_email_domain_error: + other: No está permitido el correo electrónico de ese dominio. Por favor utilice otro. + lang: + not_found: + other: Archivo de idioma no encontrado. + object: + captcha_verification_failed: + other: Captcha fallido. + disallow_follow: + other: No dispones de permiso para seguir. + disallow_vote: + other: No dispones de permiso para votar. + disallow_vote_your_self: + other: No puedes votar a tu propia publicación. + not_found: + other: Objeto no encontrado. + verification_failed: + other: Verificación fallida. + email_or_password_incorrect: + other: Contraseña o correo incorrecto. + old_password_verification_failed: + other: La verificación de la contraseña antigua falló + new_password_same_as_previous_setting: + other: La nueva contraseña es igual a la anterior. + already_deleted: + other: Esta publicación ha sido borrada. + meta: + object_not_found: + other: Meta objeto no encontrado + question: + already_deleted: + other: Esta publicación ha sido eliminada. + under_review: + other: Tu publicación está siendo revisada. Será visible una vez sea aprobada. + not_found: + other: Pregunta no encontrada. + cannot_deleted: + other: Sin permiso para eliminar. + cannot_close: + other: Sin permiso para cerrar. + cannot_update: + other: Sin permiso para actualizar. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: El rango de reputación no cumple la condición. + vote_fail_to_meet_the_condition: + other: Gracias por los comentarios. Necesitas al menos reputación {{.Rank}} para votar. + no_enough_rank_to_operate: + other: Necesitas al menos reputación {{.Rank}} para hacer esto. + report: + handle_failed: + other: Error en el manejador del reporte. + not_found: + other: Informe no encontrado. + tag: + already_exist: + other: La etiqueta ya existe. + not_found: + other: Etiqueta no encontrada. + recommend_tag_not_found: + other: La etiqueta recomendada no existe. + recommend_tag_enter: + other: Por favor, introduce al menos una de las etiquetas requeridas. + not_contain_synonym_tags: + other: No debe contener etiquetas sinónimas. + cannot_update: + other: Sin permiso para actualizar. + is_used_cannot_delete: + other: No puedes eliminar una etiqueta que está en uso. + cannot_set_synonym_as_itself: + other: No se puede establecer como sinónimo de una etiqueta la propia etiqueta. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: El nombre no puede ser una dirección de correo electrónico. + theme: + not_found: + other: Tema no encontrado. + revision: + review_underway: + other: No se puede editar actualmente, hay una versión en la cola de revisiones. + no_permission: + other: Sin permisos para ver. + user: + external_login_missing_user_id: + other: La plataforma de terceros no proporciona un UserID único, por lo que si no puede iniciar sesión, contacte al administrador del sitio. + external_login_unbinding_forbidden: + other: Por favor añada una contraseña de inicio de sesión a su cuenta antes de eliminar este método de acceso. + email_or_password_wrong: + other: + other: Contraseña o correo incorrecto. + not_found: + other: Usuario no encontrado. + suspended: + other: El usuario ha sido suspendido. + username_invalid: + other: Nombre de usuario no válido. + username_duplicate: + other: El nombre de usuario ya está en uso. + set_avatar: + other: Fallo al actualizar el avatar. + cannot_update_your_role: + other: No puedes modificar tu propio rol. + not_allowed_registration: + other: Actualmente el sitio no está abierto para el registro. + not_allowed_login_via_password: + other: Actualmente el sitio no está abierto para iniciar sesión por contraseña. + access_denied: + other: Acceso denegado + page_access_denied: + other: No tienes acceso a esta página. + add_bulk_users_format_error: + other: "Error {{.Field}} formato cerca de '{{.Content}}' en la línea {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "El número de usuarios que añadas a la vez debe estar en el rango de 1 a {{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Lectura de configuración fallida + database: + connection_failed: + other: Conexión a la base de datos fallida + create_table_failed: + other: Creación de tabla fallida + install: + create_config_failed: + other: No es posible crear el archivo config.yaml. + upload: + unsupported_file_format: + other: Formato de archivo no soportado. + site_info: + config_not_found: + other: Configuración del sitio no encontrada. + badge: + object_not_found: + other: Insignia no encontrada + reason: + spam: + name: + other: correo no deseado + desc: + other: Esta publicación es un anuncio, o vandalismo. No es útil o relevante para el tema actual. + rude_or_abusive: + name: + other: grosero u ofensivo + desc: + other: "Alguna persona podría considerar este contenido inapropiado para una discusión respetuosa." + a_duplicate: + name: + other: un duplicado + desc: + other: Esta pregunta ha sido hecha antes y ya ha sido resuelta. + placeholder: + other: Introduce el enlace de la pregunta existente + not_a_answer: + name: + other: no es una respuesta + desc: + other: "Esto fue publicado como respuesta pero no intenta responder a la pregunta. Podría ser una edición, un comentario, otra pregunta diferente o ser eliminado por completo." + no_longer_needed: + name: + other: ya no es necesario + desc: + other: Este comentario está desactualizado, es conversacional o no es relevante a esta publicación. + something: + name: + other: otro motivo + desc: + other: Esta publicación requiere revisión del personal por otro motivo no listado arriba. + placeholder: + other: Háganos saber qué le interesa en concreto + community_specific: + name: + other: un motivo determinado de la comunidad + desc: + other: Esta pregunta no cumple con una norma comunitaria. + not_clarity: + name: + other: requiere detalles o aclaraciones + desc: + other: Esta pregunta actualmente incluye múltiples preguntas en una. Debería enfocarse en una única cuestión. + looks_ok: + name: + other: parece correcto + desc: + other: Esta publicación es buena como es y no es de baja calidad. + needs_edit: + name: + other: necesita editarse, y lo hice + desc: + other: Mejora y corrige los problemas con esta publicación personalmente. + needs_close: + name: + other: necesita cerrar + desc: + other: Una pregunta cerrada no puede responderse, pero aún se puede editar, votar y comentar. + needs_delete: + name: + other: necesita eliminación + desc: + other: Esta publicación será eliminada. + question: + close: + duplicate: + name: + other: correo no deseado + desc: + other: La pregunta ya ha sido preguntada y resuelta previamente. + guideline: + name: + other: razón específica de la comunidad + desc: + other: Esta pregunta infringe alguna norma de la comunidad. + multiple: + name: + other: necesita más detalles o aclaraciónes + desc: + other: Esta pregunta incluye múltiples preguntas en una sola. Debería centrarse únicamente en un solo tema. + other: + name: + other: otra razón + desc: + other: Esta publicación requiere otra razón no listada arriba. + operation_type: + asked: + other: preguntada + answered: + other: respondida + modified: + other: modificada + deleted_title: + other: Pregunta eliminada + questions_title: + other: Preguntas + tag: + tags_title: + other: Etiquetas + no_description: + other: La etiqueta no tiene descripción. + notification: + action: + update_question: + other: pregunta actualizada + answer_the_question: + other: pregunta respondidas + update_answer: + other: respuesta actualizada + accept_answer: + other: respuesta aceptada + comment_question: + other: pregunta comentada + comment_answer: + other: respuesta comentada + reply_to_you: + other: te ha respondido + mention_you: + other: te ha mencionado + your_question_is_closed: + other: Tu pregunta ha sido cerrada + your_question_was_deleted: + other: Tu pregunta ha sido eliminada + your_answer_was_deleted: + other: Tu respuesta ha sido eliminada + your_comment_was_deleted: + other: Tu comentario ha sido eliminado + up_voted_question: + other: pregunta votada a favor + down_voted_question: + other: pregunta votada en contra + up_voted_answer: + other: respuesta votada a favor + down_voted_answer: + other: respuesta votada en contra + up_voted_comment: + other: comentario votado a favor + invited_you_to_answer: + other: te invitó a responder + earned_badge: + other: Ha ganado la insignia "{{.BadgeName}}" + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Confirma tu nueva dirección de correo" + body: + other: "Confirme su nueva dirección de correo electrónico para {{.SiteName}} haciendo clic en el siguiente enlace:
        \n{{.ChangeEmailUrl}}

        \n\nSi no solicitó este cambio, por favor, ignore este mensaje.

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} respondió tu pregunta" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nVerlo en {{.SiteName}}

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída.

        \n\nDarse de baja" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} te invitó a responder" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Es posible que conozca la respuesta.

        \nVerlo en {{.SiteName}}

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída.

        \n\nDarse de baja" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} comentó en tu publicación" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nVerlo en {{.SiteName}}

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída.

        \n\nDarse de baja" + new_question: + title: + other: "[{{.SiteName}}] Nueva pregunta: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Reestablecimiento de contraseña" + body: + other: "Se solicitó el restablecimiento de su contraseña en {{.SiteName}}.

        \n\nSi no lo solicitó, puede ignorar este mensaje.

        \n\nHaga clic en el siguiente enlace para generar una nueva contraseña:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída." + register: + title: + other: "[{{.SiteName}}] Confirma tu nueva cuenta" + body: + other: "¡Bienvenido a {{.SiteName}}!

        \n\nHaga clic en el siguiente enlace y active su nueva cuenta:
        \n{{.RegisterUrl}}

        \n\nSi no puede hacer clic en el enlace anterior, intente copiando y pegando el enlace en la barra de dirección en su navegador web.

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída." + test: + title: + other: "[{{.SiteName}}] Correo de prueba" + body: + other: "Este es un mensaje de prueba.\n

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída." + action_activity_type: + upvote: + other: votar a favor + upvoted: + other: votado a favor + downvote: + other: voto negativo + downvoted: + other: votado en contra + accept: + other: aceptar + accepted: + other: aceptado + edit: + other: editar + review: + queued_post: + other: Publicación en cola + flagged_post: + other: Publicación marcada + suggested_post_edit: + other: Ediciones sugeridas + reaction: + tooltip: + other: "{{ .Names }} y {{ .Count }} más..." + badge: + default_badges: + autobiographer: + name: + other: Autobiógrafo + desc: + other: Completó la información de su perfil. + certified: + name: + other: Certificado + desc: + other: Completó nuestro nuevo tutorial de usuario. + editor: + name: + other: Editor + desc: + other: Primer mensaje editado. + first_flag: + name: + other: Primera Denuncia + desc: + other: Primer denuncia de un post. + first_upvote: + name: + other: Primer voto favorable + desc: + other: Primera vez que le doy un 'like' a un post. + first_link: + name: + other: Primer Enlace + desc: + other: First added a link to another post. + first_reaction: + name: + other: Primera reacción + desc: + other: Primero reaccionó al post. + first_share: + name: + other: Primer Compartir + desc: + other: Primero compartió un post. + scholar: + name: + other: Erudito + desc: + other: Hecha una pregunta y aceptada una respuesta. + commentator: + name: + other: Comentador + desc: + other: Deja 5 comentarios. + new_user_of_the_month: + name: + other: Nuevo usuario del mes + desc: + other: Contribuciones pendientes en su primer mes. + read_guidelines: + name: + other: Lea los lineamientos + desc: + other: Lea las [directrices de la comunidad]. + reader: + name: + other: Lector + desc: + other: Lee cada respuesta en un tema con más de 10 respuestas. + welcome: + name: + other: Bienvenido + desc: + other: Recibió un voto a favor. + nice_share: + name: + other: Buena Compartición + desc: + other: Compartió un post con 25 visitantes únicos. + good_share: + name: + other: Buena Compartida + desc: + other: Compartió un post con 300 visitantes únicos. + great_share: + name: + other: Excelente Compartida + desc: + other: Compartió un post con 1000 visitantes únicos. + out_of_love: + name: + other: Fuera del Amor + desc: + other: Utilizó 50 votos positivos en un día. + higher_love: + name: + other: Amor Más Alto + desc: + other: Utilizó 50 votos positivos en un día 5 veces. + crazy_in_love: + name: + other: Loco(a) por el Amor + desc: + other: Utilizó 50 votos positivos en un día 20 veces. + promoter: + name: + other: Promotor + desc: + other: Invitó a un usuario. + campaigner: + name: + other: Activista + desc: + other: Invitó a 3 usuarios básicos. + champion: + name: + other: Campeón + desc: + other: Invitado 5 miembros. + thank_you: + name: + other: Gracias + desc: + other: Tiene 20 publicaciones con votos positivos y dio 10 votos positivos. + gives_back: + name: + other: Da a Cambio + desc: + other: Tiene 100 publicaciones con votos positivos y dio 100 votos positivos. + empathetic: + name: + other: Empático + desc: + other: Tiene 500 publicaciones con votos positivos y dio 1000 votos positivos. + enthusiast: + name: + other: Entusiasta + desc: + other: Visita 10 días consecutivos. + aficionado: + name: + other: Aficionado + desc: + other: Visita 100 días consecutivos. + devotee: + name: + other: Devoto + desc: + other: Visita 365 días consecutivos. + anniversary: + name: + other: Aniversario + desc: + other: Miembro activo por un año, publicó al menos una vez. + appreciated: + name: + other: Apreciación + desc: + other: Recibió 1 voto positivo en 20 puestos. + respected: + name: + other: Respetado + desc: + other: Recibió 2 voto positivo en 100 puestos. + admired: + name: + other: Admirado + desc: + other: Recibió 5 voto positivo en 300 puestos. + solved: + name: + other: Resuelto + desc: + other: Tener una respuesta aceptada. + guidance_counsellor: + name: + other: Consejero de Orientación + desc: + other: Tener 10 respuestas aceptadas. + know_it_all: + name: + other: Sabelotodo + desc: + other: Tener 50 respuestas aceptadas. + solution_institution: + name: + other: Institución de Soluciones + desc: + other: Tener 150 respuestas aceptadas. + nice_answer: + name: + other: Buena Respuesta + desc: + other: Respuesta con una puntuación de 10 o más. + good_answer: + name: + other: Excelente Respuesta + desc: + other: Respuesta con una puntuación de 25 o más. + great_answer: + name: + other: Gran Respuesta + desc: + other: Respuesta con una puntuación de 50 o más. + nice_question: + name: + other: Buena Pregunta + desc: + other: Pregunta con una puntuación de 10 o más. + good_question: + name: + other: Excelente Pregunta + desc: + other: Pregunta con una puntuación de 25 o más. + great_question: + name: + other: Gran Pregunta + desc: + other: Pregunta con una puntuación de 50 o más. + popular_question: + name: + other: Pregunta popular + desc: + other: Pregunta con 500 puntos de vista. + notable_question: + name: + other: Pregunta Notable + desc: + other: Pregunta con 1,000 vistas. + famous_question: + name: + other: Pregunta Famosa + desc: + other: Pregunta con 5,000 vistas. + popular_link: + name: + other: Enlace Popular + desc: + other: Publicado un enlace externo con 50 clics. + hot_link: + name: + other: Enlace caliente + desc: + other: Publicado un enlace externo con 300 clics. + famous_link: + name: + other: Enlace familiar + desc: + other: Publicado un enlace externo con 100 clics. + default_badge_groups: + getting_started: + name: + other: Primeros pasos + community: + name: + other: Comunidad + posting: + name: + other: Publicación +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Cómo formatear + desc: >- +
        • menciona una publicación: #post_id

        • para hacer enlaces

          <https://url.com>

          [Título](https://url.com)
        • poner retornos entre párrafos

        • _italic_ o **negrita**

        • sangría del código con 4 espacios

        • cita colocando > al inicio de la línea

        • comillas invertidas se escapa `like _this_`

        • crear barreras de código con comillas invertidas `

          ```
          código aquí
          ```
        + pagination: + prev: Anterior + next: Siguiente + page_title: + question: Pregunta + questions: Preguntas + tag: Etiqueta + tags: Etiquetas + tag_wiki: wiki de Etiquetas + create_tag: Crear etiqueta + edit_tag: Editar etiqueta + ask_a_question: Create Question + edit_question: Editar Pregunta + edit_answer: Editar respuesta + search: Buscar + posts_containing: Publicaciones que contienen + settings: Ajustes + notifications: Notificaciones + login: Acceder + sign_up: Registrarse + account_recovery: Recuperación de la cuenta + account_activation: Activación de la cuenta + confirm_email: Confirmar correo electrónico + account_suspended: Cuenta suspendida + admin: Administrador + change_email: Modificar correo + install: Instalación de Answer + upgrade: Actualización de Answer + maintenance: Mantenimiento del sitio web + users: Usuarios + oauth_callback: Procesando + http_404: HTTP Error 404 + http_50X: HTTP Error 500 + http_403: HTTP Error 403 + logout: Cerrar sesión + posts: Posts + notifications: + title: Notificaciones + inbox: Buzón de entrada + achievement: Logros + new_alerts: Nuevas alertas + all_read: Marcar todo como leído + show_more: Mostrar más + someone: Alguien + inbox_type: + all: Todo + posts: Publicaciones + invites: Invitaciones + votes: Votos + answer: Respuesta + question: Pregunta + badge_award: Medalla + suspended: + title: Tu cuenta ha sido suspendida + until_time: "Tu cuenta ha sido suspendida hasta el {{ time }}." + forever: Este usuario ha sido suspendido indefinidamente. + end: Has infringido alguna norma de la comunidad. + contact_us: Contáctanos + editor: + blockquote: + text: Cita + bold: + text: Negrita + chart: + text: Gráfica + flow_chart: Diagrama de flujo + sequence_diagram: Diagrama de secuencia + class_diagram: Diagrama de clase + state_diagram: Diagrama de estado + entity_relationship_diagram: Diagrama de relación de entidad + user_defined_diagram: Diagrama definido por el usuario + gantt_chart: Diagrama de Gantt + pie_chart: Grafico de torta + code: + text: Código + add_code: Añadir código + form: + fields: + code: + label: Código + msg: + empty: Código no puede estar vacío. + language: + label: Idioma + placeholder: Detección automática + btn_cancel: Cancelar + btn_confirm: Añadir + formula: + text: Fórmula + options: + inline: Fórmula en línea + block: Bloque de fórmula + heading: + text: Encabezado + options: + h1: Encabezado 1 + h2: Encabezado 2 + h3: Encabezado 3 + h4: Encabezado 4 + h5: Encabezado 5 + h6: Encabezado 6 + help: + text: Ayuda + hr: + text: Regla horizontal + image: + text: Imagen + add_image: Añadir imagen + tab_image: Subir imagen + form_image: + fields: + file: + label: Archivo de imagen + btn: Seleccionar imagen + msg: + empty: El título no puede estar vacío. + only_image: Solo se permiten archivos de imagen. + max_size: El tamaño del archivo no puede exceder {{size}} MB. + desc: + label: Descripción + tab_url: URL de la imagen + form_url: + fields: + url: + label: URL de la imagen + msg: + empty: La URL de la imagen no puede estar vacía. + name: + label: Descripción + btn_cancel: Cancelar + btn_confirm: Añadir + uploading: Subiendo + indent: + text: Sangría + outdent: + text: Quitar sangría + italic: + text: Cursiva + link: + text: Enlace + add_link: Añadir enlace + form: + fields: + url: + label: Por sus siglas en ingles (Localizador Uniforme de recursos), dirección electrónica de un sitio web + msg: + empty: La dirección no puede estar vacía. + name: + label: Descripción + btn_cancel: Cancelar + btn_confirm: Añadir + ordered_list: + text: Lista numerada + unordered_list: + text: Lista con viñetas + table: + text: Tabla + heading: Encabezado + cell: Celda + file: + text: Adjuntar archivos + not_supported: "No soporta ese tipo de archivo. Inténtalo de nuevo con {{file_type}}." + max_size: "El tamaño de los archivos adjuntos no puede exceder {{size}} MB." + close_modal: + title: Estoy cerrando este post como... + btn_cancel: Cancelar + btn_submit: Enviar + remark: + empty: No puede estar en blanco. + msg: + empty: Por favor selecciona una razón. + report_modal: + flag_title: Estoy marcando para reportar este post de... + close_title: Estoy cerrando este post como... + review_question_title: Revisar pregunta + review_answer_title: Revisar respuesta + review_comment_title: Revisar comentario + btn_cancel: Cancelar + btn_submit: Enviar + remark: + empty: No puede estar en blanco. + msg: + empty: Por favor selecciona una razón. + not_a_url: El formato de la URL es incorrecto. + url_not_match: El origen de la URL no coincide con el sitio web actual. + tag_modal: + title: Crear nueva etiqueta + form: + fields: + display_name: + label: Nombre público + msg: + empty: El nombre a mostrar no puede estar vacío. + range: Nombre a mostrar con un máximo de 35 caracteres. + slug_name: + label: Ruta de la URL + desc: Slug de URL de hasta 35 caracteres. + msg: + empty: URL no puede estar vacío. + range: URL slug hasta 35 caracteres. + character: La URL amigable contiene caracteres no permitidos. + desc: + label: Descripción + revision: + label: Revisión + edit_summary: + label: Editar resumen + placeholder: >- + Explica brevemente los cambios (corrección ortográfica, mejora de formato) + btn_cancel: Cancelar + btn_submit: Enviar + btn_post: Publicar nueva etiqueta + tag_info: + created_at: Creado + edited_at: Editado + history: Historial + synonyms: + title: Sinónimos + text: Las siguientes etiquetas serán reasignadas a + empty: No se encontraron sinónimos. + btn_add: Añadir un sinónimo + btn_edit: Editar + btn_save: Guardar + synonyms_text: Las siguientes etiquetas serán reasignadas a + delete: + title: Eliminar esta etiqueta + tip_with_posts: >- +

        No permitimos eliminar etiquetas con publicaciones.

        Primero elimine esta etiqueta de las publicaciones.

        + tip_with_synonyms: >- +

        No permitimos eliminar etiqueta con sinónimos.

        Primero elimine los sinónimos de esta etiqueta.

        + tip: '¿Estás seguro de que deseas borrarlo?' + close: Cerrar + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Editar etiqueta + default_reason: Editar etiqueta + default_first_reason: Añadir etiqueta + btn_save_edits: Guardar cambios + btn_cancel: Cancelar + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [a las] HH:mm" + now: ahora + x_seconds_ago: "hace {{count}}s" + x_minutes_ago: "hace {{count}}m" + x_hours_ago: "hace {{count}}h" + hour: hora + day: día + hours: horas + days: días + month: month + months: months + year: year + reaction: + heart: corazón + smile: sonrisa + frown: frown + btn_label: añadir o eliminar reacciones + undo_emoji: deshacer reacción de {{ emoji }} + react_emoji: reaccionar con {{ emoji }} + unreact_emoji: desreaccionar con {{ emoji }} + comment: + btn_add_comment: Añadir comentario + reply_to: Responder a + btn_reply: Responder + btn_edit: Editar + btn_delete: Eliminar + btn_flag: Reportar + btn_save_edits: Guardar cambios + btn_cancel: Cancelar + show_more: "{{count}} comentarios más" + tip_question: >- + Utiliza los comentarios para pedir más información o sugerir mejoras y modificaciones. Evita responder preguntas en los comentarios. + tip_answer: >- + Usa comentarios para responder a otros usuarios o notificarles de cambios. Si estás añadiendo nueva información, edita tu publicación en vez de comentar. + tip_vote: Añade algo útil a la publicación + edit_answer: + title: Editar respuesta + default_reason: Editar respuesta + default_first_reason: Añadir respuesta + form: + fields: + revision: + label: Revisión + answer: + label: Respuesta + feedback: + characters: El contenido debe tener al menos 6 caracteres. + edit_summary: + label: Editar resumen + placeholder: >- + Explique brevemente sus cambios (ortografía corregida, gramática corregida, formato mejorado) + btn_save_edits: Guardar cambios + btn_cancel: Cancelar + tags: + title: Etiquetas + sort_buttons: + popular: Popular + name: Nombre + newest: Más reciente + button_follow: Seguir + button_following: Siguiendo + tag_label: preguntas + search_placeholder: Filtrar por nombre de etiqueta + no_desc: La etiqueta no tiene descripción. + more: Mas + wiki: Wiki + ask: + title: Create Question + edit_title: Editar pregunta + default_reason: Editar pregunta + default_first_reason: Create question + similar_questions: Preguntas similares + form: + fields: + revision: + label: Revisión + title: + label: Título + placeholder: What's your topic? Be specific. + msg: + empty: El título no puede estar vacío. + range: Título hasta 150 caracteres + body: + label: Cuerpo + msg: + empty: Cuerpo no puede estar vacío. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Etiquetas + msg: + empty: Se requiere al menos una etiqueta. + answer: + label: Respuesta + msg: + empty: La respuesta no puede estar vacía. + edit_summary: + label: Editar resumen + placeholder: >- + Explique brevemente sus cambios (ortografía corregida, gramática corregida, formato mejorado) + btn_post_question: Publica tu pregunta + btn_save_edits: Guardar cambios + answer_question: Responde a tu propia pregunta + post_question&answer: Publicar una pregunta y su respuesta + tag_selector: + add_btn: Añadir etiqueta + create_btn: Crear nueva etiqueta + search_tag: Buscar etiqueta + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: Ninguna etiqueta coincide + tag_required_text: Etiqueta requerida (al menos una) + header: + nav: + question: Preguntas + tag: Etiquetas + user: Usuarios + badges: Insignias + profile: Perfil + setting: Ajustes + logout: Cerrar sesión + admin: Administrador + review: Revisar + bookmark: Marcadores + moderation: Moderación + search: + placeholder: Buscar + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Cambiar + loading: cargando... + pic_auth_code: + title: Captcha + placeholder: Introduce el texto anterior + msg: + empty: El Captcha no puede estar vacío. + inactive: + first: >- + ¡Casi estás listo! Te hemos enviado un correo de activación a {{mail}}. Por favor, sigue las instrucciones en el correo para activar tu cuenta. + info: "Si no te ha llegado el correo, comprueba la carpeta de SPAM." + another: >- + Te hemos enviado otro correo de activación a {{mail}}. Puede tardar algunos minutos en llegar; asegúrate de revisar tu carpeta de SPAM. + btn_name: Reenviar correo de activación + change_btn_name: Cambiar correo + msg: + empty: No puede estar en blanco. + resend_email: + url_label: '¿Estás seguro de reenviar el correo de activación?' + url_text: También puedes dar el enlace de activación de arriba al usuario. + login: + login_to_continue: Inicia sesión para continuar + info_sign: '¿No tienes cuenta? <1>Regístrate' + info_login: '¿Ya tienes una cuenta? <1>Inicia sesión' + agreements: Al registrarte, aceptas la <1>política de privacidad y los <3>términos de servicio. + forgot_pass: '¿Has olvidado la contraseña?' + name: + label: Nombre + msg: + empty: El nombre no puede estar vacío. + range: El nombre debe tener entre 2 y 30 caracteres de largo. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: Correo electrónico + msg: + empty: El correo electrónico no puede estar vacío. + password: + label: Contraseña + msg: + empty: La contraseña no puede estar vacía. + different: Las contraseñas introducidas en ambos lados no coinciden + account_forgot: + page_title: Olvidaste Tu Contraseña + btn_name: Enviadme un correo electrónico de recuperación + send_success: >- + Si existe una cuenta con el correo {{mail}}, deberías de recibir un email con instrucciones sobre cómo recuperar tu contraseña próximamente. + email: + label: Correo electrónico + msg: + empty: El correo electrónico no puede estar vacío. + change_email: + btn_cancel: Cancelar + btn_update: Actualizar dirección de correo + send_success: >- + Si existe una cuenta con el correo {{mail}}, deberías de recibir un email con instrucciones sobre cómo recuperar tu contraseña próximamente. + email: + label: Nuevo correo + msg: + empty: El correo electrónico no puede estar vacío. + oauth: + connect: Conectar con {{ auth_name }} + remove: Eliminar {{ auth_name }} + oauth_bind_email: + subtitle: Añade un correo de recuperación a tu cuenta. + btn_update: Actualizar dirección de correo + email: + label: Correo + msg: + empty: El correo no puede estar vacío. + modal_title: El correo ya está en uso. + modal_content: Este correo electrónico ha sido registrado. ¿Estás seguro de conectarlo a la cuenta existente? + modal_cancel: Cambiar correo + modal_confirm: Conectarse a la cuenta existente + password_reset: + page_title: Restablecimiento de Contraseña + btn_name: Restablecer mi contraseña + reset_success: >- + Tu contraseña ha sido actualizada con éxito; vas a ser redirigido a la página de inicio de sesión. + link_invalid: >- + Lo sentimos, este enlace de restablecimiento de contraseña ya no es válido. ¿Tal vez tu contraseña ya está restablecida? + to_login: Continuar a la página de inicio de sesión + password: + label: Contraseña + msg: + empty: La contraseña no puede estar vacía. + length: La longitud debe ser de entre 8 y 32 caracteres + different: Las contraseñas introducidas en ambos lados no coinciden + password_confirm: + label: Confirmar nueva contraseña + settings: + page_title: Ajustes + goto_modify: Ir a modificar + nav: + profile: Perfil + notification: Notificaciones + account: Cuenta + interface: Interfaz + profile: + heading: Perfil + btn_name: Guardar + display_name: + label: Nombre público + msg: El nombre a mostrar no puede estar vacío. + msg_range: Display name must be 2-30 characters in length. + username: + label: Nombre de usuario + caption: La gente puede mencionarte con "@nombredeusuario". + msg: El nombre de usuario no puede estar vacío. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Imagen de perfil + gravatar: Gravatar + gravatar_text: Puedes cambiar la imagen en + custom: Propia + custom_text: Puedes subir tu propia imagen. + default: Sistema + msg: Por favor, sube una imagen + bio: + label: Sobre mí + website: + label: Sitio Web + placeholder: "https://example.com" + msg: Formato del sitio web incorrecto + location: + label: Ubicación + placeholder: "Ciudad, País" + notification: + heading: Notificaciones por correo + turn_on: Activar + inbox: + label: Notificaciones de bandeja + description: Respuestas a tus preguntas, comentarios, invitaciones, y más. + all_new_question: + label: Todas las preguntas nuevas + description: Recibe notificaciones de todas las preguntas nuevas. Hasta 50 preguntas por semana. + all_new_question_for_following_tags: + label: Todas las preguntas nuevas para las etiquetas siguientes + description: Recibe notificaciones de nuevas preguntas para las etiquetas siguientes. + account: + heading: Cuenta + change_email_btn: Cambiar correo electrónico + change_pass_btn: Cambiar contraseña + change_email_info: >- + Te hemos enviado un email a esa dirección. Por favor sigue las instrucciones de confirmación. + email: + label: Correo + new_email: + label: Nuevo correo + msg: El nuevo correo no puede estar vacío. + pass: + label: Contraseña actual + msg: La contraseña no puede estar vacía. + password_title: Contraseña + current_pass: + label: Contraseña actual + msg: + empty: La contraseña actual no puede estar vacía. + length: El largo necesita estar entre 8 y 32 caracteres. + different: Las contraseñas no coinciden. + new_pass: + label: Nueva contraseña + pass_confirm: + label: Confirmar nueva contraseña + interface: + heading: Interfaz + lang: + label: Idioma de Interfaz + text: Idioma de la interfaz de usuario. Cambiará cuando actualices la página. + my_logins: + title: Mis accesos + label: Inicia sesión o regístrate en este sitio usando estas cuentas. + modal_title: Eliminar acceso + modal_content: '¿Estás seguro de querer eliminar esta sesión de tu cuenta?' + modal_confirm_btn: Eliminar + remove_success: Eliminado con éxito + toast: + update: actualización correcta + update_password: Contraseña cambiada con éxito. + flag_success: Gracias por reportar. + forbidden_operate_self: No puedes modificar tu propio usuario + review: Tu revisión será visible luego de ser aprobada. + sent_success: Enviado con éxito + related_question: + title: Related + answers: respuestas + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Personas Preguntadas + desc: Selecciona personas que creas que sepan la respuesta. + invite: Invitar a responder + add: Añadir personas + search: Buscar personas + question_detail: + action: Acción + created: Created + Asked: Preguntada + asked: preguntada + update: Modificada + Edited: Edited + edit: editada + commented: comentado + Views: Visto + Follow: Seguir + Following: Siguiendo + follow_tip: Sigue esta pregunta para recibir notificaciones + answered: respondida + closed_in: Cerrado el + show_exist: Mostrar una pregunta existente. + useful: Útil + question_useful: Es útil y claro + question_un_useful: Es poco claro o no es útil + question_bookmark: Añadir esta pregunta a marcadores + answer_useful: Es útil + answer_un_useful: No es útil + answers: + title: Respuestas + score: Puntuación + newest: Más reciente + oldest: Más antiguo + btn_accept: Aceptar + btn_accepted: Aceptada + write_answer: + title: Tu respuesta + edit_answer: Editar mi respuesta existente + btn_name: Publica tu respuesta + add_another_answer: Añadir otra respuesta + confirm_title: Continuar a pregunta + continue: Continuar + confirm_info: >- +

        ¿Seguro que quieres añadir otra respuesta?

        Puedes utilizar el enlace de edición para detallar y mejorar tu respuesta existente en su lugar.

        + empty: La respuesta no puede estar vacía. + characters: el contenido debe tener al menos 6 caracteres. + tips: + header_1: Gracias por tu respuesta + li1_1: Asegúrate de responder la pregunta. Proporciona detalles y comparte tu investigación. + li1_2: Respalda cualquier declaración que hagas con referencias o experiencia personal. + header_2: Pero evita ... + li2_1: Pedir ayuda, pedir aclaraciones, o responder a otras respuestas. + reopen: + confirm_btn: Reabrir + title: Reabrir esta publicación + content: '¿Seguro que quieres reabrir esta publicación?' + list: + confirm_btn: Lista + title: Listar esta publicación + content: '¿Estás seguro de que quieres listar?' + unlist: + confirm_btn: Deslistar + title: No listar esta publicación + content: '¿Estás seguro de que quieres dejar de listar?' + pin: + title: Fijar esta publicación + content: '¿Estás seguro de querer fijar esto globalmente? Esta publicación aparecerá por encima de todas las listas de publicaciones.' + confirm_btn: Fijar + delete: + title: Eliminar esta publicación + question: >- + No recomendamos borrar preguntas con respuestas porque esto priva a los lectores futuros de este conocimiento.

        El borrado repetido de preguntas respondidas puede resultar en que tu cuenta se bloquee para hacer preguntas. ¿Estás seguro de que deseas borrarlo? + answer_accepted: >- +

        No recomendamos borrar la respuesta aceptada porque esto priva a los lectores futuros de este conocimiento.

        El borrado repetido de respuestas aceptadas puede resultar en que tu cuenta se bloquee para responder. ¿Estás seguro de que deseas borrarlo? + other: '¿Estás seguro de que deseas borrarlo?' + tip_answer_deleted: Esta respuesta ha sido eliminada + undelete_title: Restaurar esta publicación + undelete_desc: '¿Estás seguro de querer restaurar?' + btns: + confirm: Confirmar + cancel: Cancelar + edit: Editar + save: Guardar + delete: Eliminar + undelete: Restaurar + list: Lista + unlist: Deslistar + unlisted: Sin enumerar + login: Acceder + signup: Registrarse + logout: Cerrar sesión + verify: Verificar + create: Create + approve: Aprobar + reject: Rechazar + skip: Omitir + discard_draft: Descartar borrador + pinned: Fijado + all: Todo + question: Pregunta + answer: Respuesta + comment: Comentario + refresh: Actualizar + resend: Reenviar + deactivate: Desactivar + active: Activar + suspend: Suspender + unsuspend: Quitar suspensión + close: Cerrar + reopen: Reabrir + ok: Aceptar + light: Claro + dark: Oscuro + system_setting: Ajuste de sistema + default: Por defecto + reset: Reiniciar + tag: Etiqueta + post_lowercase: publicación + filter: Filtro + ignore: Ignorar + submit: Enviar + normal: Normal + closed: Cerrado + deleted: Eliminado + deleted_permanently: Deleted permanently + pending: Pendiente + more: Más + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Resultados de la búsqueda + keywords: Palabras claves + options: Opciones + follow: Seguir + following: Siguiendo + counts: "{{count}} Resultados" + counts_loading: "... Results" + more: Más + sort_btns: + relevance: Relevancia + newest: Más reciente + active: Activas + score: Puntuación + more: Mas + tips: + title: Consejos de búsqueda avanzada + tag: "<1>[tag] búsqueda por etiquetas" + user: "<1>user:username búsqueda por autor" + answer: "<1>answers:0 preguntas sin responder" + score: "<1>score:3 Publicaciones con un puntaje de 3 o más" + question: "<1>is:question buscar preguntas" + is_answer: "<1>is:answer buscar respuestas" + empty: No pudimos encontrar nada.
        Prueba a buscar con palabras diferentes o menos específicas. + share: + name: Compartir + copy: Copiar enlace + via: Compartir vía... + copied: Copiado + facebook: Compartir en Facebook + twitter: Share to X + cannot_vote_for_self: No puedes votar tu propia publicación. + modal_confirm: + title: Error... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Tu nueva cuenta ha sido confirmada, serás redirigido a la página de inicio. + link: Continuar a la página de inicio + oops: '¡Ups!' + invalid: El enlace que utilizaste ya no funciona. + confirm_new_email: Tu email ha sido actualizado. + confirm_new_email_invalid: >- + Lo siento, este enlace de confirmación ya no es válido. ¿Quizás ya se haya cambiado tu correo electrónico? + unsubscribe: + page_title: Desuscribir + success_title: Desuscrito con éxito + success_desc: Ha sido eliminado con éxito de esta lista de suscriptores y no recibirá más correos electrónicos nuestros. + link: Cambiar ajustes + question: + following_tags: Etiquetas seguidas + edit: Editar + save: Guardar + follow_tag_tip: Sigue etiquetas para personalizar tu lista de preguntas. + hot_questions: Preguntas del momento + all_questions: Todas las preguntas + x_questions: "{{ count }} Preguntas" + x_answers: "{{ count }} respuestas" + x_posts: "{{ count }} Posts" + questions: Preguntas + answers: Respuestas + newest: Más reciente + active: Activo + hot: Popular + frequent: Frecuente + recommend: Recomendar + score: Puntuación + unanswered: Sin respuesta + modified: modificada + answered: respondida + asked: preguntada + closed: cerrada + follow_a_tag: Seguir una etiqueta + more: Más + personal: + overview: Información general + answers: Respuestas + answer: respuesta + questions: Preguntas + question: pregunta + bookmarks: Guardadas + reputation: Reputación + comments: Comentarios + votes: Votos + badges: Insignias + newest: Más reciente + score: Puntuación + edit_profile: Editar perfil + visited_x_days: "Visitado {{ count }} días" + viewed: Visto + joined: Unido + comma: "," + last_login: Visto + about_me: Sobre mí + about_me_empty: "// ¡Hola Mundo!" + top_answers: Mejores respuestas + top_questions: Preguntas Principales + stats: Estadísticas + list_empty: No se encontraron publicaciones.
        ¿Quizás le gustaría seleccionar una pestaña diferente? + content_empty: No se han encontrado publicaciones. + accepted: Aceptada + answered: respondida + asked: preguntó + downvoted: votado negativamente + mod_short: MOD + mod_long: Moderadores + x_reputation: reputación + x_votes: votos recibidos + x_answers: respuestas + x_questions: preguntas + recent_badges: Insignias recientes + install: + title: Instalación + next: Próximo + done: Hecho + config_yaml_error: No se puede crear el archivo config.yaml. + lang: + label: Elige un idioma + db_type: + label: Motor de base de datos + db_username: + label: Nombre de usuario + placeholder: raíz + msg: El nombre de usuario no puede estar vacío. + db_password: + label: Contraseña + placeholder: raíz + msg: La contraseña no puede estar vacía. + db_host: + label: Host de base de datos + placeholder: "db:3306" + msg: El host de base de datos no puede estar vacío. + db_name: + label: Nombre de base de datos + placeholder: respuesta + msg: El nombre de la base de datos no puede estar vacío. + db_file: + label: Archivo de base de datos + placeholder: /data/respuesta.db + msg: El archivo de la base de datos no puede estar vacío. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Crear config.yaml + label: El archivo config.yaml creado. + desc: >- + Puede crear el archivo <1>config.yaml manualmente en el directorio <1>/var/www/xxx/ y pegar el siguiente texto en él. + info: Después de haber hecho eso, haga clic en el botón "Siguiente". + site_information: Información del sitio + admin_account: Cuenta de administrador + site_name: + label: Nombre del sitio + msg: El nombre del sitio no puede estar vacío. + msg_max_length: El nombre del sitio tener como máximo 30 caracteres. + site_url: + label: Sitio URL + text: La dirección de su sitio. + msg: + empty: La URL del sitio no puede estar vacía. + incorrect: Formato incorrecto de la URL del sitio. + max_length: El URL del sitio debe tener como máximo 512 caracteres. + contact_email: + label: Correo electrónico de contacto + text: Dirección de correo electrónico del contacto clave responsable de este sitio. + msg: + empty: El correo electrónico de contacto no puede estar vacío. + incorrect: Formato incorrecto de correo electrónico de contacto. + login_required: + label: Privado + switch: Inicio de sesión requerido + text: Solo usuarios conectados pueden acceder a esta comunidad. + admin_name: + label: Nombre + msg: El nombre no puede estar vacío. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Contraseña + text: >- + Necesitará esta contraseña para iniciar sesión. Guárdela en un lugar seguro. + msg: La contraseña no puede estar vacía. + msg_min_length: La contraseña debe contener 8 caracteres como mínimo. + msg_max_length: La contraseña debe contener como máximo 32 caracteres. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: Correo electrónico + text: Necesitará este correo electrónico para iniciar sesión. + msg: + empty: El correo electrónico no puede estar vacío. + incorrect: Correo electrónico con formato incorrecto. + ready_title: Tu sitio está listo + ready_desc: >- + Si alguna vez desea cambiar más configuraciones, visite la <1>sección de administración; encuéntrelo en el menú del sitio. + good_luck: "¡Diviértete y buena suerte!" + warn_title: Advertencia + warn_desc: >- + El archivo <1>config.yaml ya existe. Si necesita restablecer alguno de los elementos de configuración de este archivo, elimínelo primero. + install_now: Puede intentar <1>instalar ahora. + installed: Ya instalado + installed_desc: >- + Parece que ya lo has instalado. Para reinstalar, borre primero las tablas de la base de datos anterior. + db_failed: La conexión a la base de datos falló + db_failed_desc: >- + Esto significa que la información de la base de datos en tu archivo <1>config.yaml es incorrecta o que no pudo establecerse contacto con el servidor de la base de datos. Esto podría significar que el host está caído. + counts: + views: puntos de vista + votes: votos + answers: respuestas + accepted: Aceptado + page_error: + http_error: Error HTTP {{ code }} + desc_403: No tienes permiso para acceder a esta página. + desc_404: Desafortunadamente, esta página no existe. + desc_50X: Se produjo un error en el servidor y no pudo completarse tu solicitud. + back_home: Volver a la página de inicio + page_maintenance: + desc: "Estamos en mantenimiento, pronto estaremos de vuelta." + nav_menus: + dashboard: Panel + contents: Contenido + questions: Preguntas + answers: Respuestas + users: Usuarios + badges: Insignias + flags: Banderas + settings: Ajustes + general: General + interface: Interfaz + smtp: SMTP + branding: Marca + legal: Legal + write: Escribir + terms: Terms + tos: Términos de servicio + privacy: Privacidad + seo: ESTE + customize: Personalizar + themes: Temas + login: Iniciar sesión + privileges: Privilegios + plugins: Extensiones + installed_plugins: Extensiones Instaladas + apperance: Appearance + website_welcome: Bienvenido a {{site_name}} + user_center: + login: Iniciar sesión + qrcode_login_tip: Por favor utiliza {{ agentName }} para escanear el código QR e iniciar sesión. + login_failed_email_tip: Error al iniciar sesión, por favor permite el acceso a tu información de correo de esta aplicación antes de intentar nuevamente. + badges: + modal: + title: Enhorabuena + content: Has ganado una nueva insignia. + close: Cerrar + confirm: Ver insignia + title: Insignias + awarded: Premiado + earned_×: Obtenidos ×{{ number }} + ×_awarded: "{{ number }} adjudicado" + can_earn_multiple: Puedes ganar esto varias veces. + earned: Ganado + admin: + admin_header: + title: Administrador + dashboard: + title: Panel + welcome: '¡Bienvenido a Admin!' + site_statistics: Estadísticas del sitio + questions: "Preguntas:" + resolved: "Resuelto:" + unanswered: "Sin respuesta:" + answers: "Respuestas:" + comments: "Comentarios:" + votes: "Votos:" + users: "Usuarios:" + flags: "Banderas:" + reviews: "Revisar:" + site_health: Salud del sitio + version: "Versión:" + https: "HTTPS:" + upload_folder: "Cargar carpeta:" + run_mode: "Modo de ejecución:" + private: Privado + public: Público + smtp: "SMTP:" + timezone: "Zona horaria:" + system_info: Información del sistema + go_version: "Versión de Go:" + database: "Base de datos:" + database_size: "Tamaño de la base de datos:" + storage_used: "Almacenamiento utilizado:" + uptime: "Tiempo ejecutándose:" + links: Enlaces + plugins: Extensiones + github: GitHub + blog: Blog + contact: Contacto + forum: Foro + documents: Documentos + feedback: Comentario + support: Soporte + review: Revisar + config: Configuración + update_to: Actualizar para + latest: Lo más nuevo + check_failed: Comprobación fallida + "yes": "Si" + "no": "No" + not_allowed: No permitido + allowed: Permitido + enabled: Activado + disabled: Desactivado + writable: Redactable + not_writable: No redactable + flags: + title: Banderas + pending: Pendiente + completed: Terminado + flagged: Marcado + flagged_type: Reportado {{ type }} + created: Creado + action: Acción + review: Revisar + user_role_modal: + title: Cambiar rol de usuario a... + btn_cancel: Cancelar + btn_submit: Entregar + new_password_modal: + title: Establecer nueva contraseña + form: + fields: + password: + label: Contraseña + text: El usuario será desconectado y deberá iniciar sesión nuevamente. + msg: La contraseña debe contener entre 8 y 32 caracteres de longitud. + btn_cancel: Cancelar + btn_submit: Enviar + edit_profile_modal: + title: Editar perfil + form: + fields: + display_name: + label: Nombre para mostrar + msg_range: Display name must be 2-30 characters in length. + username: + label: Nombre de usuario + msg_range: Username must be 2-30 characters in length. + email: + label: Correo electrónico + msg_invalid: Dirección de correo inválida. + edit_success: Editado exitosamente + btn_cancel: Cancelar + btn_submit: Enviar + user_modal: + title: Añadir nuevo usuario + form: + fields: + users: + label: Añadir usuarios en cantidad + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separe “nombre, correo electrónico, contraseña” con comas. Un usuario por línea. + msg: "Por favor, introduzca el correo electrónico del usuario, uno por línea." + display_name: + label: Nombre público + msg: El nombre de la pantalla debe tener entre 2 y 30 caracteres de longitud. + email: + label: Correo + msg: El correo no es válido. + password: + label: Contraseña + msg: La contraseña debe contener entre 8 y 32 caracteres de longitud. + btn_cancel: Cancelar + btn_submit: Enviar + users: + title: Usuarios + name: Nombre + email: Correo electrónico + reputation: Reputación + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Estado + role: Rol + action: Acción + change: Cambiar + all: Todo + staff: Personal + more: Más + inactive: Inactivo + suspended: Suspendido + deleted: Eliminado + normal: Normal + Moderator: Moderador + Admin: Administrador + User: Usuario + filter: + placeholder: "Filtrar por nombre, usuario:id" + set_new_password: Establecer nueva contraseña + edit_profile: Editar perfil + change_status: Cambiar Estado + change_role: Cambiar rol + show_logs: Mostrar registros + add_user: Agregar usuario + deactivate_user: + title: Desactivar usuario + content: Un usuario inactivo debe revalidar su correo electrónico. + delete_user: + title: Eliminar este usuario + content: '¿Estás seguro de que deseas eliminar este usuario? ¡Esto es permanente!' + remove: Eliminar su contenido + label: Eliminar todas las preguntas, respuestas, comentarios, etc. + text: No marque esto si solo desea eliminar la cuenta del usuario. + suspend_user: + title: Suspender a este usuario + content: Un usuario suspendido no puede iniciar sesión. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Preguntas + unlisted: No listado + post: Correo + votes: Votos + answers: Respuestas + created: Creado + status: Estado + action: Acción + change: Cambiar + pending: Pendiente + filter: + placeholder: "Filtrar por título, pregunta:id" + answers: + page_title: Respuestas + post: Correo + votes: Votos + created: Creado + status: Estado + action: Acción + change: Cambiar + filter: + placeholder: "Filtrar por título, respuesta: id" + general: + page_title: General + name: + label: Nombre del sitio + msg: El nombre del sitio no puede estar vacío. + text: "El nombre de este sitio, tal como se usa en la etiqueta del título." + site_url: + label: Sitio URL + msg: La url del sitio no puede estar vacía. + validate: Por favor introduzca un URL válido. + text: La dirección de su sitio. + short_desc: + label: Descripción breve del sitio + msg: La descripción breve del sitio no puede estar vacía. + text: "Breve descripción, tal como se usa en la etiqueta del título en la página de inicio." + desc: + label: Descripción del sitio + msg: La descripción del sitio no puede estar vacía. + text: "Describa este sitio en una oración, como se usa en la etiqueta de meta descripción." + contact_email: + label: Correo electrónico de contacto + msg: El correo electrónico de contacto no puede estar vacío. + validate: El correo electrónico de contacto no es válido. + text: Dirección de correo electrónico del contacto clave responsable de este sitio. + check_update: + label: Actualizaciones de software + text: Comprobar actualizaciones automáticamente + interface: + page_title: Interfaz + language: + label: Idioma de Interfaz + msg: El idioma de la interfaz no puede estar vacío. + text: Idioma de la interfaz de usuario. Cambiará cuando actualice la página. + time_zone: + label: Zona horaria + msg: El huso horario no puede estar vacío. + text: Elija una ciudad en la misma zona horaria que usted. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: Desde correo + msg: Desde el correo electrónico no puede estar vacío. + text: La dirección de correo electrónico desde la que se envían los correos electrónicos. + from_name: + label: Desde nombre + msg: Desde el nombre no puede estar vacío. + text: El nombre desde el que se envían los correos electrónicos. + smtp_host: + label: Host SMTP + msg: El host SMTP no puede estar vacío. + text: Su servidor de correo. + encryption: + label: Cifrado + msg: El cifrado no puede estar vacío. + text: Para la mayoría de los servidores, SSL es la opción recomendada. + ssl: SSL + tls: TLS + none: Ninguno + smtp_port: + label: Puerto SMTP + msg: El puerto SMTP debe ser el número 1 ~ 65535. + text: El puerto a su servidor de correo. + smtp_username: + label: Nombre de usuario SMTP + msg: El nombre de usuario SMTP no puede estar vacío. + smtp_password: + label: Contraseña de SMTP + msg: La contraseña SMTP no puede estar vacía. + test_email_recipient: + label: Destinatarios de correo electrónico de prueba + text: Proporcione la dirección de correo electrónico que recibirá los envíos de prueba. + msg: Los destinatarios de correo electrónico de prueba no son válidos + smtp_authentication: + label: Habilitar autenticación + title: Autenticación SMTP + msg: La autenticación SMTP no puede estar vacía. + "yes": "Si" + "no": "No" + branding: + page_title: Marca + logo: + label: Logo + msg: El logotipo no puede estar vacío. + text: La imagen del logotipo en la parte superior izquierda de su sitio. Utilice una imagen rectangular ancha con una altura de 56 y una relación de aspecto superior a 3:1. Si se deja en blanco, se mostrará el texto del título del sitio. + mobile_logo: + label: Logo Móvil + text: El logotipo utilizado en la versión móvil de su sitio. Utilice una imagen rectangular ancha con una altura de 56. Si se deja en blanco, se utilizará la imagen de la configuración de "logotipo". + square_icon: + label: Icono cuadrado + msg: El icono cuadrado no puede estar vacío. + text: Imagen utilizada como base para los iconos de metadatos. Idealmente, debería ser más grande que 512x512. + favicon: + label: Icono de favoritos + text: Un favicon para su sitio. Para que funcione correctamente sobre un CDN, debe ser un png. Se cambiará el tamaño a 32x32. Si se deja en blanco, se utilizará el "icono cuadrado". + legal: + page_title: Legal + terms_of_service: + label: Términos de servicio + text: "Puede agregar términos de contenido de servicio aquí. Si ya tiene un documento alojado en otro lugar, proporcione la URL completa aquí." + privacy_policy: + label: Política de privacidad + text: "Puede agregar contenido de política de privacidad aquí. Si ya tiene un documento alojado en otro lugar, proporcione la URL completa aquí." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Escribir + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Escribir respuesta + label: Cada usuario solo puede escribir una respuesta por pregunta + text: "Desactivar para permitir a los usuarios escribir múltiples respuestas a la misma pregunta, lo que puede causar que las respuestas no estén enfocadas." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Etiquetas recomendadas + text: "Las etiquetas recomendadas se mostrarán en la lista desplegable por defecto." + msg: + contain_reserved: "las etiquetas recomendadas no pueden contener etiquetas reservadas" + required_tag: + title: Establecer etiquetas necesarias + label: Establecer "Etiquetas recomendadas" como etiquetas requeridas + text: "Cada nueva pregunta debe tener al menos una etiqueta de recomendación." + reserved_tags: + label: Etiquetas reservadas + text: "Las etiquetas reservadas sólo pueden ser usadas por el moderador." + image_size: + label: Tamaño máximo de la imagen (MB) + text: "Tamaño máximo de la imagen." + attachment_size: + label: Tamaño máximo del archivo adjunto (MB) + text: "El tamaño máximo de subida de archivos adjuntos." + image_megapixels: + label: Megapixels de imagen máx + text: "Número máximo de megapixels permitidos para una imagen." + image_extensions: + label: Extensiones de adjuntos autorizadas + text: "Una lista de extensiones de archivo permitidas para la visualización de imágenes, separadas con comas." + attachment_extensions: + label: Extensiones de adjuntos autorizadas + text: "Una lista de extensiones de archivo permitidas para subir, separadas con comas. ADVERTENCIA: Permitir subidas puede causar problemas de seguridad." + seo: + page_title: SEO + permalink: + label: Enlace permanente + text: Las estructuras de URL personalizadas pueden mejorar la facilidad de uso y la compatibilidad futura de sus enlaces. + robots: + label: robots.txt + text: Esto anulará permanentemente cualquier configuración del sitio relacionada. + themes: + page_title: Temas + themes: + label: Temas + text: Seleccione un tema existente. + color_scheme: + label: Esquema de color + navbar_style: + label: Navbar background style + primary_color: + label: Color primario + text: Modifica los colores usados por tus temas + css_and_html: + page_title: CSS y HTML + custom_css: + label: CSS personalizado + text: > + + head: + label: Cabeza + text: > + + header: + label: Encabezado + text: > + + footer: + label: Pie de página + text: Esto se insertará antes . + sidebar: + label: Barra lateral + text: Esto se añadirá en la barra lateral. + login: + page_title: Iniciar sesión + membership: + title: Membresía + label: Permitir registro de nuevas ceuntas + text: Desactiva esto para evitar que cualquier persona pueda crear una cuenta. + email_registration: + title: Registro de correo electrónico + label: Permitir registro de correo electrónico + text: Desactivar para evitar registros a través de correo electrónico. + allowed_email_domains: + title: Dominios de correo electrónico permitidos + text: Dominios de correo electrónico con los que los usuarios deben registrar sus cuentas. Un dominio por línea. Ignorado cuando esté vacío. + private: + title: Privado + label: Inicio de sesión requerido + text: Sólo usuarios con sesión iniciada pueden acceder a esta comunidad. + password_login: + title: Inicio de sesión con contraseña + label: Permitir inicio de sesión con correo y contraseña + text: "ADVERTENCIA: Si se desactiva, es posible que no pueda iniciar sesión si no ha configurado previamente otro método de inicio de sesión." + installed_plugins: + title: Extensiones Instaladas + plugin_link: Los plugins extienden y expanden la funcionalidad. Puede encontrar plugins en el <1>Repositorio de plugin. + filter: + all: Todos + active: Activo + inactive: Inactivo + outdated: Desactualizado + plugins: + label: Extensiones + text: Seleccione una extensión existente. + name: Nombre + version: Versión + status: Estado + action: Acción + deactivate: Desactivar + activate: Activar + settings: Ajustes + settings_users: + title: Usuarios + avatar: + label: Avatar predeterminado + text: Para usuarios sin un avatar personalizado propio. + gravatar_base_url: + label: Gravatar Base URL + text: URL de la base API del proveedor Gravatar. Ignorado cuando esté vacío. + profile_editable: + title: Perfil editable + allow_update_display_name: + label: Permitir a usuarios cambiar su nombre público + allow_update_username: + label: Permitir a los usuarios cambiar su nombre de usuario + allow_update_avatar: + label: Permitir a los usuarios cambiar su foto de perfil + allow_update_bio: + label: Permitir a los usuarios cambiar su descripción + allow_update_website: + label: Permitir a los usuarios cambiar su sitio web + allow_update_location: + label: Permitir a los usuarios cambiar su ubicación + privilege: + title: Privilegios + level: + label: Nivel de reputación requerido + text: Elegir reputación requerida para los privilegios + msg: + should_be_number: la entrada debe ser número + number_larger_1: número debe ser igual o mayor que 1 + badges: + action: Accin + active: Activo + activate: Activación + all: All + awards: Premios + deactivate: Desactivar + filter: + placeholder: Filtrar por nombre, insignia:id + group: Grupo + inactive: Inactivo + name: Nombre + show_logs: Mostrar logs + status: Status + title: Insignias + form: + optional: (opcional) + empty: no puede estar en blanco + invalid: no es válido + btn_submit: Guardar + not_found_props: "La propiedad requerida {{ key }} no se ha encontrado." + select: Seleccionar + page_review: + review: Revisar + proposed: propuesto + question_edit: Edición de preguntas + answer_edit: Edición de respuestas + tag_edit: Edición de etiquetas + edit_summary: Editar resumen + edit_question: Editar pregunta + edit_answer: Editar respuesta + edit_tag: Editar etiqueta + empty: No quedan tareas de revisión. + approve_revision_tip: '¿Aprueban ustedes esta revisión?' + approve_flag_tip: '¿Aprueban ustedes esta bandera?' + approve_post_tip: '¿Aprueban ustedes esta bandera?' + approve_user_tip: '¿Apruebas a este usuario?' + suggest_edits: Ediciones Sugeridas + flag_post: Marcar publicación + flag_user: Marcar usuario + queued_post: Publicación en cola + queued_user: Usuario en cola + filter_label: Tipo + reputation: reputación + flag_post_type: Marcada esta publicación como {{ type }}. + flag_user_type: Marcado este usuario como {{ type }}. + edit_post: Editar publicación + list_post: Listar publicación + unlist_post: Deslistar publicación + timeline: + undeleted: recuperado + deleted: eliminado + downvote: voto negativo + upvote: votar a favor + accept: aceptar + cancelled: cancelado + commented: comentado + rollback: retroceder + edited: editada + answered: contestada + asked: preguntó + closed: cerrado + reopened: reabierto + created: creado + pin: fijado + unpin: desfijado + show: listado + hide: deslistado + title: "Historial para" + tag_title: "Línea temporal para" + show_votes: "Mostrar votos" + n_or_a: N/A + title_for_question: "Línea de tiempo para" + title_for_answer: "Cronología de la respuesta a {{ title }} por {{ author }}" + title_for_tag: "Cronología de la etiqueta" + datetime: Fecha y hora + type: Tipo + by: Por + comment: Comentario + no_data: "No pudimos encontrar nada." + users: + title: Usuarios + users_with_the_most_reputation: Usuarios con el mayor puntaje de reputación esta semana + users_with_the_most_vote: Usuarios que más votaron esta semana + staffs: Nuestor equipo de la comunidad + reputation: reputación + votes: votos + prompt: + leave_page: '¿Seguro que quieres salir de la página?' + changes_not_save: Es posible que sus cambios no se guarden. + draft: + discard_confirm: '¿Está seguro de que desea descartar este borrador?' + messages: + post_deleted: Esta publicación ha sido eliminada. + post_cancel_deleted: Este publicación ha sido restaurada. + post_pin: Esta publicación ha sido fijada. + post_unpin: Esta publicación ha sido desfijada. + post_hide_list: Esta publicación ha sido ocultada de la lista. + post_show_list: Esta publicación ha sido mostrada a la lista. + post_reopen: Esta publicación ha sido reabierta. + post_list: Esta publicación ha sido listada. + post_unlist: Esta publicación ha sido retirado de la lista.. + post_pending: Su publicación está pendiente de revisión. Esto es una vista previa, será visible después de que haya sido aprobado. + post_closed: Esta publicación ha sido cerrada. + answer_deleted: Esta respuesta ha sido eliminada. + answer_cancel_deleted: Esta respuesta ha sido restaurada. + change_user_role: El rol de este usuario ha sido cambiado. + user_inactive: Este usuario ya esta inactivo. + user_normal: Este usuario ya es normal. + user_suspended: Este usuario ha sido suspendido. + user_deleted: Este usuario ha sido eliminado. + badge_activated: Esta insignia ha sido activada. + badge_inactivated: Esta insignia ha sido desactivada. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/fa_IR.yaml b/data/i18n/fa_IR.yaml new file mode 100644 index 000000000..5bff8a821 --- /dev/null +++ b/data/i18n/fa_IR.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: موفق. + unknown: + other: خطای ناشناخته. + request_format_error: + other: ساختار درخواست شناخته شده نیست. + unauthorized_error: + other: دسترسی غیر مجاز. + database_error: + other: خطای سرور داده. + forbidden_error: + other: عدم اجازه دسترسی. + duplicate_request_error: + other: ارسال تکراری. + action: + report: + other: نشان + edit: + other: ویرایش + delete: + other: حذف + close: + other: بستن + reopen: + other: بازگشایی + forbidden_error: + other: عدم اجازه دسترسی. + pin: + other: سنجاق کردن + hide: + other: پنهان کردن + unpin: + other: برداشتن سنجاق + show: + other: فهرست + invite_someone_to_answer: + other: ویرایش + undelete: + other: بازگردانی حذف + merge: + other: Merge + role: + name: + user: + other: کاربر + admin: + other: ادمین + moderator: + other: مدير + description: + user: + other: پیش فرض بدون دسترسی خاص. + admin: + other: تمامی دسترسی ها را داراست. + moderator: + other: دسترسی به تمامی پست هارا داراست بجز تنظیمات ادمین. + privilege: + level_1: + description: + other: سطح ۱ (شهرت کمی نیاز هست برای تیم/گروه های خصوصی) + level_2: + description: + other: سطح ۲ (شهرت کمی نیاز هست برای انجمن های استارتاپی) + level_3: + description: + other: سطح ۳ (شهرت بالایی برای نیاز هست برای انجمن های تکمیل) + level_custom: + description: + other: سطح دلخواه + rank_question_add_label: + other: سوال بپرس + rank_answer_add_label: + other: جواب بده + rank_comment_add_label: + other: نظر بده + rank_report_add_label: + other: نشان + rank_comment_vote_up_label: + other: رای موافق + rank_link_url_limit_label: + other: بیشتر از دو لینک را هم زمان پست کنید + rank_question_vote_up_label: + other: رای موافق + rank_answer_vote_up_label: + other: رای موافق + rank_question_vote_down_label: + other: رای مخالف + rank_answer_vote_down_label: + other: رای مخالف + rank_invite_someone_to_answer_label: + other: فردی رو دعوت کنین تا جواب بدن + rank_tag_add_label: + other: ساخت تگ جدید + rank_tag_edit_label: + other: ویرایش توضیحات تگ (نیازمند بازبینی) + rank_question_edit_label: + other: ویرایش سوال دیگران (نیازمند بازبینی) + rank_answer_edit_label: + other: ویرایش جواب دیگران (نیازمند بازبینی) + rank_question_edit_without_review_label: + other: ویرایش سوال دیگران بدون نیاز به بازبینی + rank_answer_edit_without_review_label: + other: ویرایش جواب دیگران بدون نیاز به بازبینی + rank_question_audit_label: + other: بازبینی ویرایش های سوال + rank_answer_audit_label: + other: بازبینی ویرایش های جواب + rank_tag_audit_label: + other: بازبینی ویرایش های تگ + rank_tag_edit_without_review_label: + other: ویرایش توضیحات تگ بدون بازبینی + rank_tag_synonym_label: + other: مدیریت تگ های مترادف + email: + other: ایمیل + e_mail: + other: ایمیل + password: + other: رمز + pass: + other: رمز + old_pass: + other: Current password + original_text: + other: پست جاری + email_or_password_wrong_error: + other: ایمیل و رمز وارد شده صحیح نیست. + error: + common: + invalid_url: + other: Invalid URL. + status_invalid: + other: Invalid status. + password: + space_invalid: + other: رمز عبور نمی تواند شامل فضای خالی باشد. + admin: + cannot_update_their_password: + other: نمیتوانید رمز عبور خود را تغییر دهید. + cannot_edit_their_profile: + other: You cannot modify your profile. + cannot_modify_self_status: + other: نمیتوانید وضعیت خود را تغییر دهید. + email_or_password_wrong: + other: ایمیل و رمز وارد شده صحیح نیست. + answer: + not_found: + other: جواب پیدا نشد. + cannot_deleted: + other: اجازه حذف ندارید. + cannot_update: + other: اجازه بروزرسانی ندارید. + question_closed_cannot_add: + other: سوالات بسته شده اند و نمیتوان سوالی اضافه کرد. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: نظرات قابل ویرایش نیستند. + not_found: + other: نظر پیدا نشد. + cannot_edit_after_deadline: + other: زمان زیادی برای ویرایش نظر گذشته است. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: ایمیل تکراری. + need_to_be_verified: + other: ایمیل باید تایید شود. + verify_url_expired: + other: لینک تایید ایمیل منقضی شده است،‌لطفا دوباره تلاش کنید. + illegal_email_domain_error: + other: دامنه ایمیل پیشتیبانی نمی شود، لطفا از ایمیل دیگری استفاده کنید. + lang: + not_found: + other: فایل زبان یافت نشد. + object: + captcha_verification_failed: + other: اشتباه در Captcha. + disallow_follow: + other: شما اجازه فالو کردن ندارید. + disallow_vote: + other: شما اجازه رای دادن ندارید. + disallow_vote_your_self: + other: شما نمی توانید به پست خودتان رای دهید. + not_found: + other: آبجکت مورد نظر پیدا نشد. + verification_failed: + other: تایید با خطا مواجه شد. + email_or_password_incorrect: + other: ایمیل و رمز وارد شده صحیح نیست. + old_password_verification_failed: + other: پسورد قدیمی تایید نشد + new_password_same_as_previous_setting: + other: پسورد جدید با پسورد قدیمی یکسان است. + already_deleted: + other: This post has been deleted. + meta: + object_not_found: + other: Meta object not found + question: + already_deleted: + other: این پست حذف شده است. + under_review: + other: Your post is awaiting review. It will be visible after it has been approved. + not_found: + other: سوال پیدا نشد. + cannot_deleted: + other: اجازه حذف ندارید. + cannot_close: + other: اجاره بستن ندارید. + cannot_update: + other: اجازه بروزرسانی ندارید. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: شهرت ناکافی. + vote_fail_to_meet_the_condition: + other: ممنون بابت بازخورد. شما حداقل به {{.Rank}} نیاز دارید برای رای دادن. + no_enough_rank_to_operate: + other: شما حداقل به {{.Rank}} نیاز دارید برای انجام این کار. + report: + handle_failed: + other: گزارش دهی با مشکل مواجه شد. + not_found: + other: گزارش مورد نظر پیدا نشد. + tag: + already_exist: + other: تگ از قبل موجود است. + not_found: + other: تگ پیدا نشد. + recommend_tag_not_found: + other: تگ پیشنهاد شده موجود نیست. + recommend_tag_enter: + other: لطفا حداقل یک تگ را وارد کنید. + not_contain_synonym_tags: + other: نباید تگ مترادف داشته باشد. + cannot_update: + other: اجازه بروزرسانی ندارید. + is_used_cannot_delete: + other: نمی توانید تگی که در حال استفاده است را حذف کنید. + cannot_set_synonym_as_itself: + other: شما نمی توانید مترادفی برای برچسب فعلی به عوان خودش تنظیم کنین. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: '"از طرفه" نمی تواند آدرس ایمیل باشد.' + theme: + not_found: + other: تم پیدا نشد. + revision: + review_underway: + other: فعلا امکان ویرایش وجود ندارد،‌این نسخه در صف بازینی قرار دارد. + no_permission: + other: اجاره بازبینی و اصلاح ندارید. + user: + external_login_missing_user_id: + other: پلتفورم های سوم شخص نمی توانند نام کاربر خاصی را ارائه دهند، بنابر این شما نمی توانید وارد شوید، لطفا با مدیریت وبسایت تماس بگیرید. + external_login_unbinding_forbidden: + other: لطفاً یک رمز ورود برای حساب خود قبل از حذف تنظیم کنید. + email_or_password_wrong: + other: + other: ایمیل و رمز وارد شده صحیح نیست. + not_found: + other: کاربر پیدا نشد. + suspended: + other: کاربر در حالت تعلیق قرار داده شده است. + username_invalid: + other: نام کاربری نامعتبر است. + username_duplicate: + other: این نام کاربری قبلا استفاده شده است. + set_avatar: + other: ست کردن آواتار با مشکل مواجه شد. + cannot_update_your_role: + other: شما نمی توانید وظیفه خود را تغییر دهید. + not_allowed_registration: + other: درحال حاضر سایت برای ثبت نام باز نیست. + not_allowed_login_via_password: + other: در حال حاضر سایت اجازه ورود از طریق رمز عبور ندارد. + access_denied: + other: دسترسی مجاز نیست + page_access_denied: + other: شما وجوز دسترسی به این صفحه را ندارید. + add_bulk_users_format_error: + other: "مشکل پیش آمده در فرمت {{.Field}} در کنار {{.Content}} در خط {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "تعداد کاربرانی که اضافه می کنید باید رنج بین ۱-{{.MaxAmount}} باشند." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: خواندن کافیگ با مشکل مواجه شد + database: + connection_failed: + other: اتصال به دیتابیس موفقیت آمیز نبود + create_table_failed: + other: ایجاد کردن جدول موفقیت آمیز نبود + install: + create_config_failed: + other: فایل config.yaml نمی تواند ایجاد شود. + upload: + unsupported_file_format: + other: فرمت فایل پشتیبانی نمی شود. + site_info: + config_not_found: + other: پیکربندی سایت پیدا نشد. + badge: + object_not_found: + other: Badge object not found + reason: + spam: + name: + other: هرزنامه + desc: + other: این پست یک تبلیغ یا خرابکاری است. این پس مفید یا مربوط به این موضوع نمی باشد. + rude_or_abusive: + name: + other: بی ادب یا توهین آمیز + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + a_duplicate: + name: + other: تکراری + desc: + other: این سوال قبلا پرسیده و جواب داده شده است. + placeholder: + other: لینک سوال مورد نظر را وارد کنید + not_a_answer: + name: + other: این یک پاسخ نیست + desc: + other: "." + no_longer_needed: + name: + other: دیگر نیازی نیست + desc: + other: این نظر منسوخ شده، مکلامه ای یا مربوط به این پس نیست. + something: + name: + other: یک مورد دیگر + desc: + other: این پست به دلیل دیگری که در بالا ذکر نشده نیاز به توجه کارکنان دارد. + placeholder: + other: به طور خاص به ما اطلاع دهید که در مورد چه چیزی نگران هستید + community_specific: + name: + other: یک دلیل خاص جامعه + desc: + other: این سوال با دستورالعمل جامعه مطابقت ندارد. + not_clarity: + name: + other: نیاز به جزئیات یا واضح کردن دارد + desc: + other: این سوال درحال حاضر شامل چندتا سوال در یکی هست. باید فقط روی یک مشکل تمرکز کند. + looks_ok: + name: + other: به نظر خوب میاد + desc: + other: این پست همانطور که هست خوب است و کیفیت پایینی ندارد. + needs_edit: + name: + other: نیاز به ویرایش بود، من انجام دادم + desc: + other: مشکلات این پست را خودتان بهبود و اصلاح کنید. + needs_close: + name: + other: نیاز است که بسته بشود + desc: + other: به یک سوال بسته شده نمیتوان جوابی ثبت کرد بلکه می توان ویرایش، رای و نظر داد. + needs_delete: + name: + other: نیاز است که حذف بشود + desc: + other: این پست حذف خواهد شد. + question: + close: + duplicate: + name: + other: هرزنامه + desc: + other: این سوال قبلا پرسیده و جواب داده شده است. + guideline: + name: + other: یک دلیل خاص جامعه + desc: + other: این سوال با دستورالعمل جامعه مطابقت ندارد. + multiple: + name: + other: نیاز به جزئیات یا واضح کردن دارد + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: یک مورد دیگر + desc: + other: این پست به دلیل دیگری نیاز دارد که در بالا ذکر نشده است. + operation_type: + asked: + other: پرسیده شده + answered: + other: جواب داده + modified: + other: تغییر یافته + deleted_title: + other: سوال حذف شده + questions_title: + other: Questions + tag: + tags_title: + other: Tags + no_description: + other: The tag has no description. + notification: + action: + update_question: + other: سوال بارگزاری شده + answer_the_question: + other: سؤال جواب داده شده + update_answer: + other: جواب بارگذاری شده + accept_answer: + other: جواب پذیرفته شده + comment_question: + other: سوال از کامنت + comment_answer: + other: جواب از کامنت + reply_to_you: + other: به شما پاسخ داد + mention_you: + other: به شما اشاره کرده + your_question_is_closed: + other: سوال شما بسته شده است + your_question_was_deleted: + other: سوال شما حذف شده است + your_answer_was_deleted: + other: جواب شما حذف شده است + your_comment_was_deleted: + other: نظر شما پاک شده است + up_voted_question: + other: رای موافق + down_voted_question: + other: سوال با رای منفی + up_voted_answer: + other: پاسخ موافق + down_voted_answer: + other: جواب مخالف + up_voted_comment: + other: نظر بدون رای + invited_you_to_answer: + other: برای جواب دادن دعوت شده اید + earned_badge: + other: You've earned the "{{.BadgeName}}" badge + email_tpl: + change_email: + title: + other: "آدرس ایمیل جدید خود را تایید کنید{{.SiteName}}" + body: + other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} به سؤال شما پاسخ داد" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} شما را به پاسخ دعوت کرد" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} روی پست شما نظر داد" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_question: + title: + other: "[{{.SiteName}}] سؤال جدید: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] گذرواژه بازنشانی شد" + body: + other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + register: + title: + other: "[{{.SiteName}}] حساب کاربری جدید خود را تأیید کنید" + body: + other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + test: + title: + other: "[{{.SiteName}}] ایمیل آزمایشی" + body: + other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + action_activity_type: + upvote: + other: رأی مثبت + upvoted: + other: رأی مثبت + downvote: + other: رأی منفی + downvoted: + other: رأی منفی + accept: + other: پذیرفتن + accepted: + other: پذیرفته شده + edit: + other: edit + review: + queued_post: + other: Queued post + flagged_post: + other: Flagged post + suggested_post_edit: + other: Suggested edits + reaction: + tooltip: + other: "{{ .Names }} and {{ .Count }} more..." + badge: + default_badges: + autobiographer: + name: + other: Autobiographer + desc: + other: Filled out profile information. + certified: + name: + other: Certified + desc: + other: Completed our new user tutorial. + editor: + name: + other: Editor + desc: + other: First post edit. + first_flag: + name: + other: First Flag + desc: + other: First flagged a post. + first_upvote: + name: + other: First Upvote + desc: + other: First up voted a post. + first_link: + name: + other: First Link + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: First Share + desc: + other: First shared a post. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Leave 5 comments. + new_user_of_the_month: + name: + other: New User of the Month + desc: + other: Outstanding contributions in their first month. + read_guidelines: + name: + other: Read Guidelines + desc: + other: Read the [community guidelines]. + reader: + name: + other: Reader + desc: + other: Read every answers in a topic with more than 10 answers. + welcome: + name: + other: Welcome + desc: + other: Received a up vote. + nice_share: + name: + other: Nice Share + desc: + other: Shared a post with 25 unique visitors. + good_share: + name: + other: Good Share + desc: + other: Shared a post with 300 unique visitors. + great_share: + name: + other: Great Share + desc: + other: Shared a post with 1000 unique visitors. + out_of_love: + name: + other: Out of Love + desc: + other: Used 50 up votes in a day. + higher_love: + name: + other: Higher Love + desc: + other: Used 50 up votes in a day 5 times. + crazy_in_love: + name: + other: Crazy in Love + desc: + other: Used 50 up votes in a day 20 times. + promoter: + name: + other: Promoter + desc: + other: Invited a user. + campaigner: + name: + other: Campaigner + desc: + other: Invited 3 basic users. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: Thank You + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Active member for a year, posted at least once. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: نحوه فرمت کردن + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: قبلی + next: بعدی + page_title: + question: سوال + questions: سوالات + tag: برچسب + tags: برچسب ها + tag_wiki: ویکی تگ + create_tag: ایجاد برچسب + edit_tag: ویرایش برچسب + ask_a_question: Create Question + edit_question: ویرایش سوال + edit_answer: ویرایش پاسخ + search: جستجو + posts_containing: پست های شامل + settings: تنظیمات + notifications: اعلانات + login: ورود + sign_up: ثبت نام + account_recovery: بازیابی حساب کاربری + account_activation: فعالسازی حساب + confirm_email: تایید ایمیل + account_suspended: حساب تعلیق شد + admin: ادمین + change_email: نگارش ایمیل + install: نصب Bepors + upgrade: بروزرسانی بپرس + maintenance: تعمیر و نگهداری وب سایت + users: کاربرها + oauth_callback: در حال پردازش + http_404: خطای 404 HTTP + http_50X: خطای 500 HTTP + http_403: خطای 403 HTTP + logout: خروج + posts: Posts + notifications: + title: اعلانات + inbox: پیغام‌های دریافتی + achievement: دستاوردها + new_alerts: هشدار جدید + all_read: علامتگذاری همه بعنوان خوانده شده + show_more: نمایش بیشتر + someone: کسی + inbox_type: + all: همه + posts: پست ها + invites: دعوت ها + votes: آراء + answer: Answer + question: Question + badge_award: Badge + suspended: + title: حساب شما معلق شده است + until_time: "حساب شما تا تاریخ {{ time }} به حالت تعلیق درآمده است." + forever: این کاربر برای همیشه به حالت تعلیق درآمده است. + end: شما یک دستورالعمل انجمن را رعایت نمی کنید. + contact_us: ارتباط با ما + editor: + blockquote: + text: مسابقه + bold: + text: قوی + chart: + text: نمودار + flow_chart: نمودار جریان + sequence_diagram: نمودار توالی + class_diagram: نمودار کلاس + state_diagram: نمودار حالت + entity_relationship_diagram: نمودار رابطه موجودیت + user_defined_diagram: نمودار تعریف شده توسط کاربر + gantt_chart: نمودار گانت + pie_chart: نمودار دابره‌ای + code: + text: نمونه کد + add_code: نمونه کد اضافه کنید + form: + fields: + code: + label: کد + msg: + empty: کد نمی تواند خالی باشد. + language: + label: زبان + placeholder: تشخیص خودکار + btn_cancel: لغو + btn_confirm: اضافه کردن + formula: + text: فرمول + options: + inline: فرمول در خط + block: بلاک کردن فرمول + heading: + text: سرفصل + options: + h1: سرفصل ۱ + h2: سرفصل ۲ + h3: سرفصل ۳ + h4: سرفصل ۴ + h5: سرفصل ۵ + h6: سرفصل ۶ + help: + text: راهنما + hr: + text: خط افقی + image: + text: عکس + add_image: افزودن عکس + tab_image: آپلود عکس + form_image: + fields: + file: + label: فایل عکس + btn: انتخاب عکس + msg: + empty: فایل نمی تواند خالی باشد. + only_image: فقط فایل های تصویری مجاز هستند. + max_size: File size cannot exceed {{size}} MB. + desc: + label: توضیحات + tab_url: لینک عکس + form_url: + fields: + url: + label: لینک عکس + msg: + empty: آدرس عکس نمی‌تواند خالی باشد. + name: + label: توضیحات + btn_cancel: لغو + btn_confirm: اضافه کردن + uploading: درحال ارسال + indent: + text: تورفتگی + outdent: + text: بیرون آمدگی + italic: + text: تاکید + link: + text: فراپیوند + add_link: اضافه کردن فراپیوند + form: + fields: + url: + label: آدرس + msg: + empty: آدرس نمی‌تواند خالی باشد. + name: + label: توضیح + btn_cancel: لغو + btn_confirm: افزودن + ordered_list: + text: فهرست عددی + unordered_list: + text: لیست گلوله‌ای + table: + text: جدول + heading: سرفصل + cell: تلفن همراه + file: + text: Attach files + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: این پست را می بندم بدلیل... + btn_cancel: لغو + btn_submit: فرستادن + remark: + empty: نمی‌تواند خالی باشد. + msg: + empty: لطفا یک دلیل را انتخاب کنید. + report_modal: + flag_title: من پرچم گذاری می کنم تا این پست را به عنوان گزارش کنم... + close_title: این پست را می بندم بدلیل... + review_question_title: بازبینی سوال + review_answer_title: بازبینی جواب + review_comment_title: بازبینی نظر + btn_cancel: لغو + btn_submit: ثبت + remark: + empty: نمی‌تواند خالی باشد. + msg: + empty: لطفا یک دلیل را انتخاب کنید. + not_a_url: URL format is incorrect. + url_not_match: URL origin does not match the current website. + tag_modal: + title: ساخت تگ جدید + form: + fields: + display_name: + label: نام + msg: + empty: نام نمی تواند خالی باشد. + range: نام باید نهایتا ۳۵ حرف داشته باشد. + slug_name: + label: نامک آدس + desc: نامک آدرس باید نهایتا ۳۵ حرف داشته باشد. + msg: + empty: نامک آدرس نمی تواند خالی باشد. + range: نامک آدرس باید نهایتا ۳۵ حرف داشته باشد. + character: نامک آدرس شامل کلمات غیر مجاز می باشد. + desc: + label: توضیحات + revision: + label: تجدید نظر + edit_summary: + label: ویرایش خلاصه + placeholder: >- + تغییرات خود را به طور خلاصه توضیح دهید (املا صحیح، دستور زبان مناسب، قالب بندی بهبود یافته) + btn_cancel: لغو + btn_submit: ثبت + btn_post: پست کردن تگ جدید + tag_info: + created_at: ایجاد شده + edited_at: ویرایش شده + history: تاریخچه + synonyms: + title: مترادف ها + text: تگ های زیر مجدداً به آنها نگاشت می شوند + empty: مترادفی پیدا نشد. + btn_add: افزودن مترادف + btn_edit: ویرایش + btn_save: ذخیره + synonyms_text: تگ های زیر مجدداً به آنها نگاشت می شوند + delete: + title: این برچسب حذف شود + tip_with_posts: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + tip_with_synonyms: >- +

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        + tip: مطمئنید که میخواهید حذف شود? + close: بستن + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: ویرایش تگ‌ + default_reason: ویرایش تگ‌ + default_first_reason: برچسب اضافه کنید + btn_save_edits: ذخیره ویرایشها + btn_cancel: لغو + dates: + long_date: ماه ماه ماه روز + long_date_with_year: "ماه روز، سال" + long_date_with_time: "ماه روز، سال در ساعت:دقیقه" + now: حالا + x_seconds_ago: "{{count}} ثانیه پیش" + x_minutes_ago: "{{count}} دقیقه پیش" + x_hours_ago: "{{count}}ساعت پیش" + hour: ساعت + day: روز + hours: ساعات + days: روزها + month: month + months: months + year: year + reaction: + heart: heart + smile: smile + frown: frown + btn_label: add or remove reactions + undo_emoji: undo {{ emoji }} reaction + react_emoji: react with {{ emoji }} + unreact_emoji: unreact with {{ emoji }} + comment: + btn_add_comment: افزودن نظر + reply_to: پاسخ به + btn_reply: پاسخ + btn_edit: ویرایش + btn_delete: حذف + btn_flag: نشان + btn_save_edits: ذخیره ویرایشها + btn_cancel: لغو + show_more: "{{count}} نظر بیشتر" + tip_question: >- + از نظرات برای درخواست اطلاعات بیشتر یا پیشنهاد بهبود استفاده کنید. از پاسخ دادن به سوالات در نظرات خودداری کنید. + tip_answer: >- + از نظرات برای پاسخ دادن به سایر کاربران یا اطلاع دادن آنها از تغییرات استفاده کنید. اگر اطلاعات جدیدی اضافه می کنید، به جای نظر دادن، پست خود را ویرایش کنید. + tip_vote: چیز مفیدی به پست اضافه می کند + edit_answer: + title: ویرایش جواب + default_reason: ویرایش جواب + default_first_reason: پاسخ را اضافه کنید + form: + fields: + revision: + label: بازنگری + answer: + label: پاسخ + feedback: + characters: متن باید حداقل ۶ حرف داشته باشد. + edit_summary: + label: ویرایش خلاصه + placeholder: >- + بطور خلاصه تغییرات را توضیح دهید (اصلاح املایی، اصلاح دستورزبان،‌ بهبود فرمت دهی) + btn_save_edits: ذخیره ویرایش ها + btn_cancel: لغو + tags: + title: برچسب ها + sort_buttons: + popular: محبوب + name: نام + newest: جدیدترین + button_follow: دنبال کردن + button_following: دنبال می کنید + tag_label: سوالات + search_placeholder: فیلتر بر اساس اسم برچسب + no_desc: برچسب هیچ توضیحی ندارد. + more: بیشتر + wiki: Wiki + ask: + title: Create Question + edit_title: سوال را ویرایش کنید + default_reason: سوال را ویرایش کنید + default_first_reason: Create question + similar_questions: سؤال های مشابه + form: + fields: + revision: + label: تجدید نظر + title: + label: عنوان + placeholder: What's your topic? Be specific. + msg: + empty: عنوان نمی تواند خالی باشد. + range: عنوان میتواند تا ۳۰ حرف باشد + body: + label: بدنه + msg: + empty: بدنه نمی تواند خالی باشد. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: برچسب ها + msg: + empty: برچسب ها نمی تواند خالی باشد. + answer: + label: پاسخ + msg: + empty: جواب نمی تواند خالی باشد. + edit_summary: + label: ویرایش خلاصه + placeholder: >- + بطور خلاصه تغییرات را توضیح دهید (اصلاح املایی، اصلاح دستورزبان،‌ بهبود فرمت دهی) + btn_post_question: سوال خود را پست کنید + btn_save_edits: ذخیره ویرایش ها + answer_question: جواب دادن به سوال خودتان + post_question&answer: سوال خود را پست و جواب دهید + tag_selector: + add_btn: اضافه کردن برچسب + create_btn: ایجاد یک برچسب جدید + search_tag: جست‌وجوی برچسب‌ + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: هیچ تگی مطابقت ندارد + tag_required_text: تگ نیاز هست (حداقل یک مورد) + header: + nav: + question: سوالات + tag: تگ‌ها + user: کاربران + badges: Badges + profile: پروفایل + setting: تنظیمات + logout: خروج + admin: ادمین + review: بازبینی + bookmark: نشانک ها + moderation: مدیریت + search: + placeholder: جستجو + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: تغییر + loading: درحال بارگذاری... + pic_auth_code: + title: کپچا + placeholder: متن بالا را تاپ کنید + msg: + empty: کپچا نمی تواند خالی باشد. + inactive: + first: >- + شما تقریباً آماده شده اید! ما یک ایمیل فعال سازی به {{mail}} ارسال کردیم. لطفا دستورالعمل های ایمیل را برای فعال کردن حساب خود دنبال کنید. + info: "اگر ایمیل ارسالی را دریافت نکردید، قسمت spam خود را چک کنید." + another: >- + ایمیل فعال‌سازی دیگری را به آدرس {{mail}} برای شما ارسال کردیم. ممکن است چند دقیقه طول بکشد تا دستتان برسد. پوشه هرزنامه خود را حتما چک کنید. + btn_name: ارسال مجدد کد فعالسازی + change_btn_name: تغییر ایمیل + msg: + empty: نمی‌تواند خالی باشد. + resend_email: + url_label: آیا مطمئن هستید که می خواهید ایمیل فعال سازی را دوباره ارسال کنید؟ + url_text: همچنین می توانید لینک فعال سازی بالا را در اختیار کاربر قرار دهید. + login: + login_to_continue: برای ادامه وارد حساب کاربری شوید + info_sign: حساب کاربری ندارید؟ ثبت نام<1> + info_login: از قبل حساب کاربری دارید؟ <1>وارد شوید + agreements: با ثبت نام، با <1>خط مشی رازداری و <3>شرایط خدمات موافقت می کنید. + forgot_pass: رمزعبور را فراموش کردید? + name: + label: نام + msg: + empty: نام نمی‌تواند خالی باشد. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: ایمیل + msg: + empty: ایمیل نمی تواند خالی باشد. + password: + label: رمز عبور + msg: + empty: رمز عبور نمی تواند خالی باشد. + different: پسوردهای وارد شده در هر دو طرف متناقض هستند + account_forgot: + page_title: رمزعبور را فراموش کردید + btn_name: ارسال ایمیل بازیابی + send_success: >- + اگر یک حساب با {{mail}} مطابقت داشته باشد، باید به زودی ایمیلی حاوی دستورالعمل‌هایی درباره نحوه بازنشانی رمز عبور خود دریافت کنید. + email: + label: ایمیل + msg: + empty: ایمیل نمی تواند خالی باشد. + change_email: + btn_cancel: لغو + btn_update: نشانی ایمیل را به روز کنید + send_success: >- + اگر یک حساب با {{mail}} مطابقت داشته باشد، باید به زودی ایمیلی حاوی دستورالعمل‌هایی درباره نحوه بازنشانی رمز عبور خود دریافت کنید. + email: + label: ایمیل جدید + msg: + empty: ایمیل نمی تواند خالی باشد. + oauth: + connect: ارتباط با {{ auth_name }} + remove: حذف {{ auth_name }} + oauth_bind_email: + subtitle: یک ایمیل بازیابی به حساب خود اضافه کنید. + btn_update: نشانی ایمیل را به روز کنید + email: + label: ایمیل + msg: + empty: ایمیل نمی تواند خالی باشد. + modal_title: ایمیل تکراری. + modal_content: این ایمیل قبلا ثبت نام کرده است. آیا مطمئن هستید که می خواهید به حساب ثبت نام کرده متصل شوید? + modal_cancel: تغییر ایمیل + modal_confirm: به حساب کاربری ثبت نام کرده متصل شوید + password_reset: + page_title: بازیابی کلمه عبور + btn_name: رمز عبورم را بازنشانی کن + reset_success: >- + شما با موفقیت رمز عبور خود را تغییر دادید، به صفحه ورود هدایت می شوید. + link_invalid: >- + متاسفم،‌ لینک بازنشانی رمز عبور دیگر اعتبار ندارد. شاید رمز عبور شما قبلا تغییر کرده است? + to_login: ادامه بدهید تا به صفحه ورود برسید + password: + label: رمز عبور + msg: + empty: رمز عبور نمی تواند خالی باشد. + length: تعداد حروف باید بین ۸ تا ۳۲ باشد + different: پسوردهای وارد شده در هر دو طرف متناقض هستند + password_confirm: + label: تأیید رمز عبور جديد + settings: + page_title: تنظیمات + goto_modify: برای تغییر بروید + nav: + profile: پروفایل + notification: اعلانات + account: حساب کاربری + interface: رابط کاربری + profile: + heading: پروفایل + btn_name: ذخیره + display_name: + label: نام + msg: نام نمی تواند خالی باشد. + msg_range: Display name must be 2-30 characters in length. + username: + label: نام‌کاربری + caption: دیگران میتوانند به شما به بصورت "@username" اشاره کنند. + msg: نام کاربری نمی تواند خالی باشد. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: عکس پروفایل + gravatar: Gravatar + gravatar_text: می توانید تصویر را تغییر دهید + custom: سفارشی + custom_text: شما میتوانید عکس خود را بازگذاری کنید. + default: سیستم + msg: لطفا یک آواتار آپلود کنید + bio: + label: درباره من + website: + label: وب سایت + placeholder: "https://example.com" + msg: فرمت نادرست وب سایت + location: + label: موقعیت + placeholder: "شهر، کشور" + notification: + heading: اعلان های ایمیلی + turn_on: روشن کردن + inbox: + label: اعلانات ایمیل + description: پاسخ به سوالات خود،‌ نظرات،‌ دعوت ها،‌و بیشتر. + all_new_question: + label: تمامی سوالات جدید + description: درمورد تمامی سوالات جدید با خبر شوید. تا ۵۰ سوال در هفته. + all_new_question_for_following_tags: + label: تمامی سوالات جدید برای این تگ ها + description: درمورد تمامی سوالات جدید در مورد این تگ ها باخبر شوید. + account: + heading: حساب کاربری + change_email_btn: تغییر ایمیل + change_pass_btn: تغییر رمز عبور + change_email_info: >- + ما یک ایمیل به آن آدرس ارسال کردیم. لطفا مراحل تایید را طی کنید. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + pass: + label: رمز عبور فعلی + msg: رمز عبور نمی تواند خالی باشد. + password_title: رمز عبور + current_pass: + label: رمز عبور فعلی + msg: + empty: رمز عبور نمی تواند خالی باشد. + length: تعداد حروف باید بین ۸ تا ۳۲ باشد. + different: دو رمز عبور وارد شده همخوانی ندارند. + new_pass: + label: رمز عبور جدید + pass_confirm: + label: تأیید رمز عبور جديد + interface: + heading: رابط کاربری + lang: + label: زبان رابط کاربری + text: زبان رابط کاربری. زمانی تغییر می کند که صفحه را دوباره بارگذاری کنید. + my_logins: + title: ورود های من + label: با استفاده از این حساب ها وارد این سایت شوید یا ثبت نام کنید. + modal_title: حذف ورود + modal_content: آیا مطمئن هستید که می خواهید این ورود را از حساب خود حذف کنید؟ + modal_confirm_btn: حذف + remove_success: با موفقیت حذف شد + toast: + update: بروز رسانی موفق بود + update_password: رمز عبور با موفقیت تغییر کرد. + flag_success: ممنون بابت اطلاع دادن. + forbidden_operate_self: عملیات غیر مجاز + review: بازبینی شما پس از بررسی نشان داده خواهد شد. + sent_success: با موفقيت ارسال شد + related_question: + title: Related + answers: جواب ها + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: مردم پرسیدند + desc: افرادی را دعوت کنید که فکر می کنید ممکن است پاسخ را بدانند. + invite: دعوت به پاسخ + add: افزودن افراد + search: جستجوی افراد + question_detail: + action: عملیات + created: Created + Asked: پرسیده شده + asked: پرسیده شده + update: تغییر یافته + Edited: Edited + edit: ویرایش شده + commented: commented + Views: مشاهده شده + Follow: دنبال کردن + Following: دنبال می کنید + follow_tip: برای دریافت اعلان ها این سوال را دنبال کنید + answered: جواب داده + closed_in: بسته شده د + show_exist: نمایش سوال موجود. + useful: مفید + question_useful: مفید و واضح است + question_un_useful: نامشخص یا مفید نیست + question_bookmark: این سوال را نشانه گذاری کنید + answer_useful: مفید است + answer_un_useful: مفید نیست + answers: + title: پاسخ ها + score: امتیاز + newest: جدیدترین + oldest: Oldest + btn_accept: پذیرفتن + btn_accepted: پذیرفته شده + write_answer: + title: پاسخ شما + edit_answer: پاسخ فعلی من را ویرایش کنید + btn_name: پاسخ خود را ارسال کنید + add_another_answer: پاسخ دیگری اضافه کنید + confirm_title: به پاسخ دادن ادامه دهید + continue: ادامه دهید + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: جواب نمی تواند خالی باشد. + characters: متن باید حداقل ۶ حرف داشته باشد. + tips: + header_1: از جواب شما متشکریم + li1_1: لطفا مطمئن شوید که جواب دهید سوال را. جزئیات بیشتری ارائه دهید و تحقیقات خود را به اشتراک بگذارید. + li1_2: از هر اظهاراتی که می کنید با ارجاعات یا تجربه شخصی پشتیبان بگیرید. + header_2: اما دوری کنید ... + li2_1: درخواست کمک، به دنبال شفاف سازی، یا پاسخ به پاسخ های دیگر. + reopen: + confirm_btn: بازگشایی مجدد + title: بازگشایی مجدد این پست + content: آیا مطمئن هستید که می‌خواهید بازگشایی مجدد انجام دهید? + list: + confirm_btn: List + title: List this post + content: Are you sure you want to list? + unlist: + confirm_btn: Unlist + title: Unlist this post + content: Are you sure you want to unlist? + pin: + title: پست را پین کن + content: آیا مطمئن هستید میخواهید پست بصورت عمومی پین شود؟ پست در بالای تمامی پست ها نشان داده خواهد شد. + confirm_btn: پین کردن + delete: + title: حذف این پست + question: >- + ما حذف سوالات با جواب را پیشنهاد نمی کنیم، زیرا انجام این کار خوانندگان آینده را از این دانش محروم می کند.

        حذف مکرر سؤالات پاسخ داده شده می تواند منجر به مسدود شدن حساب شما از سؤال شود. آیا مطمئن هستید که می خواهید حذف کنید? + answer_accepted: >- + ما حذف جواب تایید شده را پیشنهاد نمی کنیم، زیرا انجام این کار خوانندگان آینده را از این دانش محروم می کند.

        حذف مکرر سؤالات پاسخ داده شده می تواند منجر به مسدود شدن حساب شما از سؤال شود. آیا مطمئن هستید که می خواهید حذف کنید? + other: مطمئنید که میخواهید حذف شود? + tip_answer_deleted: جواب شما حذف شده است + undelete_title: حذف این پست + undelete_desc: آیا مطمئن به بازگردانی هستید؟ + btns: + confirm: تایید + cancel: لغو + edit: ویرایش + save: ذخیره + delete: حذف + undelete: بازگردانی + list: List + unlist: Unlist + unlisted: Unlisted + login: ورود + signup: عضويت + logout: خروج + verify: تایید + create: Create + approve: تایید + reject: رد کردن + skip: بعدی + discard_draft: دور انداختن پیش‌نویس‌ + pinned: پین شد + all: همه + question: سوال + answer: پاسخ + comment: نظر + refresh: بارگذاری مجدد + resend: ارسال مجدد + deactivate: غیرفعال کردن + active: فعال + suspend: تعلیق + unsuspend: لغو تعلیق + close: بستن + reopen: بازگشایی + ok: تأیید + light: روشن + dark: تیره + system_setting: تنظیمات سامانه + default: Default + reset: Reset + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignore + submit: Submit + normal: Normal + closed: Closed + deleted: Deleted + deleted_permanently: Deleted permanently + pending: Pending + more: More + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: نتایج جستجو + keywords: کلیدواژه ها + options: گزینه‌ها + follow: دنبال کردن + following: دنبال میکنید + counts: "{{count}} نتیجه" + counts_loading: "... Results" + more: بیشتر + sort_btns: + relevance: مرتبط + newest: جدیدترین + active: فعال + score: امتیاز + more: بیشتر + tips: + title: گزینه های پیشرفته جستجو + tag: "<1>[tag] search with a tag" + user: "<1>user:username جستجو براساس نویسنده" + answer: "<1>answers:0 سوال بی جواب" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: چیزی پیدا نکردیم
        کلمات کلیدی متفاوت یا کمتر خاص را امتحان کنید. + share: + name: اشتراک‌گذاری + copy: کپی کردن لینک + via: اشتراک گذاری پست با... + copied: کپی انجام شد + facebook: اشتراک گذاری در فیس بوک + twitter: Share to X + cannot_vote_for_self: شما نمی توانید به پست خودتان رای دهید. + modal_confirm: + title: خطا... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: اکانت جدید شما تایید شده است، به صفحه خانه منتقل خواهید شد. + link: ادامه بدهید تا به صفحه خانه برسید + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: ایمیل شما به‌روز شده است. + confirm_new_email_invalid: >- + متاسفیم، لینک تایید دیگر مجاز نیست. شاید حساب شما از قبل فعال شده است? + unsubscribe: + page_title: قطع عضویت + success_title: لغو عضویت موفق (Automatic Translation) + success_desc: شما با موفقیت از این لیست مشترک حذف شده اید و دیگر ایمیلی از ما دریافت نخواهید کرد. + link: تغییر تنظیمات + question: + following_tags: تگهای مورد نظر + edit: ویرایش + save: ذخیره + follow_tag_tip: برچسب ها را دنبال کنید تا لیست سوالات خود را تنظیم کنید. + hot_questions: سوالات داغ + all_questions: تمام سوالات + x_questions: "{{ count }} سوال" + x_answers: "{{ count }} جواب" + x_posts: "{{ count }} Posts" + questions: سوالات + answers: پاسخ ها + newest: جدیدترین + active: فعال + hot: Hot + frequent: Frequent + recommend: Recommend + score: امتیاز + unanswered: بدون پاسخ + modified: تغییر یافته + answered: جواب داده + asked: پرسیده شده + closed: بسته + follow_a_tag: یک برچسب را دنبال کنید + more: بیشتر + personal: + overview: خلاصه + answers: پاسخ ها + answer: پاسخ + questions: سوالات + question: سوال + bookmarks: نشان ها + reputation: محبوبیت + comments: نظرات + votes: آراء + badges: Badges + newest: جدیدترین + score: امتیاز + edit_profile: ویرایش پروفایل + visited_x_days: "Visited {{ count }} days" + viewed: مشاهده شده + joined: عضو شد + comma: "," + last_login: مشاهده شده + about_me: درباره من + about_me_empty: "// Hello, World !" + top_answers: پاسخ های برتر + top_questions: سوالات برتر + stats: آمار + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + content_empty: No posts found. + accepted: پذیرفته شده + answered: جواب داده + asked: پرسیده شده + downvoted: رأی منفی + mod_short: MOD + mod_long: Moderators + x_reputation: محبوبیت + x_votes: آرای دریافت شد + x_answers: جواب ها + x_questions: سوالات + recent_badges: Recent Badges + install: + title: Installation + next: بعدی + done: انجام شده + config_yaml_error: نمیتوان فایل config.yaml را ایجاد کرد. + lang: + label: لطفا زبان خود را انتخاب کنید + db_type: + label: موتور پایگاه‌داده + db_username: + label: نام‌کاربری + placeholder: روت + msg: نام کاربری نمی تواند خالی باشد. + db_password: + label: رمز عبور + placeholder: روت + msg: رمز عبور نمی تواند خالی باشد. + db_host: + label: میزبان پایگاه داده + placeholder: "db:3306" + msg: پایگاه داده میزبان نمیتواند خالی باشد. + db_name: + label: نام پایگاه‌داده + placeholder: پاسخ + msg: نام پایگاه داده میزبان نمیتواند خالی باشد. + db_file: + label: فایل پایگاه داده + placeholder: /data/answer.db + msg: فایل پایگاه داده نمیتواند خالی باشد. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Config.yaml را بسازید + label: فایل config.yaml ساخته شد. + desc: >- + شما بصورت دستی میتوانید فایل <1>config.yaml را در پوشه <1>/var/wwww/xxx/ ایجاد و متن را در داخل آن جایگذاری کنید. + info: بعد از اتمام،‌ بر روی "بعدی" کلیک کنید. + site_information: اطلاعات سایت + admin_account: حساب ادمین + site_name: + label: نام سایت + msg: نام سایت نمی تواند خالی باشد. + msg_max_length: Site name must be at maximum 30 characters in length. + site_url: + label: آدرس سایت + text: آدرس سایت شما + msg: + empty: آدرس سایت نمی تواند خالی باشد. + incorrect: فرمت آدرس سایت نادرست است. + max_length: Site URL must be at maximum 512 characters in length. + contact_email: + label: ایمیل ارتباطی + text: آدرس ایمیل مخاطب کلیدی پاسخگو برای این سایت. + msg: + empty: ایمیل مخاطب نمی تواند خالی باشد. + incorrect: فرمت ایمیل مخاطب نادرست است. + login_required: + label: خصوصی + switch: ورود الزامی است + text: تنها افرادی که وارد سایت شده اند میتوانند به این انجمن دسترسی پیدا کنند. + admin_name: + label: نام + msg: نام نمی‌تواند خالی باشد. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: رمز عبور + text: >- + شما برای ورود نیازمند این پسورد خواهید بود. لطفا در محل امنی ذخیره کنید. + msg: رمز عبور نمی تواند خالی باشد. + msg_min_length: Password must be at least 8 characters in length. + msg_max_length: Password must be at maximum 32 characters in length. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: ایمیل + text: شما به این ایمیل برای ورود نیاز خواهید داشت. + msg: + empty: ایمیل نمی تواند خالی باشد. + incorrect: فرمت ایمیل نادرست است. + ready_title: Your site is ready + ready_desc: >- + اگر به تغییر بیشتر تنظیمات نیاز دارید،‌به <1> قسمت ادمین مراجعه کنید،‌میتوانید این گزینه را در منو سایت مشاهده کنید. + good_luck: "خوش بگذره و موفق باشید!" + warn_title: هشدار + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: قبلاً نصب شده است + installed_desc: >- + شما پیش از‌این وردپرس را برپا نموده‌اید. برای راه‌اندازی دوباره ابتدا جدول‌های کهنه در پایگاه‌داده را پاک نمایید. + db_failed: اتصال به دیتابیس موفقیت آمیز نبود + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: مشاهده + votes: آراء + answers: جواب ها + accepted: پذیرفته شده + page_error: + http_error: HTTP Error {{ code }} + desc_403: شما مجوز دسترسی به این صفحه را ندارید. + desc_404: متاسفانه این صفحه وجود ندارد. + desc_50X: The server encountered an error and could not complete your request. + back_home: بازگشت به صفحه اصلی + page_maintenance: + desc: "ما درحال تعمیر هستیم، به زودی برمی گردیم." + nav_menus: + dashboard: داشبرد + contents: محتوا + questions: سوالات + answers: پاسخ ها + users: کاربران + badges: Badges + flags: پرچم + settings: تنظیمات + general: عمومی + interface: رابط کاربری + smtp: SMTP + branding: نام تجاری + legal: قانونی + write: نوشتن + terms: Terms + tos: قوانین + privacy: حریم خصوصی + seo: سئو + customize: شخصی‌سازی + themes: پوسته ها + login: ورود + privileges: مجوزها + plugins: افزونه‌ها + installed_plugins: پلاگین های نصب شده + apperance: Appearance + website_welcome: به {{site_name}} خوش آمدید + user_center: + login: ورود + qrcode_login_tip: لطفاً از {{ agentName }} برای اسکن کد QR و ورود به سیستم استفاده کنید. + login_failed_email_tip: ورود ناموفق بود، لطفاً قبل از امتحان مجدد به این برنامه اجازه دهید به اطلاعات ایمیل شما دسترسی داشته باشد. + badges: + modal: + title: Congratulations + content: You've earned a new badge. + close: Close + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + admin: + admin_header: + title: ادمین + dashboard: + title: داشبرد + welcome: Welcome to Admin! + site_statistics: Site statistics + questions: "سوالات:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "جواب ها:" + comments: "نظرات:" + votes: "آرا:" + users: "Users:" + flags: "علامت‌ها:" + reviews: "Reviews:" + site_health: Site health + version: "نسخه:" + https: "HTTPS:" + upload_folder: "Upload folder:" + run_mode: "Running mode:" + private: Private + public: در دسترس عموم + smtp: "SMTP:" + timezone: "منطقه زمانی:" + system_info: اطلاعات سامانه + go_version: "نسخه Go:" + database: "پایگاه داده:" + database_size: "اندازه پایگاه داده :" + storage_used: "فضای استفاده شده:" + uptime: "پایداری:" + links: Links + plugins: افزونه‌ها + github: GitHub + blog: بلاگ + contact: تماس + forum: Forum + documents: اسناد + feedback: ﺑﺎﺯﺧﻮﺭﺩ + support: پشتیبانی + review: بازبینی + config: کانفینگ + update_to: آپدیت کردن به + latest: آخرین + check_failed: بررسی ناموفق بود + "yes": "بله" + "no": "نه" + not_allowed: غیر مجاز + allowed: مجاز + enabled: فعال + disabled: غیرفعال + writable: قابل نوشتن + not_writable: غیرقابل کُپی + flags: + title: علامت‌ها + pending: در حالت انتظار + completed: تکمیل شده + flagged: علامت گذاری شده + flagged_type: پرچم گذاری شده {{ type }} + created: ایجاد شده + action: عمل + review: بازبینی + user_role_modal: + title: تغییر نقش کاربر به ... + btn_cancel: لغو + btn_submit: ثبت + new_password_modal: + title: تعیین رمزعبور جدید + form: + fields: + password: + label: رمز عبور + text: کاربر از سیستم خارج می شود و باید دوباره وارد سیستم شود. + msg: رمز عبور باید 8 تا 32 کاراکتر باشد. + btn_cancel: لغو + btn_submit: ثبت + edit_profile_modal: + title: Edit profile + form: + fields: + display_name: + label: Display name + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Invalid Email Address. + edit_success: Edited successfully + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: افزودن کاربر جدید + form: + fields: + users: + label: اضافه کردن انبوه کاربر + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: '"نام، ایمیل، رمز عبور" را با کاما جدا کنید. یک کاربر در هر خط.' + msg: "لطفا ایمیل کاربر را در هر خط یکی وارد کنید." + display_name: + label: نمایش نام + msg: Display name must be 2-30 characters in length. + email: + label: ایمیل + msg: ایمیل معتبر نمی‌باشد + password: + label: رمز عبور + msg: رمز عبور باید 8 تا 32 کاراکتر باشد. + btn_cancel: لغو + btn_submit: ثبت + users: + title: کاربرها + name: نام + email: ایمیل + reputation: محبوبیت + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: وضعیت + role: نقش + action: عمل + change: تغییر + all: همه + staff: کارکنان + more: بیشتر + inactive: غیرفعال + suspended: تعلیق شده + deleted: حذف شده + normal: عادي + Moderator: مدير + Admin: ادمین + User: کاربر + filter: + placeholder: "فیلتر براساس، user:id" + set_new_password: تعیین رمزعبور جدید + edit_profile: Edit profile + change_status: تغییر وضعیت + change_role: تغییر نقش + show_logs: نمایش ورود ها + add_user: افزودن کاربر + deactivate_user: + title: غیر فعال کردن کاربر + content: یک کاربر غیرفعال باید ایمیل خود را دوباره تایید کند. + delete_user: + title: این کاربر حذف شود + content: آیا مطمئن هستید که میخواهید این کابر را حذف نمایید؟ این اقدام دائمی است! + remove: محتوای آنها را حذف کنید + label: تمام سوالات، پاسخ ها، نظرات و غیره را حذف کن. + text: اگر می‌خواهید فقط حساب کاربر را حذف کنید، این را بررسی نکنید. + suspend_user: + title: تعلیق این کاربر + content: کاربر تعلیق شده نمی‌تواند وارد شود. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: سوالات + unlisted: Unlisted + post: پست + votes: آراء + answers: پاسخ ها + created: ایجاد شده + status: وضعیت + action: عمل + change: تغییر + pending: Pending + filter: + placeholder: "فیلتر براساس، user:id" + answers: + page_title: پاسخ ها + post: پست + votes: آراء + created: ایجاد شده + status: وضعیت + action: اقدام + change: تغییر + filter: + placeholder: "فیلتر براساس، user:id" + general: + page_title: عمومی + name: + label: نام سایت + msg: نام سایت نمی تواند خالی باشد. + text: "نام این سایت همانطور که در تگ عنوان استفاده شده است." + site_url: + label: آدرس سایت + msg: آدرس سایت نمی تواند خالی باشد. + validate: لطفا یک url معتبر وارد کنید. + text: آدرس سایت شما. + short_desc: + label: نام این سایت مورد استفاده قرار گرفته است + msg: توضیحات کوتاه سایت نمی تواند خالی باشد. + text: "شرح کوتاه، همانطور که در تگ عنوان در صفحه اصلی استفاده شده است." + desc: + label: توضیحات سایت + msg: توضیحات کوتاه سایت نمی تواند خالی باشد. + text: "همانطور که در تگ توضیحات متا استفاده شده است، این سایت را در یک جمله توصیف کنید." + contact_email: + label: ایمیل ارتباطی + msg: ایمیل مخاطب نمی تواند خالی باشد. + validate: ایمیل تماس معتبر نیست. + text: آدرس ایمیل مخاطب کلیدی مسئول این سایت. + check_update: + label: Software updates + text: Automatically check for updates + interface: + page_title: رابط کاربری + language: + label: زبان رابط کاربری + msg: زبان رابط نمی تواند خالی باشد. + text: زبان رابط کاربری. زمانی تغییر می کند که صفحه را دوباره بارگذاری کنید. + time_zone: + label: منطقه زمانی + msg: منطقه زمانی نمی تواند خالی باشد. + text: شهری را در همان منطقه زمانی خود انتخاب کنید. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: از ایمیل + msg: ایمیل نباید خالی باشد. + text: آدرس ایمیلی که ایمیل ها از آن ارسال می شوند. + from_name: + label: نام فرستنده + msg: ایمیل نباید خالی باشد. + text: آدرس ایمیلی که ایمیل ها از آن ارسال می شوند. + smtp_host: + label: ميزبان SMTP + msg: میزبان SMTP نمی تواند خالی باشد. + text: سرور ایمیل شما. + encryption: + label: رمزگذاری + msg: کلید رمزگذاری نمی تواند خالی باشد. + text: برای اکثر سرورها SSL گزینه پیشنهادی است. + ssl: SSL + tls: TLS + none: هیچ‌کدام + smtp_port: + label: پورت SMTP + msg: پورت SMTP باید شماره 1 ~ 65535 باشد. + text: پورت سرور ایمیل شما. + smtp_username: + label: نام کاربری SMTP + msg: نام کاربری SMTP نمی تواند خالی باشد. + smtp_password: + label: رمزعبور SMTP + msg: رمز عبور مدیر نمی‌تواند خالی باشد. + test_email_recipient: + label: گیرندگان ایمیل را آزمایش کنید + text: آدرس ایمیلی را ارائه دهید که ارسال های آزمایشی را دریافت می کند. + msg: گیرندگان ایمیل آزمایشی نامعتبر است + smtp_authentication: + label: فعال کردن احراز هویت + title: تأیید هویت SMTP + msg: احراز هویت SMTP نمی تواند خالی باشد. + "yes": "بله" + "no": "نه" + branding: + page_title: نام تجاری + logo: + label: لوگو + msg: کد نمی تواند خالی باشد. + text: تصویر لوگو در سمت چپ بالای سایت شما. از یک تصویر مستطیلی عریض با ارتفاع 56 و نسبت تصویر بیشتر از 3:1 استفاده کنید. اگر خالی بماند، متن عنوان سایت نشان داده می شود. + mobile_logo: + label: لوگوی موبایل + text: لوگوی مورد استفاده در نسخه موبایلی سایت شما. از یک تصویر مستطیلی عریض با ارتفاع 56 استفاده کنید. اگر خالی بماند، تصویر از تنظیمات "لوگو" استفاده خواهد شد. + square_icon: + label: نماد مربعی + msg: نماد مربعی نمی تواند خالی باشد. + text: تصویر به عنوان پایه نمادهای متادیتا استفاده می شود. در حالت ایده آل باید بزرگتر از 512x512 باشد. + favicon: + label: نمادک + text: فاویکون برای سایت شما. برای اینکه روی CDN به درستی کار کند باید یک png باشد. به 32x32 تغییر اندازه خواهد شد. اگر خالی بماند، از "نماد مربع" استفاده می شود. + legal: + page_title: قانونی + terms_of_service: + label: شرایط خدمات + text: "می توانید محتوای شرایط خدمات را در اینجا اضافه کنید. اگر قبلاً سندی دارید که در جای دیگری میزبانی شده است، URL کامل را در اینجا ارائه دهید." + privacy_policy: + label: حریم خصوصی + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: نوشتن + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Each user can only write one answer for each question + text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Recommend tags + text: "Recommend tags will show in the dropdown list by default." + msg: + contain_reserved: "recommended tags cannot contain reserved tags" + required_tag: + title: Set required tags + label: Set “Recommend tags” as required tags + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved tags + text: "Reserved tags can only be used by moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: بهینه‌سازی عملیات موتورهای جستجو + permalink: + label: پیوند ثابت + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + color_scheme: + label: Color scheme + navbar_style: + label: Navbar background style + primary_color: + label: Primary color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: > + + head: + label: Head + text: > + + header: + label: Header + text: > + + footer: + label: Footer + text: This will insert before </body>. + sidebar: + label: Sidebar + text: This will insert in sidebar. + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + email_registration: + title: Email registration + label: Allow email registration + text: Turn off to prevent anyone creating new account through email. + allowed_email_domains: + title: دامنه های مجاز ایمیل + text: دامنه های ایمیلی که کاربران باید با آنها حساب ثبت کنند. یک دامنه در هر خط. وقتی خالی است نادیده گرفته می شود. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + password_login: + title: Password login + label: Allow email and password login + text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." + installed_plugins: + title: Installed Plugins + plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + filter: + all: All + active: Active + inactive: Inactive + outdated: Outdated + plugins: + label: Plugins + text: Select an existing plugin. + name: Name + version: Version + status: وضعیت + action: اقدام + deactivate: Deactivate + activate: فعال سازی + settings: تنظیمات + settings_users: + title: کاربران + avatar: + label: آواتار پیش فرض + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar Base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + profile_editable: + title: Profile editable + allow_update_display_name: + label: Allow users to change their display name + allow_update_username: + label: Allow users to change their username + allow_update_avatar: + label: Allow users to change their profile image + allow_update_bio: + label: Allow users to change their about me + allow_update_website: + label: Allow users to change their website + allow_update_location: + label: Allow users to change their location + privilege: + title: Privileges + level: + label: Reputation required level + text: Choose the reputation required for the privileges + msg: + should_be_number: the input should be number + number_larger_1: number should be equal or larger than 1 + badges: + action: Action + active: Active + activate: Activate + all: All + awards: Awards + deactivate: Deactivate + filter: + placeholder: Filter by name, badge:id + group: Group + inactive: Inactive + name: Name + show_logs: Show logs + status: Status + title: Badges + form: + optional: (optional) + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + select: Select + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + approve_revision_tip: Do you approve this revision? + approve_flag_tip: Do you approve this flag? + approve_post_tip: Do you approve this post? + approve_user_tip: Do you approve this user? + suggest_edits: Suggested edits + flag_post: Flag post + flag_user: Flag user + queued_post: Queued post + queued_user: Queued user + filter_label: Type + reputation: reputation + flag_post_type: Flagged this post as {{ type }}. + flag_user_type: Flagged this user as {{ type }}. + edit_post: Edit post + list_post: List post + unlist_post: پست فهرست نشده + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + pin: pinned + unpin: unpinned + show: listed + hide: unlisted + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores this week + users_with_the_most_vote: Users who voted the most this week + staffs: Our community staff + reputation: reputation + votes: votes + prompt: + leave_page: Are you sure you want to leave the page? + changes_not_save: Your changes may not be saved. + draft: + discard_confirm: Are you sure you want to discard your draft? + messages: + post_deleted: This post has been deleted. + post_cancel_deleted: This post has been undeleted. + post_pin: This post has been pinned. + post_unpin: This post has been unpinned. + post_hide_list: This post has been hidden from list. + post_show_list: This post has been shown to list. + post_reopen: This post has been reopened. + post_list: This post has been listed. + post_unlist: This post has been unlisted. + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/fi_FI.yaml b/data/i18n/fi_FI.yaml new file mode 100644 index 000000000..25c086f11 --- /dev/null +++ b/data/i18n/fi_FI.yaml @@ -0,0 +1,1384 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: Success. + unknown: + other: Unknown error. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + email: + other: Email + password: + other: Password + email_or_password_wrong_error: + other: Email and password do not match. + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + question: + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + rank: + fail_to_meet_the_condition: + other: Rank fail to meet the condition. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend Tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + smtp: + config_from_name_cannot_be_email: + other: The From Name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to Revision. + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + report: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude: + name: + other: rude or abusive + desc: + other: A reasonable person would find this content inappropriate for respectful discourse. + duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + not_answer: + name: + other: not an answer + desc: + other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. + not_need: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + other: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comments + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to {{site_name}} + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to {{site_name}} + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/fr_FR.yaml b/data/i18n/fr_FR.yaml new file mode 100644 index 000000000..a4fdcb2ed --- /dev/null +++ b/data/i18n/fr_FR.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Succès. + unknown: + other: Erreur inconnue. + request_format_error: + other: Format de fichier incorrect. + unauthorized_error: + other: Non autorisé. + database_error: + other: Erreur du serveur de données. + forbidden_error: + other: Interdit. + duplicate_request_error: + other: Soumission en double. + action: + report: + other: Signaler + edit: + other: Éditer + delete: + other: Supprimer + close: + other: Fermer + reopen: + other: Rouvrir + forbidden_error: + other: Interdit. + pin: + other: Épingler + hide: + other: Délister + unpin: + other: Désépingler + show: + other: Liste + invite_someone_to_answer: + other: Modifier + undelete: + other: Annuler la suppression + merge: + other: Fusionner + role: + name: + user: + other: Utilisateur + admin: + other: Administrateur + moderator: + other: Modérateur + description: + user: + other: Par défaut, sans accès spécial. + admin: + other: Possède tous les droits pour accéder au site. + moderator: + other: Possède les accès à tous les messages sauf aux paramètres d'administration. + privilege: + level_1: + description: + other: Niveau 1 (moins de réputation requise pour une équipe privée, un groupe) + level_2: + description: + other: Niveau 2 (faible réputation requise pour la communauté des startups) + level_3: + description: + other: Niveau 3 (haute réputation requise pour une communauté mature) + level_custom: + description: + other: Niveau personnalisé + rank_question_add_label: + other: Poser une question + rank_answer_add_label: + other: Écrire une réponse + rank_comment_add_label: + other: Ajouter un commentaire + rank_report_add_label: + other: Signaler + rank_comment_vote_up_label: + other: Voter favorablement le commentaire + rank_link_url_limit_label: + other: Poster plus de 2 liens à la fois + rank_question_vote_up_label: + other: Voter favorablement la question + rank_answer_vote_up_label: + other: Voter favorablement la réponse + rank_question_vote_down_label: + other: Voter contre la question + rank_answer_vote_down_label: + other: Voter contre la réponse + rank_invite_someone_to_answer_label: + other: Inviter quelqu'un à répondre + rank_tag_add_label: + other: Créer une nouvelle étiquette + rank_tag_edit_label: + other: Modifier la description de la balise (à réviser) + rank_question_edit_label: + other: Modifier la question des autres (à revoir) + rank_answer_edit_label: + other: Modifier la réponse d'un autre (à revoir) + rank_question_edit_without_review_label: + other: Modifier la question d'un autre utilisateur sans révision + rank_answer_edit_without_review_label: + other: Modifier la réponse d'un autre utilisateur sans révision + rank_question_audit_label: + other: Vérifier la question + rank_answer_audit_label: + other: Revoir les modifications de la réponse + rank_tag_audit_label: + other: Évaluer les modifications des tags + rank_tag_edit_without_review_label: + other: Modifier la description du tag sans révision + rank_tag_synonym_label: + other: Gérer les tags synonyme + email: + other: Email + e_mail: + other: Email + password: + other: Mot de passe + pass: + other: Mot de passe + old_pass: + other: Mot de passe actuel + original_text: + other: Ce post + email_or_password_wrong_error: + other: L'email et le mot de passe ne correspondent pas. + error: + common: + invalid_url: + other: URL invalide. + status_invalid: + other: Statut invalide. + password: + space_invalid: + other: Le mot de passe ne doit pas comporter d'espaces. + admin: + cannot_update_their_password: + other: Vous ne pouvez pas modifier votre mot de passe. + cannot_edit_their_profile: + other: Vous ne pouvez pas modifier votre profil. + cannot_modify_self_status: + other: Vous ne pouvez pas modifier votre statut. + email_or_password_wrong: + other: L'email et le mot de passe ne correspondent pas. + answer: + not_found: + other: Réponse introuvable. + cannot_deleted: + other: Pas de permission pour supprimer. + cannot_update: + other: Pas de permission pour mettre à jour. + question_closed_cannot_add: + other: Les questions sont fermées et ne peuvent pas être ajoutées. + content_cannot_empty: + other: La réponse ne peut être vide. + comment: + edit_without_permission: + other: Les commentaires ne sont pas autorisés à être modifiés. + not_found: + other: Commentaire non trouvé. + cannot_edit_after_deadline: + other: Le commentaire a été posté il y a trop longtemps pour être modifié. + content_cannot_empty: + other: Le commentaire ne peut être vide. + email: + duplicate: + other: L'adresse e-mail existe déjà. + need_to_be_verified: + other: L'adresse e-mail doit être vérifiée. + verify_url_expired: + other: L'URL de vérification de l'email a expiré, veuillez renvoyer l'email. + illegal_email_domain_error: + other: L'e-mail n'est pas autorisé à partir de ce domaine de messagerie. Veuillez en utiliser un autre. + lang: + not_found: + other: Fichier de langue non trouvé. + object: + captcha_verification_failed: + other: Le Captcha est incorrect. + disallow_follow: + other: Vous n’êtes pas autorisé à suivre. + disallow_vote: + other: Vous n’êtes pas autorisé à voter. + disallow_vote_your_self: + other: Vous ne pouvez pas voter pour votre propre message. + not_found: + other: Objet non trouvé. + verification_failed: + other: La vérification a échoué. + email_or_password_incorrect: + other: L'e-mail et le mot de passe ne correspondent pas. + old_password_verification_failed: + other: La vérification de l'ancien mot de passe a échoué + new_password_same_as_previous_setting: + other: Le nouveau mot de passe est le même que le précédent. + already_deleted: + other: Ce post a été supprimé. + meta: + object_not_found: + other: Méta objet introuvable + question: + already_deleted: + other: Ce message a été supprimé. + under_review: + other: Votre message est en attente de révision. Il sera visible une fois approuvé. + not_found: + other: Question non trouvée. + cannot_deleted: + other: Pas de permission pour supprimer. + cannot_close: + other: Pas de permission pour fermer. + cannot_update: + other: Pas de permission pour mettre à jour. + content_cannot_empty: + other: Le contenu ne peut pas être vide. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Le rang de réputation ne remplit pas la condition. + vote_fail_to_meet_the_condition: + other: Merci pour vos commentaires. Vous avez besoin d'au moins {{.Rank}} de réputation pour voter. + no_enough_rank_to_operate: + other: Vous avez besoin d'au moins {{.Rank}} de réputation pour faire cela. + report: + handle_failed: + other: La gestion du rapport a échoué. + not_found: + other: Rapport non trouvé. + tag: + already_exist: + other: Le tag existe déjà. + not_found: + other: Tag non trouvé. + recommend_tag_not_found: + other: Le tag Recommandé n'existe pas. + recommend_tag_enter: + other: Veuillez saisir au moins un tag. + not_contain_synonym_tags: + other: Ne dois pas contenir de tags synonymes. + cannot_update: + other: Pas de permission pour mettre à jour. + is_used_cannot_delete: + other: Vous ne pouvez pas supprimer un tag utilisé. + cannot_set_synonym_as_itself: + other: Vous ne pouvez pas définir le synonyme de la balise actuelle comme elle-même. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: Le nom d'expéditeur ne peut pas être une adresse e-mail. + theme: + not_found: + other: Thème non trouvé. + revision: + review_underway: + other: Impossible d'éditer actuellement, il y a une version dans la file d'attente des revues. + no_permission: + other: Aucune autorisation de réviser. + user: + external_login_missing_user_id: + other: La plateforme tierce ne fournit pas un identifiant d'utilisateur unique, vous ne pouvez donc pas vous connecter, veuillez contacter l'administrateur du site. + external_login_unbinding_forbidden: + other: Veuillez définir un mot de passe de connexion pour votre compte avant de supprimer ce login. + email_or_password_wrong: + other: + other: L'email et le mot de passe ne correspondent pas. + not_found: + other: Utilisateur non trouvé. + suspended: + other: L'utilisateur a été suspendu. + username_invalid: + other: Le nom d'utilisateur est invalide. + username_duplicate: + other: Nom d'utilisateur déjà utilisé. + set_avatar: + other: La configuration de l'avatar a échoué. + cannot_update_your_role: + other: Vous ne pouvez pas modifier votre rôle. + not_allowed_registration: + other: Actuellement, le site n'est pas ouvert aux inscriptions. + not_allowed_login_via_password: + other: Actuellement le site n'est pas autorisé à se connecter par mot de passe. + access_denied: + other: Accès refusé + page_access_denied: + other: Vous n'avez pas accès à cette page. + add_bulk_users_format_error: + other: "Erreur format {{.Field}} près de '{{.Content}}' à la ligne {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "Le nombre d'utilisateurs que vous ajoutez simultanément doit être compris entre 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: La lecture de la configuration a échoué + database: + connection_failed: + other: La connexion à la base de données a échoué + create_table_failed: + other: La création de la table a échoué + install: + create_config_failed: + other: Impossible de créer le fichier config.yaml. + upload: + unsupported_file_format: + other: Format de fichier non supporté. + site_info: + config_not_found: + other: Configuration du site introuvable. + badge: + object_not_found: + other: Objet badge introuvable + reason: + spam: + name: + other: Courrier indésirable + desc: + other: Ce message est une publicité ou un vandalisme. Il n'est pas utile ou pertinent pour le sujet actuel. + rude_or_abusive: + name: + other: grossier ou abusif + desc: + other: "Une personne raisonnable trouverait ce contenu inapproprié pour un discours respectueux." + a_duplicate: + name: + other: un doublon + desc: + other: Cette question a déjà été posée et a déjà une réponse. + placeholder: + other: Entrez le lien de la question existante + not_a_answer: + name: + other: n'est pas une réponse + desc: + other: "Cela a été posté comme une réponse, mais il n'essaie pas de répondre à la question. Il devrait s'agir d'un commentaire, d'une autre question, ou devrait être supprimé totalement." + no_longer_needed: + name: + other: ce n’est plus nécessaire + desc: + other: Ce commentaire est obsolète, conversationnel ou non pertinent pour ce post. + something: + name: + other: quelque chose d'autre + desc: + other: Ce message nécessite l'attention de l'équipe de modération pour une autre raison non listée ci-dessus. + placeholder: + other: Faites-nous savoir précisément ce qui vous préoccupe + community_specific: + name: + other: une raison spécifique à la communauté + desc: + other: Cette question ne répond pas à une directive de la communauté. + not_clarity: + name: + other: nécessite plus de détails ou de clarté + desc: + other: Cette question comprend actuellement plusieurs questions en une seule. Elle ne devrait se concentrer que sur un seul problème. + looks_ok: + name: + other: semble bien + desc: + other: Ce poste est bon en tant que tel et n'est pas de mauvaise qualité. + needs_edit: + name: + other: a besoin d'être modifié, et je l'ai fait + desc: + other: Améliorez et corrigez vous-même les problèmes liés à ce message. + needs_close: + name: + other: a besoin de fermer + desc: + other: Une question fermée ne peut pas être répondue, mais peut-être quand même modifiée, votée et commentée. + needs_delete: + name: + other: a besoin d'être supprimé + desc: + other: Ce message sera supprimé. + question: + close: + duplicate: + name: + other: courrier indésirable + desc: + other: Cette question a déjà été posée auparavant et a déjà une réponse. + guideline: + name: + other: une raison spécifique à la communauté + desc: + other: Cette question ne répond pas à une directive de la communauté. + multiple: + name: + other: a besoin de détails ou de clarté + desc: + other: Cette question comprend actuellement plusieurs questions en une seule. Elle ne devrait se concentrer que sur un seul problème. + other: + name: + other: quelque chose d'autre + desc: + other: Ce message nécessite l'attention du personnel pour une autre raison non listée ci-dessus. + operation_type: + asked: + other: demandé + answered: + other: répondu + modified: + other: modifié + deleted_title: + other: Question supprimée + questions_title: + other: Questions + tag: + tags_title: + other: Étiquettes + no_description: + other: L'étiquette n'a pas de description. + notification: + action: + update_question: + other: question mise à jour + answer_the_question: + other: question répondue + update_answer: + other: réponse mise à jour + accept_answer: + other: réponse acceptée + comment_question: + other: a commenté la question + comment_answer: + other: a commenté la réponse + reply_to_you: + other: vous a répondu + mention_you: + other: vous a mentionné + your_question_is_closed: + other: Une réponse a été publiée pour votre question + your_question_was_deleted: + other: Une réponse a été publiée pour votre question + your_answer_was_deleted: + other: Votre réponse a bien été supprimée + your_comment_was_deleted: + other: Votre commentaire a été supprimé + up_voted_question: + other: question approuvée + down_voted_question: + other: question défavorisée + up_voted_answer: + other: voter favorablement la réponse + down_voted_answer: + other: réponse défavorisée + up_voted_comment: + other: commentaire approuvé + invited_you_to_answer: + other: vous invite à répondre + earned_badge: + other: Vous avez gagné le badge "{{.BadgeName}}" + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Confirmez votre nouvelle adresse e-mail" + body: + other: "Confirmez votre nouvelle adresse électronique pour {{.SiteName}} en cliquant sur le lien suivant :
        \\n{{.ChangeEmailUrl}}

        \\n\\nSi vous n'avez pas demandé ce changement, veuillez ignorer cet e-mail.

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} a répondu à votre question" + body: + other: "{{.QuestionTitle}}

        \\n\\n{{.DisplayName}}:
        \\n
        {{.AnswerSummary}}

        \\nVoir sur {{.SiteName}}

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue.

        \\n\\nDésabonner" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} vous a invité à répondre" + body: + other: "{{.QuestionTitle}}

        \\n\\n{{.DisplayName}}:
        \\n
        Je pense que vous pourriez connaître la réponse.

        \\nVoir sur {{.SiteName}}

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue.

        \\n\\nDésabonner" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} a commenté votre message" + body: + other: "{{.QuestionTitle}}

        \\n\\n{{.DisplayName}}:
        \\n
        {{.CommentSummary}}

        \\nVoir sur {{.SiteName}}

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue.

        \\n\\nDésabonner" + new_question: + title: + other: "[{{.SiteName}}] Nouvelle question : {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote : Il s'agit d'un e-mail automatique, merci de ne pas répondre à ce message, votre réponse ne pourra être considérée.

        \n\nSe désabonner" + pass_reset: + title: + other: "[{{.SiteName }}] Réinitialisation du mot de passe" + body: + other: "Quelqu'un a demandé à réinitialiser votre mot de passe sur {{.SiteName}}.

        \\n\\nSi ce n'était pas vous, vous pouvez ignorer cet e-mail en toute sécurité.

        \\n\\nCliquez sur le lien suivant pour choisir un nouveau mot de passe :
        \\n{{.PassResetUrl}}\\n

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue." + register: + title: + other: "[{{.SiteName}}] Confirmez la création de votre compte" + body: + other: "Bienvenue sur {{.SiteName}}!

        \\n\\nCliquez sur le lien suivant pour confirmer et activer votre nouveau compte :
        \\n{{.RegisterUrl}}

        \\n\\nSi le lien ci-dessus n'est pas cliquable, essayez de le copier et de le coller dans la barre d'adresse de votre navigateur web.

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue." + test: + title: + other: "[{{.SiteName}}] Email de test" + body: + other: "Ceci est un e-mail de test.

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue." + action_activity_type: + upvote: + other: vote positif + upvoted: + other: voté pour + downvote: + other: voter contre + downvoted: + other: voté contre + accept: + other: accepter + accepted: + other: accepté + edit: + other: éditer + review: + queued_post: + other: Post en file d'attente + flagged_post: + other: Signaler post + suggested_post_edit: + other: Modifications suggérées + reaction: + tooltip: + other: "{{ .Names }} et {{ .Count }} de plus..." + badge: + default_badges: + autobiographer: + name: + other: Autobiographe + desc: + other: Informations sur le profil. + certified: + name: + other: Certifié + desc: + other: Nous avons terminé notre nouveau tutoriel d'utilisation. + editor: + name: + other: Éditeur + desc: + other: Première modification du post. + first_flag: + name: + other: Premier drapeau + desc: + other: Premier a signalé un post. + first_upvote: + name: + other: Premier vote positif + desc: + other: Premier a signalé un post. + first_link: + name: + other: Premier lien + desc: + other: A ajouté un lien vers un autre message. + first_reaction: + name: + other: Première réaction + desc: + other: Première réaction au post. + first_share: + name: + other: Premier partage + desc: + other: Premier post partagé. + scholar: + name: + other: Érudit + desc: + other: A posé une question et accepté une réponse. + commentator: + name: + other: Commentateur + desc: + other: Laissez 5 commentaires. + new_user_of_the_month: + name: + other: Nouvel utilisateur du mois + desc: + other: Contributions en suspens au cours de leur premier mois. + read_guidelines: + name: + other: Lire les lignes de conduite + desc: + other: Lisez les [lignes directrices de la communauté]. + reader: + name: + other: Lecteur + desc: + other: Lisez toutes les réponses dans un sujet avec plus de 10 réponses. + welcome: + name: + other: Bienvenue + desc: + other: A reçu un vote positif. + nice_share: + name: + other: Bien partagé + desc: + other: A partagé un poste avec 25 visiteurs uniques. + good_share: + name: + other: Bon partage + desc: + other: A partagé un poste avec 300 visiteurs uniques. + great_share: + name: + other: Super Partage + desc: + other: A partagé un poste avec 1000 visiteurs uniques. + out_of_love: + name: + other: Amoureux + desc: + other: A donné 50 likes dans une journée. + higher_love: + name: + other: Amour plus grand + desc: + other: A donné 50 likes dans une journée 5 fois. + crazy_in_love: + name: + other: Fou d'amour + desc: + other: A recueilli 50 votes positifs par jour 20 fois. + promoter: + name: + other: Promoteur + desc: + other: Inviter un utilisateur. + campaigner: + name: + other: Propagandiste + desc: + other: A invité 3 utilisateurs de base. + champion: + name: + other: Champion + desc: + other: A invité 5 membres. + thank_you: + name: + other: Merci + desc: + other: A 20 postes votés et a donné 10 votes. + gives_back: + name: + other: Redonne + desc: + other: A 100 postes votés et a donné 100 votes. + empathetic: + name: + other: Empathique + desc: + other: A 500 postes votés et a donné 1000 votes. + enthusiast: + name: + other: Enthousiaste + desc: + other: Visite de 10 jours consécutifs. + aficionado: + name: + other: Aficionado + desc: + other: Visite de 100 jours consécutifs. + devotee: + name: + other: Devotee + desc: + other: Visite de 365 jours consécutifs. + anniversary: + name: + other: Anniversaire + desc: + other: Membre actif pour une année, affiché au moins une fois. + appreciated: + name: + other: Apprécié + desc: + other: A reçu 1 vote positif sur 20 posts. + respected: + name: + other: Respecté + desc: + other: A reçu 2 vote positif sur 100 posts. + admired: + name: + other: Admirée + desc: + other: A reçu 5 vote positif sur 300 messages. + solved: + name: + other: Résolu + desc: + other: Une réponse a été acceptée. + guidance_counsellor: + name: + other: Conseiller d'orientation + desc: + other: 10 réponses sont acceptées. + know_it_all: + name: + other: Tout-savoir + desc: + other: 50 réponses sont acceptées. + solution_institution: + name: + other: Institution de solution + desc: + other: 150 réponses sont acceptées. + nice_answer: + name: + other: Belle réponse + desc: + other: Réponse a obtenu un score de 10 ou plus. + good_answer: + name: + other: Bonne répone + desc: + other: Réponse a obtenu un score de 25 ou plus. + great_answer: + name: + other: Super Réponse + desc: + other: Réponse a obtenu un score de 50 ou plus. + nice_question: + name: + other: Belle Question + desc: + other: Question a obtenu un score de 10 ou plus. + good_question: + name: + other: Bonne Question + desc: + other: Question a obtenu un score de 25 ou plus. + great_question: + name: + other: Super Question + desc: + other: Question a obtenu un score de 50 ou plus. + popular_question: + name: + other: Question Populaire + desc: + other: Question avec 500 points de vue. + notable_question: + name: + other: Question notable + desc: + other: Question avec 1,000 points de vue. + famous_question: + name: + other: Question célèbre + desc: + other: Question avec 5000 points de vue. + popular_link: + name: + other: Lien populaire + desc: + other: A posté un lien externe avec 50 clics. + hot_link: + name: + other: Lien chaud + desc: + other: A posté un lien externe avec 300 clics. + famous_link: + name: + other: Célèbre lien + desc: + other: A posté un lien externe avec 100 clics. + default_badge_groups: + getting_started: + name: + other: Initialisation complète + community: + name: + other: Communauté + posting: + name: + other: Publication +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Comment mettre en forme + desc: >- +
        • mentionner un post: #post_id

        • Pour faire des liens

          <https://url.com>

          [Title](https://url.com)
        • mettre des retour entre les paragraphes

        • _italic_ or **gras**

        • indenter le code par 4 espaces

        • citation en plaçant > au début de la ligne

        • guillemets inversés `comme_ca_`

        • créer une banière de code avec les guillemets inversés `

          ```
          code ici
          ```
        + pagination: + prev: Préc + next: Suivant + page_title: + question: Question + questions: Questions + tag: Étiquette + tags: Étiquettes + tag_wiki: tag wiki + create_tag: Créer un tag + edit_tag: Modifier l'étiquette + ask_a_question: Create Question + edit_question: Modifier la question + edit_answer: Modifier la réponse + search: Rechercher + posts_containing: Messages contenant + settings: Paramètres + notifications: Notifications + login: Se connecter + sign_up: S'inscrire + account_recovery: Récupération de compte + account_activation: Activation du compte + confirm_email: Confirmer l'email + account_suspended: Compte suspendu + admin: Admin + change_email: Modifier l'e-mail + install: Installation d'Answer + upgrade: Mise à jour d'Answer + maintenance: Maintenance du site + users: Utilisateurs + oauth_callback: Traitement + http_404: Erreur HTTP 404 + http_50X: Erreur HTTP 500 + http_403: Erreur HTTP 403 + logout: Se déconnecter + posts: Posts + notifications: + title: Notifications + inbox: Boîte de réception + achievement: Accomplissements + new_alerts: Nouvelles notifications + all_read: Tout marquer comme lu + show_more: Afficher plus + someone: Quelqu'un + inbox_type: + all: Tous + posts: Publications + invites: Invitations + votes: Votes + answer: Réponse + question: Question + badge_award: Badge + suspended: + title: Votre compte a été suspendu + until_time: "Votre compte a été suspendu jusqu'au {{ time }}." + forever: Cet utilisateur a été suspendu pour toujours. + end: Vous ne respectez pas les directives de la communauté. + contact_us: Contactez-nous + editor: + blockquote: + text: Bloc de citation + bold: + text: Gras + chart: + text: Diagramme + flow_chart: Organigramme + sequence_diagram: Diagramme de séquence + class_diagram: Diagramme de classe + state_diagram: Diagramme d'état + entity_relationship_diagram: Diagramme entité-association + user_defined_diagram: Diagramme défini par l'utilisateur + gantt_chart: Diagramme de Gantt + pie_chart: Camembert + code: + text: Exemple de Code + add_code: Ajouter un exemple de code + form: + fields: + code: + label: Code + msg: + empty: Le code ne peut pas être vide. + language: + label: Langage + placeholder: Détection automatique + btn_cancel: Annuler + btn_confirm: Ajouter + formula: + text: Formule + options: + inline: Formule en ligne + block: Bloc de formule + heading: + text: Titre + options: + h1: Titre de niveau 1 + h2: Titre de niveau 2 + h3: Titre de niveau 3 + h4: Titre de niveau 4 + h5: Titre de niveau 5 + h6: Titre de niveau 6 + help: + text: Aide + hr: + text: Ligne horizontale + image: + text: Image + add_image: Ajouter une image + tab_image: Téléverser une image + form_image: + fields: + file: + label: Fichier image + btn: Sélectionner une image + msg: + empty: Le fichier ne doit pas être vide. + only_image: Seules les images sont autorisées. + max_size: La taille du fichier ne doit pas dépasser {{size}} Mo. + desc: + label: Description + tab_url: URL de l'image + form_url: + fields: + url: + label: URL de l'image + msg: + empty: L'URL de l'image ne peut pas être vide. + name: + label: Description + btn_cancel: Annuler + btn_confirm: Ajouter + uploading: Téléversement en cours + indent: + text: Indentation + outdent: + text: Désindenter + italic: + text: Mise en valeur + link: + text: Hyperlien + add_link: Ajouter un lien hypertexte + form: + fields: + url: + label: URL + msg: + empty: L'URL ne peut pas être vide. + name: + label: Description + btn_cancel: Annuler + btn_confirm: Ajouter + ordered_list: + text: Liste numérotée + unordered_list: + text: Liste à puces + table: + text: Tableau + heading: Titre + cell: Cellule + file: + text: Joindre des fichiers + not_supported: "Ne prenez pas en charge ce type de fichier. Réessayez avec {{file_type}}." + max_size: "La taille du fichier ne doit pas dépasser {{size}} Mo." + close_modal: + title: Je ferme ce post comme... + btn_cancel: Annuler + btn_submit: Valider + remark: + empty: Ne peut pas être vide. + msg: + empty: Veuillez sélectionner une raison. + report_modal: + flag_title: Je suis en train de signaler ce post comme... + close_title: Je ferme ce post comme... + review_question_title: Vérifier la question + review_answer_title: Vérifier la réponse + review_comment_title: Revoir le commentaire + btn_cancel: Annuler + btn_submit: Envoyer + remark: + empty: Ne peut pas être vide. + msg: + empty: Veuillez sélectionner une raison s'il vous plaît. + not_a_url: Le format de l'URL est incorrect. + url_not_match: L'origine de l'URL ne correspond pas au site web actuel. + tag_modal: + title: Créer un nouveau tag + form: + fields: + display_name: + label: Nom Affiché + msg: + empty: Le nom d'affichage ne peut être vide. + range: Le nom doit contenir moins de 35 caractères. + slug_name: + label: Limace d'URL + desc: Titre de 35 caractères maximum. + msg: + empty: L'URL ne peut pas être vide. + range: Titre de 35 caractères maximum. + character: Le slug d'URL contient un jeu de caractères non autorisé. + desc: + label: Description + revision: + label: Révision + edit_summary: + label: Modifier le résumé + placeholder: >- + Expliquez brièvement vos modifications (orthographe corrigée, grammaire corrigée, mise en forme améliorée) + btn_cancel: Annuler + btn_submit: Valider + btn_post: Publier un nouveau tag + tag_info: + created_at: Créé + edited_at: Modifié + history: Historique + synonyms: + title: Synonymes + text: Les tags suivants seront redistribués vers + empty: Aucun synonyme trouvé. + btn_add: Ajouter un synonyme + btn_edit: Modifier + btn_save: Enregistrer + synonyms_text: Les balises suivantes seront remappées en + delete: + title: Supprimer cette étiquette + tip_with_posts: >- +

        Nous ne permettons pas la suppression d'un tag avec des posts

        Veuillez d'abord supprimer ce tag des posts.

        + tip_with_synonyms: >- +

        Nous ne permettons pas de supprimer un tag avec des synonymes.

        Veuillez d'abord supprimer les synonymes de ce tag.

        + tip: Êtes-vous sûr de vouloir supprimer ? + close: Fermer + merge: + title: Étiquette de fusion + source_tag_title: Étiquette de source + source_tag_description: Cette étiquette de source et ses données associées seront réorganisées vers l'étiquette cible. + target_tag_title: Étiquette cible + target_tag_description: Un synonyme entre ces deux étiquettes sera créé après la fusion. + no_results: Aucune étiquette correspondante + btn_submit: Valider + btn_close: Fermer + edit_tag: + title: Editer le tag + default_reason: Éditer le tag + default_first_reason: Ajouter un tag + btn_save_edits: Enregistrer les modifications + btn_cancel: Annuler + dates: + long_date: D MMM + long_date_with_year: "D MMMM YYYY" + long_date_with_time: "D MMM YYYY [at] HH:mm" + now: maintenant + x_seconds_ago: "il y a {{count}}s" + x_minutes_ago: "il y a {{count}}m" + x_hours_ago: "il y a {{count}}h" + hour: heure + day: jour + hours: heures + days: jours + month: month + months: months + year: year + reaction: + heart: cœur + smile: sourire + frown: froncer les sourcils + btn_label: ajout et suppression de réactions + undo_emoji: annuler la réaction {{ emoji }} + react_emoji: réagir à {{ emoji }} + unreact_emoji: annuler la réaction avec {{ emoji }} + comment: + btn_add_comment: Ajoutez un commentaire + reply_to: Répondre à + btn_reply: Répondre + btn_edit: Éditer + btn_delete: Supprimer + btn_flag: Balise + btn_save_edits: Enregistrer les modifications + btn_cancel: Annuler + show_more: "{{count}} commentaires restants" + tip_question: >- + Utilisez les commentaires pour demander plus d'informations ou suggérer des améliorations. Évitez de répondre aux questions dans les commentaires. + tip_answer: >- + Utilisez des commentaires pour répondre à d'autres utilisateurs ou leur signaler des modifications. Si vous ajoutez de nouvelles informations, modifiez votre message au lieu de commenter. + tip_vote: Il ajoute quelque chose d'utile au post + edit_answer: + title: Modifier la réponse + default_reason: Modifier la réponse + default_first_reason: Ajouter une réponse + form: + fields: + revision: + label: Modification + answer: + label: Réponse + feedback: + characters: le contenu doit comporter au moins 6 caractères. + edit_summary: + label: Modifier le résumé + placeholder: >- + Expliquez brièvement vos changements (correction orthographique, correction grammaticale, mise en forme améliorée) + btn_save_edits: Enregistrer les modifications + btn_cancel: Annuler + tags: + title: Étiquettes + sort_buttons: + popular: Populaire + name: Nom + newest: Le plus récent + button_follow: Suivre + button_following: Abonnements + tag_label: questions + search_placeholder: Filtrer par étiquette + no_desc: L'étiquette n'a pas de description. + more: Plus + wiki: Wiki + ask: + title: Create Question + edit_title: Modifier la question + default_reason: Modifier la question + default_first_reason: Create question + similar_questions: Questions similaires + form: + fields: + revision: + label: Modification + title: + label: Titre + placeholder: What's your topic? Be specific. + msg: + empty: Le titre ne peut pas être vide. + range: Titre de 150 caractères maximum + body: + label: Corps + msg: + empty: Le corps ne peut pas être vide. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Étiquettes + msg: + empty: Les étiquettes ne peuvent pas être vides. + answer: + label: Réponse + msg: + empty: La réponse ne peut être vide. + edit_summary: + label: Modifier le résumé + placeholder: >- + Expliquez brièvement vos changements (correction orthographique, correction grammaticale, mise en forme améliorée) + btn_post_question: Publier votre question + btn_save_edits: Enregistrer les modifications + answer_question: Répondre à votre propre question + post_question&answer: Publiez votre question et votre réponse + tag_selector: + add_btn: Ajouter une étiquette + create_btn: Créer une nouvelle étiquette + search_tag: Rechercher une étiquette + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: Aucune étiquette correspondante + tag_required_text: Étiquette requise (au moins une) + header: + nav: + question: Questions + tag: Étiquettes + user: Utilisateurs + badges: Badges + profile: Profil + setting: Paramètres + logout: Se déconnecter + admin: Administration + review: Vérifier + bookmark: Favoris + moderation: Modération + search: + placeholder: Rechercher + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Remplacer + loading: chargement en cours... + pic_auth_code: + title: Captcha + placeholder: Saisissez le texte ci-dessus + msg: + empty: Le captcha ne peut pas être vide. + inactive: + first: >- + Vous avez presque fini ! Un mail de confirmation a été envoyé à {{mail}}. Veuillez suivre les instructions dans le mail pour activer votre compte. + info: "S'il n'arrive pas, vérifiez dans votre dossier spam." + another: >- + Nous vous avons envoyé un autre e-mail d'activation à {{mail}}. Cela peut prendre quelques minutes pour arriver ; assurez-vous de vérifier votre dossier spam. + btn_name: Renvoyer le mail d'activation + change_btn_name: Modifier l'e-mail + msg: + empty: Ne peut pas être vide. + resend_email: + url_label: Êtes-vous sûr de vouloir renvoyer l'email d'activation ? + url_text: Vous pouvez également donner le lien d'activation ci-dessus à l'utilisateur. + login: + login_to_continue: Connectez-vous pour continuer + info_sign: Vous n'avez pas de compte ? <1>Inscrivez-vous + info_login: Vous avez déjà un compte ? <1>Connectez-vous + agreements: En vous inscrivant, vous acceptez la <1>politique de confidentialité et les <3>conditions de service. + forgot_pass: Mot de passe oublié ? + name: + label: Nom + msg: + empty: Le nom ne peut pas être vide. + range: Le nom doit contenir entre 2 et 30 caractères. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: Email + msg: + empty: L'email ne peut pas être vide. + password: + label: Mot de passe + msg: + empty: Le mot de passe ne peut pas être vide. + different: Les mots de passe saisis ne sont pas identiques + account_forgot: + page_title: Mot de passe oublié + btn_name: Envoyer un e-mail de récupération + send_success: >- + Si un compte est associé à {{mail}}, vous recevrez un email contenant les instructions pour réinitialiser votre mot de passe. + email: + label: E-mail + msg: + empty: L'e-mail ne peut pas être vide. + change_email: + btn_cancel: Annuler + btn_update: Mettre à jour l'adresse e-mail + send_success: >- + Si un compte est associé à {{mail}}, vous recevrez un email contenant les instructions pour réinitialiser votre mot de passe. + email: + label: Nouvel e-mail + msg: + empty: L'email ne peut pas être vide. + oauth: + connect: Se connecter avec {{ auth_name }} + remove: Retirer {{ auth_name }} + oauth_bind_email: + subtitle: Ajoutez un e-mail de récupération à votre compte. + btn_update: Mettre à jour l'adresse e-mail + email: + label: Email + msg: + empty: L'email ne peut pas être vide. + modal_title: L'email existe déjà. + modal_content: Cette adresse e-mail est déjà enregistrée. Êtes-vous sûr de vouloir vous connecter au compte existant ? + modal_cancel: Modifier l'adresse e-mail + modal_confirm: Se connecter au compte existant + password_reset: + page_title: Réinitialiser le mot de passe + btn_name: Réinitialiser mon mot de passe + reset_success: >- + Vous avez modifié votre mot de passe avec succès ; vous allez être redirigé vers la page de connexion. + link_invalid: >- + Désolé, ce lien de réinitialisation de mot de passe n'est plus valide. Peut-être que votre mot de passe est déjà réinitialisé ? + to_login: Continuer vers la page de connexion + password: + label: Mot de passe + msg: + empty: Le mot de passe ne peut pas être vide. + length: La longueur doit être comprise entre 8 et 32 + different: Les mots de passe saisis ne sont pas identiques + password_confirm: + label: Confirmer le nouveau mot de passe + settings: + page_title: Paramètres + goto_modify: Aller modifier + nav: + profile: Profil + notification: Notifications + account: Compte + interface: Interface + profile: + heading: Profil + btn_name: Enregistrer + display_name: + label: Nom affiché + msg: Le nom ne peut être vide. + msg_range: Le nom d'affichage doit contenir entre 2 et 30 caractères. + username: + label: Nom d'utilisateur + caption: Les gens peuvent vous mentionner avec "@username". + msg: Le nom d'utilisateur ne peut pas être vide. + msg_range: Le nom d'utilisateur doit contenir entre 2 et 30 caractères. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Photo de profil + gravatar: Gravatar + gravatar_text: Vous pouvez modifier l'image sur + custom: Personnaliser + custom_text: Vous pouvez charger votre image. + default: Système + msg: Veuillez charger un avatar + bio: + label: Biographie + website: + label: Site Web + placeholder: "https://example.com" + msg: Format du site web incorrect + location: + label: Position + placeholder: "Ville, Pays" + notification: + heading: Notifications + turn_on: Activer + inbox: + label: Notifications par e-mail + description: Réponses à vos questions, commentaires, invitaitons et plus. + all_new_question: + label: Toutes les nouvelles questions + description: Recevez une notification pour toutes les nouvelles questions. Jusqu'à 50 questions par semaine. + all_new_question_for_following_tags: + label: Toutes les nouvelles questions pour les tags suivants + description: Recevez une notification pour toutes les nouvelles questions avec les tags suivants. + account: + heading: Compte + change_email_btn: Modifier l'adresse e-mail + change_pass_btn: Changer le mot de passe + change_email_info: >- + Nous vous avons envoyé un mail à cette adresse. Merci de suivre les instructions. + email: + label: Email + new_email: + label: Nouvel e-mail + msg: La nouvelle adresse e-mail ne peut pas être vide. + pass: + label: Mot de passe actuel + msg: Le mot de passe ne peut pas être vide. + password_title: Mot de passe + current_pass: + label: Mot de passe actuel + msg: + empty: Le mot de passe actuel ne peut pas être vide. + length: La longueur doit être comprise entre 8 et 32. + different: Le mot de passe saisi ne correspond pas. + new_pass: + label: Nouveau mot de passe + pass_confirm: + label: Confirmer le nouveau mot de passe + interface: + heading: Interface + lang: + label: Langue de l'interface + text: Langue de l'interface utilisateur. Cela changera lorsque vous rafraîchissez la page. + my_logins: + title: Mes identifiants + label: Connectez-vous ou inscrivez-vous sur ce site en utilisant ces comptes. + modal_title: Supprimer la connexion + modal_content: Confirmez-vous vouloir supprimer cette connexion de votre compte ? + modal_confirm_btn: Supprimer + remove_success: Supprimé avec succès + toast: + update: mise à jour effectuée + update_password: Mot de passe changé avec succès. + flag_success: Merci pour votre signalement. + forbidden_operate_self: Interdit d'opérer sur vous-même + review: Votre révision s'affichera après vérification. + sent_success: Envoyé avec succès + related_question: + title: Related + answers: réponses + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Personnes interrogées + desc: Invite people who you think might know the answer. + invite: Inviter à répondre + add: Ajouter des personnes + search: Rechercher des personnes + question_detail: + action: Action + created: Created + Asked: Demandé + asked: demandé + update: Modifié + Edited: Edited + edit: modifié + commented: commenté + Views: Consultée + Follow: S’abonner + Following: Abonné(s) + follow_tip: Suivre cette question pour recevoir des notifications + answered: répondu + closed_in: Fermé dans + show_exist: Afficher la question existante. + useful: Utile + question_useful: C'est utile et clair + question_un_useful: Ce n'est pas clair ou n'est pas utile + question_bookmark: Ajouter cette question à vos favoris + answer_useful: C'est utile + answer_un_useful: Ce n'est pas utile + answers: + title: Réponses + score: Score + newest: Les plus récents + oldest: Le plus ancien + btn_accept: Accepter + btn_accepted: Accepté + write_answer: + title: Votre réponse + edit_answer: Modifier ma réponse existante + btn_name: Poster votre réponse + add_another_answer: Ajouter une autre réponse + confirm_title: Continuer à répondre + continue: Continuer + confirm_info: >- +

        Êtes-vous sûr de vouloir ajouter une autre réponse ?

        Vous pouvez utiliser le lien d'édition pour affiner et améliorer votre réponse existante.

        + empty: La réponse ne peut être vide. + characters: le contenu doit comporter au moins 6 caractères. + tips: + header_1: Merci pour votre réponse + li1_1: N’oubliez pas de répondre à la question. Fournissez des détails et partagez vos recherches. + li1_2: Sauvegardez toutes les déclarations que vous faites avec des références ou une expérience personnelle. + header_2: Mais évitez... + li2_1: Demander de l'aide, chercher des éclaircissements ou répondre à d'autres réponses. + reopen: + confirm_btn: Rouvrir + title: Rouvrir ce message + content: Êtes-vous sûr de vouloir rouvrir ? + list: + confirm_btn: Liste + title: Lister ce message + content: Êtes-vous sûr de vouloir lister ? + unlist: + confirm_btn: Délister + title: Masquer ce message de la liste + content: Êtes-vous sûr de vouloir masquer ce message de la liste ? + pin: + title: Épingler cet article + content: Êtes-vous sûr de vouloir l'épingler globalement ? Ce message apparaîtra en haut de toutes les listes de messages. + confirm_btn: Épingler + delete: + title: Supprimer la publication + question: >- + Nous ne recommandons pas de supprimer des questions avec des réponses car cela prive les futurs lecteurs de cette connaissance.

        Suppression répétée des questions répondues peut empêcher votre compte de poser. Êtes-vous sûr de vouloir supprimer ? + answer_accepted: >- +

        Nous ne recommandons pas de supprimer la réponse acceptée car cela prive les futurs lecteurs de cette connaissance.

        La suppression répétée des réponses acceptées peut empêcher votre compte de répondre. Êtes-vous sûr de vouloir supprimer ? + other: Êtes-vous sûr de vouloir supprimer ? + tip_answer_deleted: Cette réponse a été supprimée + undelete_title: Annuler la suppression de ce message + undelete_desc: Êtes-vous sûr de vouloir annuler la suppression ? + btns: + confirm: Confimer + cancel: Annuler + edit: Modifier + save: Enregistrer + delete: Supprimer + undelete: Annuler la suppression + list: Liste + unlist: Délister + unlisted: Non listé + login: Se connecter + signup: S'inscrire + logout: Se déconnecter + verify: Vérifier + create: Créer + approve: Approuver + reject: Rejeter + skip: Ignorer + discard_draft: Abandonner le brouillon + pinned: Épinglé + all: Tous + question: Question + answer: Réponse + comment: Commentaire + refresh: Actualiser + resend: Renvoyer + deactivate: Désactiver + active: Actif + suspend: Suspendre + unsuspend: Lever la suspension + close: Fermer + reopen: Rouvrir + ok: OK + light: Clair + dark: Sombre + system_setting: Paramètres système + default: Défaut + reset: Réinitialiser + tag: Étiquette + post_lowercase: publier + filter: Filtre + ignore: Ignore + submit: Soumettre + normal: Normal + closed: Fermé + deleted: Supprimé + deleted_permanently: Supprimé définitivement + pending: En attente de traitement + more: Plus + view: Vue + card: Carte + compact: Compact + display_below: Afficher dessous + always_display: Toujours afficher + or: ou + back_sites: Retour aux sites + search: + title: Résultats de la recherche + keywords: Mots-clés + options: Options + follow: Suivre + following: Abonnements + counts: "{{count}} Résultats" + counts_loading: "... Results" + more: Plus + sort_btns: + relevance: Pertinence + newest: Les plus récents + active: Actif + score: Score + more: Plus + tips: + title: Astuces de recherche avancée + tag: "<1>[tag] recherche à l'aide d'un tag" + user: "<1>utilisateur:username recherche par auteur" + answer: "<1>réponses:0 questions sans réponses" + score: "<1>score:3 messages avec plus de 3 points" + question: "<1>est:question rechercher des questions" + is_answer: "<1>est :réponse réponses de recherche" + empty: Nous n'avons rien trouvé.
        Essayez des mots-clés différents ou moins spécifiques. + share: + name: Partager + copy: Copier le lien + via: Partager via... + copied: Copié + facebook: Partager sur Facebook + twitter: Partager sur X + cannot_vote_for_self: Vous ne pouvez pas voter pour votre propre message. + modal_confirm: + title: Erreur... + delete_permanently: + title: Supprimer définitivement + content: Êtes-vous sûr de vouloir supprimer définitivement ? + account_result: + success: Votre nouveau compte est confirmé; vous serez redirigé vers la page d'accueil. + link: Continuer vers la page d'accueil + oops: Oups ! + invalid: Le lien que vous utilisez ne fonctionne plus. + confirm_new_email: Votre adresse email a été mise à jour. + confirm_new_email_invalid: >- + Désolé, ce lien de confirmation n'est plus valide. Votre email est peut-être déjà modifié ? + unsubscribe: + page_title: Se désabonner + success_title: Désabonnement réussi + success_desc: Vous avez été supprimé de cette liste d'abonnés avec succès et ne recevrez plus d'e-mails. + link: Modifier les paramètres + question: + following_tags: Hashtags suivis + edit: Éditer + save: Enregistrer + follow_tag_tip: Suivez les tags pour organiser votre liste de questions. + hot_questions: Questions populaires + all_questions: Toutes les questions + x_questions: "{{ count }} questions" + x_answers: "{{ count }} réponses" + x_posts: "{{ count }} Posts" + questions: Questions + answers: Réponses + newest: Les plus récents + active: Actif + hot: Populaires + frequent: Fréquent + recommend: Recommandé + score: Score + unanswered: Sans réponse + modified: modifié + answered: répondu + asked: demandé + closed: fermé + follow_a_tag: Suivre ce tag + more: Plus + personal: + overview: Aperçu + answers: Réponses + answer: réponse + questions: Questions + question: question + bookmarks: Favoris + reputation: Réputation + comments: Commentaires + votes: Votes + badges: Badges + newest: Les plus récents + score: Score + edit_profile: Éditer le profil + visited_x_days: "Visité {{ count }} jours" + viewed: Vu + joined: Inscrit + comma: "," + last_login: Vu + about_me: À propos de moi + about_me_empty: "// Hello, World !" + top_answers: Les meilleures réponses + top_questions: Questions les plus populaires + stats: Statistiques + list_empty: Aucune publication trouvée.
        Peut-être souhaiteriez-vous sélectionner un autre onglet ? + content_empty: Aucun post trouvé. + accepted: Accepté + answered: a répondu + asked: a demandé + downvoted: voté contre + mod_short: MOD + mod_long: Modérateurs + x_reputation: réputation + x_votes: votes reçus + x_answers: réponses + x_questions: questions + recent_badges: Badges récents + install: + title: Installation + next: Suivant + done: Terminé + config_yaml_error: Impossible de créer le fichier config.yaml. + lang: + label: Veuillez choisir une langue + db_type: + label: Moteur de base de données + db_username: + label: Nom d'utilisateur + placeholder: root + msg: Le nom d'utilisateur ne peut pas être vide. + db_password: + label: Mot de passe + placeholder: root + msg: Le mot de passe ne peut pas être vide. + db_host: + label: Hôte de la base de données + placeholder: "db:3306" + msg: L'hôte de la base de données ne peut pas être vide. + db_name: + label: Nom de la base de données + placeholder: réponse + msg: Le nom de la base de données ne peut pas être vide. + db_file: + label: Fichier de base de données + placeholder: /data/answer.db + msg: Le fichier de base de données ne doit pas être vide. + ssl_enabled: + label: Activer SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: Mode SSL + ssl_root_cert: + placeholder: Chemin du fichier sslrootcert + msg: Le chemin vers le fichier sslrootcert ne peut pas être vide + ssl_cert: + placeholder: Chemin du fichier sslcert + msg: Le chemin vers le fichier sslcert ne peut pas être vide + ssl_key: + placeholder: Chemin du fichier sslkey + msg: Le chemin vers le fichier sslkey ne peut pas être vide + config_yaml: + title: Créer config.yaml + label: Le fichier config.yaml a été créé. + desc: >- + Vous pouvez créer manuellement le fichier <1>config.yaml dans le répertoire <1>/var/wwww/xxx/ et y coller le texte suivant. + info: Après avoir fini, cliquez sur le bouton "Suivant". + site_information: Informations du site + admin_account: Compte Admin + site_name: + label: Nom du site + msg: Le nom ne peut pas être vide. + msg_max_length: Le nom affiché doit avoir une longueur de 4 à 30 caractères. + site_url: + label: URL du site + text: L'adresse de ce site. + msg: + empty: L'URL ne peut pas être vide. + incorrect: Le format de l'URL est incorrect. + max_length: L'URL du site doit avoir une longueur maximale de 512 caractères. + contact_email: + label: Email de contact + text: L'adresse email du responsable du site. + msg: + empty: L'email de contact ne peut pas être vide. + incorrect: Le format de l'email du contact est incorrect. + login_required: + label: Privé + switch: Connexion requise + text: Seuls les utilisateurs connectés peuvent accéder à cette communauté. + admin_name: + label: Nom + msg: Le nom ne peut pas être vide. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: La longueur du nom doit être comprise entre 2 et 30 caractères. + admin_password: + label: Mot de passe + text: >- + Vous aurez besoin de ce mot de passe pour vous connecter . Sauvegarder le de façon sécurisée. + msg: Le mot de passe ne peut pas être vide. + msg_min_length: Le mot de passe doit comporter au moins 8 caractères. + msg_max_length: Le mot de passe doit comporter au maximum 32 caractères. + admin_confirm_password: + label: "Répétez le mot de passe" + text: "Veuillez saisir à nouveau votre mot de passe pour confirmer." + msg: "Les mots de passe ne correspondent pas." + admin_email: + label: Email + text: Vous aurez besoin de cet email pour vous connecter. + msg: + empty: L'email ne peut pas être vide. + incorrect: Le format de l'email est incorrect. + ready_title: Votre site est prêt + ready_desc: >- + Si vous avez envie de changer plus de paramètres, visitez la <1>section admin; retrouvez la dans le menu du site. + good_luck: "Amusez-vous et bonne chance !" + warn_title: Attention + warn_desc: >- + Le fichier <1>config.yaml existe déjà. Si vous avez besoin de réinitialiser l'un des éléments de configuration de ce fichier, veuillez le supprimer d'abord. + install_now: Vous pouvez essayer de <1>l'installer maintenant. + installed: Déjà installé + installed_desc: >- + Il semble que se soit déjà installer. Pour tout réinstaller, veuillez d'abord nettoyer votre ancienne base de données. + db_failed: La connexion à la base de données a échoué + db_failed_desc: >- + Cela signifie que les informations de la base de données dans votre fichier <1>config.yaml est incorrect ou le contact avec le serveur de base de données n'a pas pu être établi. Cela pourrait signifier que le serveur de base de données de votre hôte est hors service. + counts: + views: vues + votes: votes + answers: réponses + accepted: Accepté + page_error: + http_error: Erreur HTTP {{ code }} + desc_403: Vous n'avez pas l'autorisation d'accéder à cette page. + desc_404: Malheureusement, cette page n'existe pas. + desc_50X: Le serveur a rencontré une erreur et n'a pas pu répondre à votre requête. + back_home: Retour à la page d'accueil + page_maintenance: + desc: "Nous sommes en maintenance, nous serons bientôt de retour." + nav_menus: + dashboard: Tableau de bord + contents: Contenus + questions: Questions + answers: Réponses + users: Utilisateurs + badges: Badges + flags: Signalements + settings: Paramètres + general: Général + interface: Interface + smtp: SMTP + branding: Marque + legal: Légal + write: Écrire + terms: Terms + tos: Conditions d'utilisation + privacy: Confidentialité + seo: SEO + customize: Personnaliser + themes: Thèmes + login: Se connecter + privileges: Privilèges + plugins: Extensions + installed_plugins: Extensions installées + apperance: Apparence + website_welcome: Bienvenue sur {{site_name}} + user_center: + login: Connexion + qrcode_login_tip: Veuillez utiliser {{ agentName }} pour scanner le code QR et vous connecter. + login_failed_email_tip: La connexion a échoué, veuillez autoriser cette application à accéder à vos informations de messagerie avant de réessayer. + badges: + modal: + title: Félicitations + content: Vous avez gagné un nouveau badge. + close: Fermer + confirm: Voir les badges + title: Badges + awarded: Octroyé + earned_×: Gagné ×{{ number }} + ×_awarded: "{{ number }} octroyés" + can_earn_multiple: Vous pouvez gagner cela plusieurs fois. + earned: Gagné + admin: + admin_header: + title: Admin + dashboard: + title: Tableau de bord + welcome: Bienvenue dans l'admin ! + site_statistics: Statistiques du site + questions: "Questions :" + resolved: "Résolu :" + unanswered: "Sans réponse :" + answers: "Réponses :" + comments: "Commentaires:" + votes: "Votes :" + users: "Utilisateurs :" + flags: "Signalements:" + reviews: "Revoir :" + site_health: Etat du site + version: "Version :" + https: "HTTPS :" + upload_folder: "Dossier de téléversement :" + run_mode: "Mode de fonctionnement :" + private: Privé + public: Public + smtp: "SMTP :" + timezone: "Fuseau horaire :" + system_info: Informations système + go_version: "Version de Go :" + database: "Base de donnée :" + database_size: "Taille de la base de données :" + storage_used: "Stockage utilisé :" + uptime: "Uptime :" + links: Liens + plugins: Extensions + github: GitHub + blog: Blog + contact: Contact + forum: Forum + documents: Documents + feedback: Commentaires + support: Support + review: Vérifier + config: Configuration + update_to: Mise à jour vers + latest: Récents + check_failed: Vérification échouée + "yes": "Oui" + "no": "Non" + not_allowed: Non autorisé + allowed: Autorisé + enabled: Activé + disabled: Désactivé + writable: Écriture autorisée + not_writable: Écriture refusée + flags: + title: Signalements + pending: En attente + completed: Complété + flagged: Signalé + flagged_type: Signalé {{ type }} + created: Créé + action: Action + review: Vérification + user_role_modal: + title: Changer le rôle d'un utilisateur en... + btn_cancel: Annuler + btn_submit: Valider + new_password_modal: + title: Définir un nouveau mot de passe + form: + fields: + password: + label: Mot de passe + text: L'utilisateur sera déconnecté et devra se connecter à nouveau. + msg: Le mot de passe doit contenir entre 8 et 32 caractères. + btn_cancel: Annuler + btn_submit: Envoyer + edit_profile_modal: + title: Éditer le profil + form: + fields: + display_name: + label: Nom affiché + msg_range: Le nom d'affichage doit contenir entre 2 et 30 caractères. + username: + label: Nom d'utilisateur + msg_range: Le nom d'utilisateur doit contenir entre 2 et 30 caractères. + email: + label: Email + msg_invalid: Adresse e-mail non valide. + edit_success: Modifié avec succès + btn_cancel: Annuler + btn_submit: Soumettre + user_modal: + title: Ajouter un nouvel utilisateur + form: + fields: + users: + label: Ajouter des utilisateurs en masse + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Séparez « nom, email, mot de passe » par des virgules. Un utilisateur par ligne. + msg: "Veuillez entrer l'email de l'utilisateur, un par ligne." + display_name: + label: Nom affiché + msg: Le nom affiché doit avoir une longueur de 2 à 30 caractères. + email: + label: Email + msg: L'email n'est pas valide. + password: + label: Mot de passe + msg: Le mot de passe doit comporter entre 8 et 32 caractères. + btn_cancel: Annuler + btn_submit: Valider + users: + title: Utilisateurs + name: Nom + email: E-mail + reputation: Réputation + created_at: Date de création + delete_at: Date de suppression + suspend_at: Date de suspension + suspend_until: Suspend until + status: Statut + role: Rôle + action: Action + change: Modifier + all: Tous + staff: Staff + more: Plus + inactive: Inactif + suspended: Suspendu + deleted: Supprimé + normal: Normal + Moderator: Modérateur + Admin: Administrateur + User: Utilisateur + filter: + placeholder: "Filtrer par nom, utilisateur:id" + set_new_password: Définir un nouveau mot de passe + edit_profile: Éditer le profil + change_status: Modifier le statut + change_role: Modifier le rôle + show_logs: Voir les logs + add_user: Ajouter un utilisateur + deactivate_user: + title: Désactiver l'utilisateur + content: Un utilisateur inactif doit revalider son email. + delete_user: + title: Supprimer cet utilisateur + content: Êtes-vous sûr de vouloir supprimer cet utilisateur ? Cette action est définitive ! + remove: Supprimer leur contenu + label: Supprimer toutes les questions, réponses, commentaires, etc. + text: Ne cochez pas cette case si vous souhaitez seulement supprimer le compte de l'utilisateur. + suspend_user: + title: Suspendre cet utilisateur + content: Un utilisateur suspendu ne peut pas se connecter. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Questions + unlisted: Non listé + post: Publication + votes: Votes + answers: Réponses + created: Créé + status: Statut + action: Action + change: Modifier + pending: En attente de traitement + filter: + placeholder: "Filtrer par titre, question:id" + answers: + page_title: Réponses + post: Publication + votes: Votes + created: Créé + status: Statut + action: Action + change: Modifier + filter: + placeholder: "Filtrer par titre, question:id" + general: + page_title: Général + name: + label: Nom du site + msg: Le nom ne peut pas être vide. + text: "Le nom de ce site, tel qu'il est utilisé dans la balise titre." + site_url: + label: URL du site + msg: L'URL ne peut pas être vide. + validate: Indiquez une URL valide. + text: L'adresse de ce site. + short_desc: + label: Courte description du site + msg: La description courte ne peut pas être vide. + text: "La description courte, telle qu'elle est utilisée dans le tag titre de la page d'accueil." + desc: + label: Description du site + msg: La description du site ne peut pas être vide. + text: "Décrivez ce site en une phrase, telle qu'elle est utilisée dans la balise meta description." + contact_email: + label: Email du contact + msg: L'email de contact ne peut pas être vide. + validate: L'email de contact n'est pas valide. + text: L'adresse email du responsable du site. + check_update: + label: Mises à jour logicielles + text: Rechercher automatiquement les mises à jour + interface: + page_title: Interface + language: + label: Langue de l'interface + msg: La langue de l'interface ne peut pas être vide. + text: Langue de l'interface de l'utilisateur. Cela changera lorsque vous rafraîchissez la page. + time_zone: + label: Fuseau Horaire + msg: Le fuseau horaire ne peut pas être vide. + text: Choisissez une ville dans le même fuseau horaire que vous. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: E-mail de l'expéditeur + msg: L'email expéditeur ne peut pas être vide. + text: L'adresse email à partir de laquelle les emails sont envoyés. + from_name: + label: Nom de l'expéditeur + msg: Le nom expéditeur ne peut pas être vide. + text: Le nom d'expéditeur à partir duquel les emails sont envoyés. + smtp_host: + label: Serveur SMTP + msg: Le'hôte SMTP ne peut pas être vide. + text: Votre serveur de mail. + encryption: + label: Chiffrement + msg: Le chiffrement ne peut pas être vide. + text: Pour la plupart des serveurs, l'option SSL est recommandée. + ssl: SSL + tls: TLS + none: Aucun + smtp_port: + label: Port SMTP + msg: Le port SMTP doit être compris entre 1 et 65535. + text: Le port vers votre serveur d'email. + smtp_username: + label: Utilisateur SMTP + msg: Le nom d'utilisateur SMTP ne peut pas être vide. + smtp_password: + label: Mot de passe SMTP + msg: Le mot de passe SMTP ne peut être vide. + test_email_recipient: + label: Destinataires des e-mails de test + text: Indiquez l'adresse email qui recevra l'email de test. + msg: Le destinataire de l'email de test est invalide + smtp_authentication: + label: Activer l'authentification + title: Authentification SMTP + msg: L'authentification SMTP ne peut pas être vide. + "yes": "Oui" + "no": "Non" + branding: + page_title: Marque + logo: + label: Logo + msg: Le logo ne peut pas être vide. + text: L'image du logo en haut à gauche de votre site. Utilisez une grande image rectangulaire avec une hauteur de 56 et un ratio d'aspect supérieur à 3:1. Si laissé vide, le titre du site sera affiché. + mobile_logo: + label: Logo pour la version mobile + text: Le logo utilisé sur la version mobile de votre site. Utilisez une image rectangulaire large avec une hauteur de 56. Si laissé vide, l'image du paramètre « logo » sera utilisée. + square_icon: + label: Icône carrée + msg: L'icône carrée ne peut pas être vide. + text: Image utilisée comme base pour les icônes de métadonnées. Idéalement supérieure à 512x512. + favicon: + label: Favicon + text: Une favicon pour votre site. Pour fonctionner correctement sur un CDN, il doit s'agir d'un png. Sera redimensionné en 32x32. Si laissé vide, « icône carrée » sera utilisé. + legal: + page_title: Légal + terms_of_service: + label: Conditions d’utilisation + text: "Vous pouvez ajouter le contenu des conditions de service ici. Si vous avez déjà un document hébergé ailleurs, veuillez fournir l'URL complète ici." + privacy_policy: + label: Protection des données + text: "Vous pouvez ajouter le contenu des conditions de service ici. Si vous avez déjà un document hébergé ailleurs, veuillez fournir l'URL complète ici." + external_content_display: + label: Contenu externe + text: "Le contenu comprend des images, des vidéos et des médias intégrés à partir de sites web externes." + always_display: Toujours afficher le contenu externe + ask_before_display: Demander avant d'afficher le contenu externe + write: + page_title: Écrire + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Écriture de la réponse + label: Chaque utilisateur ne peut écrire qu'une seule réponse pour chaque question + text: "Désactivez pour permettre aux utilisateurs d'écrire plusieurs réponses à la même question, ce qui peut causer une perte de concentration des réponses." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Tags recommandés + text: "Les balises recommandées apparaîtront par défaut dans la liste déroulante." + msg: + contain_reserved: "les tags recommandés ne peuvent pas contenir de tags réservés" + required_tag: + title: Définir les tags nécessaires + label: Définir les balises « Recommander» comme balises requises + text: "Chaque nouvelle question doit avoir au moins un tag recommandé." + reserved_tags: + label: Tags réservés + text: "Les tags réservés ne peuvent être ajoutés à un message que par un modérateur." + image_size: + label: Taille maximale de l'image (MB) + text: "La taille maximale de téléchargement d'image." + attachment_size: + label: Taille maximale des pièces jointes (MB) + text: "La taille maximale de téléchargement des fichiers joints." + image_megapixels: + label: Max mégapixels image + text: "Nombre maximum de mégapixels autorisés pour une image." + image_extensions: + label: Extensions de pièces jointes autorisées + text: "Une liste d'extensions de fichier autorisées pour l'affichage d'image, séparées par des virgules." + attachment_extensions: + label: Extensions de pièces jointes autorisées + text: "Une liste d'extensions de fichier autorisées pour le téléchargement, séparées par des virgules. ATTENTION : Autoriser les envois peut causer des problèmes de sécurité." + seo: + page_title: Référencement + permalink: + label: Lien permanent + text: Des structures d'URL personnalisées peuvent améliorer la facilité d'utilisation et la compatibilité de vos liens. + robots: + label: robots.txt + text: Ceci remplacera définitivement tous les paramètres liés au site. + themes: + page_title: Thèmes + themes: + label: Thèmes + text: Sélectionne un thème existant. + color_scheme: + label: Jeu de couleurs + navbar_style: + label: Style d'arrière-plan de la barre de navigation + primary_color: + label: Couleur primaire + text: Modifier les couleurs utilisées par vos thèmes + css_and_html: + page_title: CSS et HTML + custom_css: + label: CSS personnalisé + text: > + + head: + label: Head + text: > + + header: + label: En-tête + text: > + + footer: + label: Pied de page + text: Ceci va être inséré avant </html>. + sidebar: + label: Panneau latéral + text: Cela va être inséré dans la barre latérale. + login: + page_title: Se connecter + membership: + title: Adhésion + label: Autoriser les inscriptions + text: Désactivez pour empêcher quiconque de créer un nouveau compte. + email_registration: + title: Inscription par e-mail + label: Autoriser l'inscription par e-mail + text: Désactiver pour empêcher toute personne de créer un nouveau compte par e-mail. + allowed_email_domains: + title: Domaines d'email autorisés + text: Domaines de messagerie avec lesquels les utilisateurs peuvent créer des comptes. Un domaine par ligne. Ignoré si vide. + private: + title: Privé + label: Connexion requise + text: Seuls les utilisateurs connectés peuvent accéder à cette communauté. + password_login: + title: Connexion par mot de passe + label: Autoriser la connexion par e-mail et mot de passe + text: "AVERTISSEMENT : Si cette option est désactivée, vous ne pourrez peut-être pas vous connecter si vous n'avez pas configuré une autre méthode de connexion." + installed_plugins: + title: Extensions installées + plugin_link: Les plugins étendent les fonctionnalités d'Answer. Vous pouvez trouver des plugins dans le dépôt <1>Answer Plugin Repositor. + filter: + all: Tous + active: Actif + inactive: Inactif + outdated: Est obsolète + plugins: + label: Extensions + text: Sélectionnez une extension existante. + name: Nom + version: Versión + status: Statut + action: Action + deactivate: Désactiver + activate: Activer + settings: Paramètres + settings_users: + title: Utilisateurs + avatar: + label: Photo de profil par défaut + text: Pour les utilisateurs sans avatar personnalisé. + gravatar_base_url: + label: Gravatar Base URL + text: URL de la base de l'API du fournisseur Gravatar. Ignorée lorsqu'elle est vide. + profile_editable: + title: Profil modifiable + allow_update_display_name: + label: Permettre aux utilisateurs de changer leur nom d'affichage + allow_update_username: + label: Permettre aux clients de changer leurs noms d'utilisateur + allow_update_avatar: + label: Permettre aux utilisateurs de changer leur image de profil + allow_update_bio: + label: Permettre aux utilisateurs de changer leur biographie + allow_update_website: + label: Permettre aux utilisateurs de modifier leur site web + allow_update_location: + label: Permettre aux utilisateurs de modifier leur position + privilege: + title: Privilèges + level: + label: Niveau de réputation requis + text: Choisissez la réputation requise pour les privilèges + msg: + should_be_number: l'entrée doit être un nombre + number_larger_1: le nombre doit être égal ou supérieur à 1 + badges: + action: Action + active: Actif + activate: Activer + all: Tous + awards: Récompenses + deactivate: Désactiver + filter: + placeholder: Filtrer par nom, badge:id + group: Groupe + inactive: Inactif + name: Nom + show_logs: Voir les logs + status: Statut + title: Badges + form: + optional: (optionnel) + empty: ne peut pas être vide + invalid: est invalide + btn_submit: Sauvegarder + not_found_props: "La propriété requise {{ key }} est introuvable." + select: Sélectionner + page_review: + review: Vérifier + proposed: proposé + question_edit: Modifier la question + answer_edit: Modifier la réponse + tag_edit: Modifier le tag + edit_summary: Modifier le résumé + edit_question: Modifier la question + edit_answer: Modifier la réponse + edit_tag: Modifier l’étiquette + empty: Aucune révision restante. + approve_revision_tip: Acceptez-vous cette révision? + approve_flag_tip: Acceptez-vous ce rapport ? + approve_post_tip: Acceptez-vous ce post? + approve_user_tip: Acceptez-vous cet utilisateur ? + suggest_edits: Modifications suggérées + flag_post: Signaler ce message + flag_user: Signaler un utilisateur + queued_post: Message en file d'attente + queued_user: Utilisateur en file d'attente + filter_label: Type + reputation: réputation + flag_post_type: A signalé ce message comme {{ type }}. + flag_user_type: A signalé cet utilisateur comme {{ type }}. + edit_post: Éditer le post + list_post: Lister le post + unlist_post: Masquer la post de la liste + timeline: + undeleted: restauré + deleted: supprimé + downvote: vote négatif + upvote: voter pour + accept: accepté + cancelled: annulé + commented: commenté + rollback: Retour arrière (Rollback) + edited: modifié + answered: répondu + asked: demandé + closed: fermé + reopened: réouvert + created: créé + pin: épinglé + unpin: non épinglé + show: listé + hide: non listé + title: "Historique de" + tag_title: "Chronologie de" + show_votes: "Afficher les votes" + n_or_a: N/A + title_for_question: "Chronologie de" + title_for_answer: "Chronologie de la réponse à {{ title }} par {{ author }}" + title_for_tag: "Chronologie pour le tag" + datetime: Date et heure + type: Type + by: Par + comment: Commentaire + no_data: "Nous n'avons rien pu trouver." + users: + title: Utilisateurs + users_with_the_most_reputation: Utilisateurs ayant le score de réputation le plus élevé cette semaine + users_with_the_most_vote: Utilisateurs qui ont le plus voté cette semaine + staffs: Staff de la communauté + reputation: réputation + votes: votes + prompt: + leave_page: Voulez-vous vraiment quitter la page ? + changes_not_save: Impossible d'enregistrer vos modifications. + draft: + discard_confirm: Êtes-vous sûr de vouloir abandonner ce brouillon ? + messages: + post_deleted: Ce message a été supprimé. + post_cancel_deleted: Ce post a été restauré. + post_pin: Ce message a été épinglé. + post_unpin: Ce message a été déépinglé. + post_hide_list: Ce message a été masqué de la liste. + post_show_list: Ce message a été affiché dans la liste. + post_reopen: Ce message a été rouvert. + post_list: Ce post a été ajouté à la liste. + post_unlist: Ce post a été retiré de la liste. + post_pending: Votre message est en attente de révision. C'est un aperçu, il sera visible une fois qu'il aura été approuvé. + post_closed: Ce post a été fermé. + answer_deleted: Cette réponse a été supprimée. + answer_cancel_deleted: Cette réponse a été restaurée. + change_user_role: Le rôle de cet utilisateur a été modifié. + user_inactive: Cet utilisateur est déjà inactif. + user_normal: Cet utilisateur est déjà normal. + user_suspended: Cet utilisateur a été suspendu. + user_deleted: Cet utilisateur a été supprimé. + badge_activated: Ce badge a été activé. + badge_inactivated: Ce badge a été désactivé. + users_deleted: Ces utilisateurs ont été supprimés. + posts_deleted: Ces questions ont été supprimées. + answers_deleted: Ces réponses ont été supprimées. + copy: Copier dans le presse-papier + copied: Copié + external_content_warning: Les images/médias externes ne sont pas affichés. + + diff --git a/data/i18n/he_IL.yaml b/data/i18n/he_IL.yaml new file mode 100644 index 000000000..25c086f11 --- /dev/null +++ b/data/i18n/he_IL.yaml @@ -0,0 +1,1384 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: Success. + unknown: + other: Unknown error. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + email: + other: Email + password: + other: Password + email_or_password_wrong_error: + other: Email and password do not match. + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + question: + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + rank: + fail_to_meet_the_condition: + other: Rank fail to meet the condition. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend Tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + smtp: + config_from_name_cannot_be_email: + other: The From Name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to Revision. + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + report: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude: + name: + other: rude or abusive + desc: + other: A reasonable person would find this content inappropriate for respectful discourse. + duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + not_answer: + name: + other: not an answer + desc: + other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. + not_need: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + other: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comments + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to {{site_name}} + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to {{site_name}} + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/hi_IN.yaml b/data/i18n/hi_IN.yaml new file mode 100644 index 000000000..17b0a6109 --- /dev/null +++ b/data/i18n/hi_IN.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Success. + unknown: + other: Unknown error. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + forbidden_error: + other: Forbidden. + duplicate_request_error: + other: Duplicate submission. + action: + report: + other: Flag + edit: + other: Edit + delete: + other: Delete + close: + other: Close + reopen: + other: Reopen + forbidden_error: + other: Forbidden. + pin: + other: Pin + hide: + other: Unlist + unpin: + other: Unpin + show: + other: List + invite_someone_to_answer: + other: Edit + undelete: + other: Undelete + merge: + other: Merge + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + privilege: + level_1: + description: + other: Level 1 (less reputation required for private team, group) + level_2: + description: + other: Level 2 (low reputation required for startup community) + level_3: + description: + other: Level 3 (high reputation required for mature community) + level_custom: + description: + other: Custom Level + rank_question_add_label: + other: Ask question + rank_answer_add_label: + other: Write answer + rank_comment_add_label: + other: Write comment + rank_report_add_label: + other: Flag + rank_comment_vote_up_label: + other: Upvote comment + rank_link_url_limit_label: + other: Post more than 2 links at a time + rank_question_vote_up_label: + other: Upvote question + rank_answer_vote_up_label: + other: Upvote answer + rank_question_vote_down_label: + other: Downvote question + rank_answer_vote_down_label: + other: Downvote answer + rank_invite_someone_to_answer_label: + other: Invite someone to answer + rank_tag_add_label: + other: Create new tag + rank_tag_edit_label: + other: Edit tag description (need to review) + rank_question_edit_label: + other: Edit other's question (need to review) + rank_answer_edit_label: + other: Edit other's answer (need to review) + rank_question_edit_without_review_label: + other: Edit other's question without review + rank_answer_edit_without_review_label: + other: Edit other's answer without review + rank_question_audit_label: + other: Review question edits + rank_answer_audit_label: + other: Review answer edits + rank_tag_audit_label: + other: Review tag edits + rank_tag_edit_without_review_label: + other: Edit tag description without review + rank_tag_synonym_label: + other: Manage tag synonyms + email: + other: Email + e_mail: + other: Email + password: + other: Password + pass: + other: Password + old_pass: + other: Current password + original_text: + other: This post + email_or_password_wrong_error: + other: Email and password do not match. + error: + common: + invalid_url: + other: Invalid URL. + status_invalid: + other: Invalid status. + password: + space_invalid: + other: Password cannot contain spaces. + admin: + cannot_update_their_password: + other: You cannot modify your password. + cannot_edit_their_profile: + other: You cannot modify your profile. + cannot_modify_self_status: + other: You cannot modify your status. + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + question_closed_cannot_add: + other: Questions are closed and cannot be added. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + illegal_email_domain_error: + other: Email is not allowed from that email domain. Please use another one. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + already_deleted: + other: This post has been deleted. + meta: + object_not_found: + other: Meta object not found + question: + already_deleted: + other: This post has been deleted. + under_review: + other: Your post is awaiting review. It will be visible after it has been approved. + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Reputation rank fail to meet the condition. + vote_fail_to_meet_the_condition: + other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. + no_enough_rank_to_operate: + other: You need at least {{.Rank}} reputation to do this. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + already_exist: + other: Tag already exists. + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + is_used_cannot_delete: + other: You cannot delete a tag that is in use. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: The from name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to revise. + user: + external_login_missing_user_id: + other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. + external_login_unbinding_forbidden: + other: Please set a login password for your account before you remove this login. + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration. + not_allowed_login_via_password: + other: Currently the site is not allowed to login via password. + access_denied: + other: Access denied + page_access_denied: + other: You do not have access to this page. + add_bulk_users_format_error: + other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + site_info: + config_not_found: + other: Site config not found. + badge: + object_not_found: + other: Badge object not found + reason: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude_or_abusive: + name: + other: rude or abusive + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + a_duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + placeholder: + other: Enter the existing question link + not_a_answer: + name: + other: not an answer + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." + no_longer_needed: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + something: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + placeholder: + other: Let us know specifically what you are concerned about + community_specific: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + not_clarity: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + looks_ok: + name: + other: looks OK + desc: + other: This post is good as-is and not low quality. + needs_edit: + name: + other: needs edit, and I did it + desc: + other: Improve and correct problems with this post yourself. + needs_close: + name: + other: needs close + desc: + other: A closed question can't answer, but still can edit, vote and comment. + needs_delete: + name: + other: needs delete + desc: + other: This post will be deleted. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + deleted_title: + other: Deleted question + questions_title: + other: Questions + tag: + tags_title: + other: Tags + no_description: + other: The tag has no description. + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted + up_voted_question: + other: upvoted question + down_voted_question: + other: downvoted question + up_voted_answer: + other: upvoted answer + down_voted_answer: + other: downvoted answer + up_voted_comment: + other: upvoted comment + invited_you_to_answer: + other: invited you to answer + earned_badge: + other: You've earned the "{{.BadgeName}}" badge + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Confirm your new email address" + body: + other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} answered your question" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_question: + title: + other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Password reset" + body: + other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + register: + title: + other: "[{{.SiteName}}] Confirm your new account" + body: + other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + test: + title: + other: "[{{.SiteName}}] Test Email" + body: + other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + action_activity_type: + upvote: + other: upvote + upvoted: + other: upvoted + downvote: + other: downvote + downvoted: + other: downvoted + accept: + other: accept + accepted: + other: accepted + edit: + other: edit + review: + queued_post: + other: Queued post + flagged_post: + other: Flagged post + suggested_post_edit: + other: Suggested edits + reaction: + tooltip: + other: "{{ .Names }} and {{ .Count }} more..." + badge: + default_badges: + autobiographer: + name: + other: Autobiographer + desc: + other: Filled out profile information. + certified: + name: + other: Certified + desc: + other: Completed our new user tutorial. + editor: + name: + other: Editor + desc: + other: First post edit. + first_flag: + name: + other: First Flag + desc: + other: First flagged a post. + first_upvote: + name: + other: First Upvote + desc: + other: First up voted a post. + first_link: + name: + other: First Link + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: First Share + desc: + other: First shared a post. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Leave 5 comments. + new_user_of_the_month: + name: + other: New User of the Month + desc: + other: Outstanding contributions in their first month. + read_guidelines: + name: + other: Read Guidelines + desc: + other: Read the [community guidelines]. + reader: + name: + other: Reader + desc: + other: Read every answers in a topic with more than 10 answers. + welcome: + name: + other: Welcome + desc: + other: Received a up vote. + nice_share: + name: + other: Nice Share + desc: + other: Shared a post with 25 unique visitors. + good_share: + name: + other: Good Share + desc: + other: Shared a post with 300 unique visitors. + great_share: + name: + other: Great Share + desc: + other: Shared a post with 1000 unique visitors. + out_of_love: + name: + other: Out of Love + desc: + other: Used 50 up votes in a day. + higher_love: + name: + other: Higher Love + desc: + other: Used 50 up votes in a day 5 times. + crazy_in_love: + name: + other: Crazy in Love + desc: + other: Used 50 up votes in a day 20 times. + promoter: + name: + other: Promoter + desc: + other: Invited a user. + campaigner: + name: + other: Campaigner + desc: + other: Invited 3 basic users. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: Thank You + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Active member for a year, posted at least once. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + create_tag: Create Tag + edit_tag: Edit Tag + ask_a_question: Create Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + oauth_callback: Processing + http_404: HTTP Error 404 + http_50X: HTTP Error 500 + http_403: HTTP Error 403 + logout: Log Out + posts: Posts + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + new_alerts: New alerts + all_read: Mark all as read + show_more: Show more + someone: Someone + inbox_type: + all: All + posts: Posts + invites: Invites + votes: Votes + answer: Answer + question: Question + badge_award: Badge + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + contact_us: Contact us + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image file + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed {{size}} MB. + desc: + label: Description + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered list + unordered_list: + text: Bulleted list + table: + text: Table + heading: Heading + cell: Cell + file: + text: Attach files + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + not_a_url: URL format is incorrect. + url_not_match: URL origin does not match the current website. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description + revision: + label: Revision + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_cancel: Cancel + btn_submit: Submit + btn_post: Post new tag + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + tip_with_posts: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + tip_with_synonyms: >- +

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        + tip: Are you sure you wish to delete? + close: Close + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + default_first_reason: Add tag + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + hours: hours + days: days + month: month + months: months + year: year + reaction: + heart: heart + smile: smile + frown: frown + btn_label: add or remove reactions + undo_emoji: undo {{ emoji }} reaction + react_emoji: react with {{ emoji }} + unreact_emoji: unreact with {{ emoji }} + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: "{{count}} more comments" + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + tip_vote: It adds something useful to the post + edit_answer: + title: Edit Answer + default_reason: Edit answer + default_first_reason: Add answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: Newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + wiki: Wiki + ask: + title: Create Question + edit_title: Edit Question + default_reason: Edit question + default_first_reason: Create question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: What's your topic? Be specific. + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + badges: Badges + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + bookmark: Bookmarks + moderation: Moderation + search: + placeholder: Search + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + resend_email: + url_label: Are you sure you want to resend the activation email? + url_text: You can also give the activation link above to the user. + login: + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New email + msg: + empty: Email cannot be empty. + oauth: + connect: Connect with {{ auth_name }} + remove: Remove {{ auth_name }} + oauth_bind_email: + subtitle: Add a recovery email to your account. + btn_update: Update email address + email: + label: Email + msg: + empty: Email cannot be empty. + modal_title: Email already existes. + modal_content: This email address already registered. Are you sure you want to connect to the existing account? + modal_cancel: Change email + modal_confirm: Connect to the existing account + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm new password + settings: + page_title: Settings + goto_modify: Go to modify + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile image + gravatar: Gravatar + gravatar_text: You can change image on + custom: Custom + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About me + website: + label: Website + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location + placeholder: "City, Country" + notification: + heading: Email Notifications + turn_on: Turn on + inbox: + label: Inbox notifications + description: Answers to your questions, comments, invites, and more. + all_new_question: + label: All new questions + description: Get notified of all new questions. Up to 50 questions per week. + all_new_question_for_following_tags: + label: All new questions for following tags + description: Get notified of new questions for following tags. + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + pass: + label: Current password + msg: Password cannot be empty. + password_title: Password + current_pass: + label: Current password + msg: + empty: Current password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New password + pass_confirm: + label: Confirm new password + interface: + heading: Interface + lang: + label: Interface language + text: User interface language. It will change when you refresh the page. + my_logins: + title: My logins + label: Log in or sign up on this site using these accounts. + modal_title: Remove login + modal_content: Are you sure you want to remove this login from your account? + modal_confirm_btn: Remove + remove_success: Removed successfully + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + sent_success: Sent successfully + related_question: + title: Related + answers: answers + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: People Asked + desc: Select people who you think might know the answer. + invite: Invite to answer + add: Add people + search: Search people + question_detail: + action: Action + created: Created + Asked: Asked + asked: asked + update: Modified + Edited: Edited + edit: edited + commented: commented + Views: Viewed + Follow: Follow + Following: Following + follow_tip: Follow this question to receive notifications + answered: answered + closed_in: Closed in + show_exist: Show existing question. + useful: Useful + question_useful: It is useful and clear + question_un_useful: It is unclear or not useful + question_bookmark: Bookmark this question + answer_useful: It is useful + answer_un_useful: It is not useful + answers: + title: Answers + score: Score + newest: Newest + oldest: Oldest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + edit_answer: Edit my existing answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + tips: + header_1: Thanks for your answer + li1_1: Please be sure to answer the question. Provide details and share your research. + li1_2: Back up any statements you make with references or personal experience. + header_2: But avoid ... + li2_1: Asking for help, seeking clarification, or responding to other answers. + reopen: + confirm_btn: Reopen + title: Reopen this post + content: Are you sure you want to reopen? + list: + confirm_btn: List + title: List this post + content: Are you sure you want to list? + unlist: + confirm_btn: Unlist + title: Unlist this post + content: Are you sure you want to unlist? + pin: + title: Pin this post + content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. + confirm_btn: Pin + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_answer_deleted: This answer has been deleted + undelete_title: Undelete this post + undelete_desc: Are you sure you wish to undelete? + btns: + confirm: Confirm + cancel: Cancel + edit: Edit + save: Save + delete: Delete + undelete: Undelete + list: List + unlist: Unlist + unlisted: Unlisted + login: Log in + signup: Sign up + logout: Log out + verify: Verify + create: Create + approve: Approve + reject: Reject + skip: Skip + discard_draft: Discard draft + pinned: Pinned + all: All + question: Question + answer: Answer + comment: Comment + refresh: Refresh + resend: Resend + deactivate: Deactivate + active: Active + suspend: Suspend + unsuspend: Unsuspend + close: Close + reopen: Reopen + ok: OK + light: Light + dark: Dark + system_setting: System setting + default: Default + reset: Reset + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignore + submit: Submit + normal: Normal + closed: Closed + deleted: Deleted + deleted_permanently: Deleted permanently + pending: Pending + more: More + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + counts_loading: "... Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post. + modal_confirm: + title: Error... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + x_posts: "{{ count }} Posts" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + frequent: Frequent + recommend: Recommend + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + badges: Badges + newest: Newest + score: Score + edit_profile: Edit profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + comma: "," + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + content_empty: No posts found. + accepted: Accepted + answered: answered + asked: asked + downvoted: downvoted + mod_short: MOD + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + recent_badges: Recent Badges + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please choose a language + db_type: + label: Database engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database host + placeholder: "db:3306" + msg: Database host cannot be empty. + db_name: + label: Database name + placeholder: answer + msg: Database name cannot be empty. + db_file: + label: Database file + placeholder: /data/answer.db + msg: Database file cannot be empty. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site name + msg: Site name cannot be empty. + msg_max_length: Site name must be at maximum 30 characters in length. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + max_length: Site URL must be at maximum 512 characters in length. + contact_email: + label: Contact email + text: Email address of key contact responsible for this site. + msg: + empty: Contact email cannot be empty. + incorrect: Contact email incorrect format. + login_required: + label: Private + switch: Login required + text: Only logged in users can access this community. + admin_name: + label: Name + msg: Name cannot be empty. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + msg_min_length: Password must be at least 8 characters in length. + msg_max_length: Password must be at maximum 32 characters in length. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_error: + http_error: HTTP Error {{ code }} + desc_403: You don't have permission to access this page. + desc_404: Unfortunately, this page doesn't exist. + desc_50X: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + badges: Badges + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + terms: Terms + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + login: Login + privileges: Privileges + plugins: Plugins + installed_plugins: Installed Plugins + apperance: Appearance + website_welcome: Welcome to {{site_name}} + user_center: + login: Login + qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. + login_failed_email_tip: Login failed, please allow this app to access your email information before try again. + badges: + modal: + title: Congratulations + content: You've earned a new badge. + close: Close + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site statistics + questions: "Questions:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + users: "Users:" + flags: "Flags:" + reviews: "Reviews:" + site_health: Site health + version: "Version:" + https: "HTTPS:" + upload_folder: "Upload folder:" + run_mode: "Running mode:" + private: Private + public: Public + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System info + go_version: "Go version:" + database: "Database:" + database_size: "Database size:" + storage_used: "Storage used:" + uptime: "Uptime:" + links: Links + plugins: Plugins + github: GitHub + blog: Blog + contact: Contact + forum: Forum + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + writable: Writable + not_writable: Not writable + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + flagged_type: Flagged {{ type }} + created: Created + action: Action + review: Review + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + edit_profile_modal: + title: Edit profile + form: + fields: + display_name: + label: Display name + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Invalid Email Address. + edit_success: Edited successfully + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + users: + label: Bulk add user + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separate “name, email, password” with commas. One user per line. + msg: "Please enter the user's email, one per line." + display_name: + label: Display name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + more: More + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + edit_profile: Edit profile + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + deactivate_user: + title: Deactivate user + content: An inactive user must re-validate their email. + delete_user: + title: Delete this user + content: Are you sure you want to delete this user? This is permanent! + remove: Remove their content + label: Remove all questions, answers, comments, etc. + text: Don’t check this if you wish to only delete the user’s account. + suspend_user: + title: Suspend this user + content: A suspended user can't log in. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Questions + unlisted: Unlisted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + pending: Pending + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short site description + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site description + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + check_update: + label: Software updates + text: Automatically check for updates + interface: + page_title: Interface + language: + label: Interface language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: From email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + tls: TLS + none: None + smtp_port: + label: SMTP port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test email recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile logo + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square icon + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Write + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Each user can only write one answer for each question + text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Recommend tags + text: "Recommend tags will show in the dropdown list by default." + msg: + contain_reserved: "recommended tags cannot contain reserved tags" + required_tag: + title: Set required tags + label: Set “Recommend tags” as required tags + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved tags + text: "Reserved tags can only be used by moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + color_scheme: + label: Color scheme + navbar_style: + label: Navbar background style + primary_color: + label: Primary color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: > + + head: + label: Head + text: > + + header: + label: Header + text: > + + footer: + label: Footer + text: This will insert before </body>. + sidebar: + label: Sidebar + text: This will insert in sidebar. + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + email_registration: + title: Email registration + label: Allow email registration + text: Turn off to prevent anyone creating new account through email. + allowed_email_domains: + title: Allowed email domains + text: Email domains that users must register accounts with. One domain per line. Ignored when empty. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + password_login: + title: Password login + label: Allow email and password login + text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." + installed_plugins: + title: Installed Plugins + plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + filter: + all: All + active: Active + inactive: Inactive + outdated: Outdated + plugins: + label: Plugins + text: Select an existing plugin. + name: Name + version: Version + status: Status + action: Action + deactivate: Deactivate + activate: Activate + settings: Settings + settings_users: + title: Users + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + profile_editable: + title: Profile editable + allow_update_display_name: + label: Allow users to change their display name + allow_update_username: + label: Allow users to change their username + allow_update_avatar: + label: Allow users to change their profile image + allow_update_bio: + label: Allow users to change their about me + allow_update_website: + label: Allow users to change their website + allow_update_location: + label: Allow users to change their location + privilege: + title: Privileges + level: + label: Reputation required level + text: Choose the reputation required for the privileges + msg: + should_be_number: the input should be number + number_larger_1: number should be equal or larger than 1 + badges: + action: Action + active: Active + activate: Activate + all: All + awards: Awards + deactivate: Deactivate + filter: + placeholder: Filter by name, badge:id + group: Group + inactive: Inactive + name: Name + show_logs: Show logs + status: Status + title: Badges + form: + optional: (optional) + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + select: Select + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + approve_revision_tip: Do you approve this revision? + approve_flag_tip: Do you approve this flag? + approve_post_tip: Do you approve this post? + approve_user_tip: Do you approve this user? + suggest_edits: Suggested edits + flag_post: Flag post + flag_user: Flag user + queued_post: Queued post + queued_user: Queued user + filter_label: Type + reputation: reputation + flag_post_type: Flagged this post as {{ type }}. + flag_user_type: Flagged this user as {{ type }}. + edit_post: Edit post + list_post: List post + unlist_post: Unlist post + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + pin: pinned + unpin: unpinned + show: listed + hide: unlisted + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores this week + users_with_the_most_vote: Users who voted the most this week + staffs: Our community staff + reputation: reputation + votes: votes + prompt: + leave_page: Are you sure you want to leave the page? + changes_not_save: Your changes may not be saved. + draft: + discard_confirm: Are you sure you want to discard your draft? + messages: + post_deleted: This post has been deleted. + post_cancel_deleted: This post has been undeleted. + post_pin: This post has been pinned. + post_unpin: This post has been unpinned. + post_hide_list: This post has been hidden from list. + post_show_list: This post has been shown to list. + post_reopen: This post has been reopened. + post_list: This post has been listed. + post_unlist: This post has been unlisted. + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/hu_HU.yaml b/data/i18n/hu_HU.yaml new file mode 100644 index 000000000..25c086f11 --- /dev/null +++ b/data/i18n/hu_HU.yaml @@ -0,0 +1,1384 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: Success. + unknown: + other: Unknown error. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + email: + other: Email + password: + other: Password + email_or_password_wrong_error: + other: Email and password do not match. + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + question: + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + rank: + fail_to_meet_the_condition: + other: Rank fail to meet the condition. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend Tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + smtp: + config_from_name_cannot_be_email: + other: The From Name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to Revision. + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + report: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude: + name: + other: rude or abusive + desc: + other: A reasonable person would find this content inappropriate for respectful discourse. + duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + not_answer: + name: + other: not an answer + desc: + other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. + not_need: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + other: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comments + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to {{site_name}} + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to {{site_name}} + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/hy_AM.yaml b/data/i18n/hy_AM.yaml new file mode 100644 index 000000000..4249c5f03 --- /dev/null +++ b/data/i18n/hy_AM.yaml @@ -0,0 +1,1371 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: "Success." + unknown: + other: "Unknown error." + request_format_error: + other: "Request format is not valid." + unauthorized_error: + other: "Unauthorized." + database_error: + other: "Data server error." + role: + name: + user: + other: "User" + admin: + other: "Admin" + moderator: + other: "Moderator" + description: + user: + other: "Default with no special access." + admin: + other: "Have the full power to access the site." + moderator: + other: "Has access to all posts except admin settings." + email: + other: "Email" + password: + other: "Password" + email_or_password_wrong_error: + other: "Email and password do not match." + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: "Answer do not found." + cannot_deleted: + other: "No permission to delete." + cannot_update: + other: "No permission to update." + comment: + edit_without_permission: + other: "Comment are not allowed to edit." + not_found: + other: "Comment not found." + email: + duplicate: + other: "Email already exists." + need_to_be_verified: + other: "Email should be verified." + verify_url_expired: + other: "Email verified URL has expired, please resend the email." + lang: + not_found: + other: "Language file not found." + object: + captcha_verification_failed: + other: "Captcha wrong." + disallow_follow: + other: "You are not allowed to follow." + disallow_vote: + other: "You are not allowed to vote." + disallow_vote_your_self: + other: "You can't vote for your own post." + not_found: + other: "Object not found." + verification_failed: + other: "Verification failed." + email_or_password_incorrect: + other: "Email and password do not match." + old_password_verification_failed: + other: "The old password verification failed" + new_password_same_as_previous_setting: + other: "The new password is the same as the previous one." + question: + not_found: + other: "Question not found." + cannot_deleted: + other: "No permission to delete." + cannot_close: + other: "No permission to close." + cannot_update: + other: "No permission to update." + rank: + fail_to_meet_the_condition: + other: "Rank fail to meet the condition." + report: + handle_failed: + other: "Report handle failed." + not_found: + other: "Report not found." + tag: + not_found: + other: "Tag not found." + recommend_tag_not_found: + other: "Recommend Tag is not exist." + recommend_tag_enter: + other: "Please enter at least one required tag." + not_contain_synonym_tags: + other: "Should not contain synonym tags." + cannot_update: + other: "No permission to update." + cannot_set_synonym_as_itself: + other: "You cannot set the synonym of the current tag as itself." + smtp: + config_from_name_cannot_be_email: + other: "The From Name cannot be a email address." + theme: + not_found: + other: "Theme not found." + revision: + review_underway: + other: "Can't edit currently, there is a version in the review queue." + no_permission: + other: "No permission to Revision." + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: "User not found." + suspended: + other: "User has been suspended." + username_invalid: + other: "Username is invalid." + username_duplicate: + other: "Username is already in use." + set_avatar: + other: "Avatar set failed." + cannot_update_your_role: + other: "You cannot modify your role." + not_allowed_registration: + other: "Currently the site is not open for registration" + config: + read_config_failed: + other: "Read config failed" + database: + connection_failed: + other: "Database connection failed" + create_table_failed: + other: "Create table failed" + install: + create_config_failed: + other: "Can't create the config.yaml file." + report: + spam: + name: + other: "spam" + desc: + other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." + rude: + name: + other: "rude or abusive" + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + duplicate: + name: + other: "a duplicate" + desc: + other: "This question has been asked before and already has an answer." + not_answer: + name: + other: "not an answer" + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." + not_need: + name: + other: "no longer needed" + desc: + other: "This comment is outdated, conversational or not relevant to this post." + other: + name: + other: "something else" + desc: + other: "This post requires staff attention for another reason not listed above." + question: + close: + duplicate: + name: + other: "spam" + desc: + other: "This question has been asked before and already has an answer." + guideline: + name: + other: "a community-specific reason" + desc: + other: "This question doesn't meet a community guideline." + multiple: + name: + other: "needs details or clarity" + desc: + other: "This question currently includes multiple questions in one. It should focus on one problem only." + other: + name: + other: "something else" + desc: + other: "This post requires another reason not listed above." + operation_type: + asked: + other: "asked" + answered: + other: "answered" + modified: + other: "modified" + notification: + action: + update_question: + other: "updated question" + answer_the_question: + other: "answered question" + update_answer: + other: "updated answer" + accept_answer: + other: "accepted answer" + comment_question: + other: "commented question" + comment_answer: + other: "commented answer" + reply_to_you: + other: "replied to you" + mention_you: + other: "mentioned you" + your_question_is_closed: + other: "Your question has been closed" + your_question_was_deleted: + other: "Your question has been deleted" + your_answer_was_deleted: + other: "Your answer has been deleted" + your_comment_was_deleted: + other: "Your comment has been deleted" +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comment + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to Answer + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name up to 30 characters + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username up to 30 characters + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to Answer + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: "After you've done that, click “Next” button." + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: display_name must be at 2 - 30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/i18n.yaml b/data/i18n/i18n.yaml new file mode 100644 index 000000000..7abb748db --- /dev/null +++ b/data/i18n/i18n.yaml @@ -0,0 +1,64 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# all support language +language_options: + - label: "English" + value: "en_US" + progress: 100 + - label: "Español" + value: "es_ES" + progress: 96 + - label: "Português(BR)" + value: "pt_BR" + progress: 96 + - label: "Português" + value: "pt_PT" + progress: 96 + - label: "Deutsch" + value: "de_DE" + progress: 96 + - label: "Français" + value: "fr_FR" + progress: 96 + - label: "日本語" + value: "ja_JP" + progress: 96 + - label: "Italiano" + value: "it_IT" + progress: 96 + - label: "Русский" + value: "ru_RU" + progress: 80 + - label: "简体中文" + value: "zh_CN" + progress: 100 + - label: "繁體中文" + value: "zh_TW" + progress: 47 + - label: "한국어" + value: "ko_KR" + progress: 73 + - label: "Tiếng Việt" + value: "vi_VN" + progress: 96 + - label: "Slovak" + value: "sk_SK" + progress: 45 + - label: "فارسی" + value: "fa_IR" + progress: 69 diff --git a/data/i18n/id_ID.yaml b/data/i18n/id_ID.yaml new file mode 100644 index 000000000..3928c6f39 --- /dev/null +++ b/data/i18n/id_ID.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Sukses. + unknown: + other: Kesalahan tidak diketahui. + request_format_error: + other: Permintaan tidak sah. + unauthorized_error: + other: Tidak diizinkan. + database_error: + other: Kesalahan data server. + forbidden_error: + other: Forbidden. + duplicate_request_error: + other: Duplicate submission. + action: + report: + other: Flag + edit: + other: Ubah + delete: + other: Hapus + close: + other: Tutup + reopen: + other: Buka kembali + forbidden_error: + other: Forbidden. + pin: + other: Pin + hide: + other: Unlist + unpin: + other: Unpin + show: + other: Daftar + invite_someone_to_answer: + other: Undang seseorang untuk menjawab + undelete: + other: Undelete + merge: + other: Merge + role: + name: + user: + other: Pengguna + admin: + other: Administrator + moderator: + other: Moderator + description: + user: + other: Default tanpa akses khusus. + admin: + other: Memiliki kontrol penuh atas situs. + moderator: + other: Memiliki kendali atas semua kiriman kecuali pengaturan administrator. + privilege: + level_1: + description: + other: Level 1 (less reputation required for private team, group) + level_2: + description: + other: Level 2 (low reputation required for startup community) + level_3: + description: + other: Level 3 (high reputation required for mature community) + level_custom: + description: + other: Custom Level + rank_question_add_label: + other: Tanyakan sesuatu + rank_answer_add_label: + other: Tulis jawaban + rank_comment_add_label: + other: Tulis komentar + rank_report_add_label: + other: Flag + rank_comment_vote_up_label: + other: Upvote comment + rank_link_url_limit_label: + other: Kirim lebih dari 2 tautan secara bersamaan + rank_question_vote_up_label: + other: Upvote question + rank_answer_vote_up_label: + other: Upvote answer + rank_question_vote_down_label: + other: Downvote question + rank_answer_vote_down_label: + other: Downvote answer + rank_invite_someone_to_answer_label: + other: Undang seseorang untuk menjawab + rank_tag_add_label: + other: Buat tag baru + rank_tag_edit_label: + other: Edit tag description (need to review) + rank_question_edit_label: + other: Edit other's question (need to review) + rank_answer_edit_label: + other: Edit other's answer (need to review) + rank_question_edit_without_review_label: + other: Edit other's question without review + rank_answer_edit_without_review_label: + other: Edit other's answer without review + rank_question_audit_label: + other: Review question edits + rank_answer_audit_label: + other: Review answer edits + rank_tag_audit_label: + other: Review tag edits + rank_tag_edit_without_review_label: + other: Edit tag description without review + rank_tag_synonym_label: + other: Manage tag synonyms + email: + other: Email + e_mail: + other: Email + password: + other: Kata sandi + pass: + other: Password + old_pass: + other: Current password + original_text: + other: This post + email_or_password_wrong_error: + other: '"Email" dan kata sandi tidak cocok.' + error: + common: + invalid_url: + other: URL salah. + status_invalid: + other: Invalid status. + password: + space_invalid: + other: Password tidak boleh mengandung spasi. + admin: + cannot_update_their_password: + other: You cannot modify your password. + cannot_edit_their_profile: + other: You cannot modify your profile. + cannot_modify_self_status: + other: You cannot modify your status. + email_or_password_wrong: + other: Email dan kata sandi tidak cocok. + answer: + not_found: + other: Jawaban tidak ditemukan. + cannot_deleted: + other: Tidak memiliki izin untuk menghapus. + cannot_update: + other: Tidak memiliki izin untuk memperbarui. + question_closed_cannot_add: + other: Questions are closed and cannot be added. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Tidak diizinkan untuk mengubah komentar. + not_found: + other: Komentar tidak ditemukan. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: Email telah terdaftar. + need_to_be_verified: + other: Email harus terverifikasi. + verify_url_expired: + other: URL verifikasi email telah kadaluwarsa, silahkan kirim ulang. + illegal_email_domain_error: + other: Email is not allowed from that email domain. Please use another one. + lang: + not_found: + other: Bahasa tidak ditemukan. + object: + captcha_verification_failed: + other: Captcha salah. + disallow_follow: + other: Anda tidak diizinkan untuk mengikuti. + disallow_vote: + other: Anda tisak diizinkan untuk melakukan vote. + disallow_vote_your_self: + other: Anda tidak dapat melakukan voting untuk ulasan Anda sendiri. + not_found: + other: Objek tidak ditemukan. + verification_failed: + other: Verifikasi gagal. + email_or_password_incorrect: + other: Email dan kata sandi tidak cocok. + old_password_verification_failed: + other: Verifikasi password lama, gagal + new_password_same_as_previous_setting: + other: Kata sandi baru sama dengan kata sandi yang sebelumnya. + already_deleted: + other: This post has been deleted. + meta: + object_not_found: + other: Meta object not found + question: + already_deleted: + other: This post has been deleted. + under_review: + other: Your post is awaiting review. It will be visible after it has been approved. + not_found: + other: Pertanyaan tidak ditemukan. + cannot_deleted: + other: Tidak memiliki izin untuk menghapus. + cannot_close: + other: Tidak diizinkan untuk menutup. + cannot_update: + other: Tidak diizinkan untuk memperbarui. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Reputation rank fail to meet the condition. + vote_fail_to_meet_the_condition: + other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. + no_enough_rank_to_operate: + other: You need at least {{.Rank}} reputation to do this. + report: + handle_failed: + other: Laporan penanganan gagal. + not_found: + other: Laporan tidak ditemukan. + tag: + already_exist: + other: Tag already exists. + not_found: + other: Tag tidak ditemukan. + recommend_tag_not_found: + other: Recommend tag is not exist. + recommend_tag_enter: + other: Silahkan isi setidaknya satu tag yang diperlukan. + not_contain_synonym_tags: + other: Tidak boleh mengandung Tag sinonim. + cannot_update: + other: Tidak memiliki izin untuk memperbaharui. + is_used_cannot_delete: + other: You cannot delete a tag that is in use. + cannot_set_synonym_as_itself: + other: Anda tidak bisa menetapkan sinonim dari tag saat ini dengan tag yang sama. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: The from name cannot be a email address. + theme: + not_found: + other: Tema tidak ditemukan. + revision: + review_underway: + other: Tidak dapat mengedit saat ini, sedang ada review versi pada antrian. + no_permission: + other: No permission to revise. + user: + external_login_missing_user_id: + other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. + external_login_unbinding_forbidden: + other: Please set a login password for your account before you remove this login. + email_or_password_wrong: + other: + other: Email dan kata sandi tidak cocok. + not_found: + other: Pengguna tidak ditemukan. + suspended: + other: Pengguna ini telah ditangguhkan. + username_invalid: + other: Nama pengguna tidak sesuai. + username_duplicate: + other: Nama pengguna sudah digunakan. + set_avatar: + other: Set avatar gagal. + cannot_update_your_role: + other: Anda tidak dapat mengubah peran anda sendiri. + not_allowed_registration: + other: Currently the site is not open for registration. + not_allowed_login_via_password: + other: Currently the site is not allowed to login via password. + access_denied: + other: Access denied + page_access_denied: + other: You do not have access to this page. + add_bulk_users_format_error: + other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Gagal membaca konfigurasi + database: + connection_failed: + other: Koneksi ke database gagal + create_table_failed: + other: Gagal membuat tabel + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + site_info: + config_not_found: + other: Site config not found. + badge: + object_not_found: + other: Badge object not found + reason: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude_or_abusive: + name: + other: rude or abusive + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + a_duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + placeholder: + other: Enter the existing question link + not_a_answer: + name: + other: not an answer + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." + no_longer_needed: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + something: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + placeholder: + other: Let us know specifically what you are concerned about + community_specific: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + not_clarity: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + looks_ok: + name: + other: looks OK + desc: + other: This post is good as-is and not low quality. + needs_edit: + name: + other: needs edit, and I did it + desc: + other: Improve and correct problems with this post yourself. + needs_close: + name: + other: needs close + desc: + other: A closed question can't answer, but still can edit, vote and comment. + needs_delete: + name: + other: needs delete + desc: + other: This post will be deleted. + question: + close: + duplicate: + name: + other: spam + desc: + other: Pertanyaan ini telah ditanyakan sebelumnya dan sudah ada jawabannya. + guideline: + name: + other: a community-specific reason + desc: + other: Pertanyaan ini tidak sesuai dengan pedoman komunitas. + multiple: + name: + other: membutuhkan detail atau kejelasan + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: lainnya + desc: + other: Posting ini membutuhkan alasan lain yang tidak tercantum di atas. + operation_type: + asked: + other: ditanyakan + answered: + other: dijawab + modified: + other: dimodifikasi + deleted_title: + other: Deleted question + questions_title: + other: Questions + tag: + tags_title: + other: Tags + no_description: + other: The tag has no description. + notification: + action: + update_question: + other: pertanyaan yang diperbaharui + answer_the_question: + other: pertanyaan yang dijawab + update_answer: + other: jawaban yang diperbaharui + accept_answer: + other: pertanyaan yanag diterima + comment_question: + other: pertanyaan yang dikomentari + comment_answer: + other: jawaban yang dikomentari + reply_to_you: + other: membalas Anda + mention_you: + other: menyebutmu + your_question_is_closed: + other: Pertanyaanmu telah ditutup + your_question_was_deleted: + other: Pertanyaanmu telah dihapus + your_answer_was_deleted: + other: Jawabanmu telah dihapus + your_comment_was_deleted: + other: Komentarmu telah dihapus + up_voted_question: + other: upvoted question + down_voted_question: + other: downvoted question + up_voted_answer: + other: upvoted answer + down_voted_answer: + other: downvoted answer + up_voted_comment: + other: upvoted comment + invited_you_to_answer: + other: invited you to answer + earned_badge: + other: You've earned the "{{.BadgeName}}" badge + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Confirm your new email address" + body: + other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} answered your question" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_question: + title: + other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Password reset" + body: + other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + register: + title: + other: "[{{.SiteName}}] Confirm your new account" + body: + other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + test: + title: + other: "[{{.SiteName}}] Test Email" + body: + other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + action_activity_type: + upvote: + other: upvote + upvoted: + other: upvoted + downvote: + other: downvote + downvoted: + other: downvoted + accept: + other: accept + accepted: + other: accepted + edit: + other: edit + review: + queued_post: + other: Queued post + flagged_post: + other: Flagged post + suggested_post_edit: + other: Suggested edits + reaction: + tooltip: + other: "{{ .Names }} and {{ .Count }} more..." + badge: + default_badges: + autobiographer: + name: + other: Autobiographer + desc: + other: Filled out profile information. + certified: + name: + other: Certified + desc: + other: Completed our new user tutorial. + editor: + name: + other: Editor + desc: + other: First post edit. + first_flag: + name: + other: First Flag + desc: + other: First flagged a post. + first_upvote: + name: + other: First Upvote + desc: + other: First up voted a post. + first_link: + name: + other: First Link + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: First Share + desc: + other: First shared a post. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Leave 5 comments. + new_user_of_the_month: + name: + other: New User of the Month + desc: + other: Outstanding contributions in their first month. + read_guidelines: + name: + other: Read Guidelines + desc: + other: Read the [community guidelines]. + reader: + name: + other: Reader + desc: + other: Read every answers in a topic with more than 10 answers. + welcome: + name: + other: Welcome + desc: + other: Received a up vote. + nice_share: + name: + other: Nice Share + desc: + other: Shared a post with 25 unique visitors. + good_share: + name: + other: Good Share + desc: + other: Shared a post with 300 unique visitors. + great_share: + name: + other: Great Share + desc: + other: Shared a post with 1000 unique visitors. + out_of_love: + name: + other: Out of Love + desc: + other: Used 50 up votes in a day. + higher_love: + name: + other: Higher Love + desc: + other: Used 50 up votes in a day 5 times. + crazy_in_love: + name: + other: Crazy in Love + desc: + other: Used 50 up votes in a day 20 times. + promoter: + name: + other: Promoter + desc: + other: Invited a user. + campaigner: + name: + other: Campaigner + desc: + other: Invited 3 basic users. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: Thank You + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Active member for a year, posted at least once. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Cara memformat + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Sebelumnya + next: Selanjutnya + page_title: + question: Pertanyaan + questions: Pertanyaan + tag: Tag + tags: Tags + tag_wiki: tag wiki + create_tag: Create Tag + edit_tag: Ubah Tag + ask_a_question: Create Question + edit_question: Sunting Pertanyaan + edit_answer: Sunting jawaban + search: Cari + posts_containing: Postingan mengandung + settings: Pengaturan + notifications: Pemberitahuan + login: Log In + sign_up: Daftar + account_recovery: Pemulihan Akun + account_activation: Aktivasi Akun + confirm_email: Konfirmasi email + account_suspended: Akun Ditangguhkan + admin: Admin + change_email: Modifikasi email + install: Instalasi Answer + upgrade: Meng-upgrade Answer + maintenance: Pemeliharaan Website + users: Pengguna + oauth_callback: Processing + http_404: HTTP Error 404 + http_50X: HTTP Error 500 + http_403: HTTP Error 403 + logout: Log Out + posts: Posts + notifications: + title: Pemberitahuan + inbox: Kotak Masuk + achievement: Pencapaian + new_alerts: New alerts + all_read: Tandai Semua Jika Sudah Dibaca + show_more: Tampilkan lebih banyak + someone: Someone + inbox_type: + all: All + posts: Posts + invites: Invites + votes: Votes + answer: Answer + question: Question + badge_award: Badge + suspended: + title: Akun Anda telah ditangguhkan + until_time: "Akun anda ditangguhkan sampai {{ time }}." + forever: Pengguna ini ditangguhkan selamanya. + end: Anda tidak sesuai dengan syarat pedoman komunitas. + contact_us: Contact us + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Diagram alir + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Tambahkan sample code + form: + fields: + code: + label: Code + msg: + empty: Code tidak boleh kosong. + language: + label: Language + placeholder: Deteksi otomatis + btn_cancel: Batal + btn_confirm: Tambah + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal rule + image: + text: Gambar + add_image: Tambahkan gambar + tab_image: Unggah gambar + form_image: + fields: + file: + label: Image file + btn: Pilih gambar + msg: + empty: File tidak boleh kosong. + only_image: Hanya file Gambar yang diperbolehkan. + max_size: File size cannot exceed {{size}} MB. + desc: + label: Description + tab_url: URL gambar + form_url: + fields: + url: + label: URL gambar + msg: + empty: URL gambar tidak boleh kosong. + name: + label: Description + btn_cancel: Batal + btn_confirm: Tambah + uploading: Sedang mengunggah + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description + btn_cancel: Batal + btn_confirm: Tambah + ordered_list: + text: Numbered list + unordered_list: + text: Bulleted list + table: + text: Table + heading: Heading + cell: Cell + file: + text: Attach files + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: Postingan ini saya tutup sebagai... + btn_cancel: Batal + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + not_a_url: URL format is incorrect. + url_not_match: URL origin does not match the current website. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description + revision: + label: Revision + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_cancel: Cancel + btn_submit: Submit + btn_post: Post new tag + tag_info: + created_at: Dibuat + edited_at: Disunting + history: Riwayat + synonyms: + title: Sinonim + text: Tag berikut akan dipetakan ulang ke + empty: Sinonim tidak ditemukan. + btn_add: Tambahkan sinonim + btn_edit: Sunting + btn_save: Simpan + synonyms_text: Tag berikut akan dipetakan ulang ke + delete: + title: Hapus tagar ini + tip_with_posts: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + tip_with_synonyms: >- +

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        + tip: Are you sure you wish to delete? + close: Tutup + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Ubah Tag + default_reason: Sunting tag + default_first_reason: Add tag + btn_save_edits: Simpan suntingan + btn_cancel: Batal + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: sekarang + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: jam + day: hari + hours: hours + days: days + month: month + months: months + year: year + reaction: + heart: heart + smile: smile + frown: frown + btn_label: add or remove reactions + undo_emoji: undo {{ emoji }} reaction + react_emoji: react with {{ emoji }} + unreact_emoji: unreact with {{ emoji }} + comment: + btn_add_comment: Tambahkan Komentar + reply_to: Balas ke + btn_reply: Balas + btn_edit: Sunting + btn_delete: Hapus + btn_flag: Flag + btn_save_edits: Simpan suntingan + btn_cancel: Batal + show_more: "{{count}} more comments" + tip_question: >- + Gunakan komentar untuk meminta informasi lebih lanjut atau menyarankan perbaikan. Hindari menjawab pertanyaan di komentar. + tip_answer: >- + Gunakan komentar untuk membalas pengguna lain atau memberi tahu mereka tentang perubahan. Jika Anda menambahkan informasi baru, cukup edit posting Anda. + tip_vote: It adds something useful to the post + edit_answer: + title: Sunting jawaban + default_reason: Edit jawaban + default_first_reason: Add answer + form: + fields: + revision: + label: Revisi + answer: + label: Jawaban + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: Newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + wiki: Wiki + ask: + title: Create Question + edit_title: Edit Question + default_reason: Edit question + default_first_reason: Create question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: What's your topic? Be specific. + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Pengguna + badges: Badges + profile: Profil + setting: Pengaturan + logout: Keluar + admin: Admin + review: Ulasan + bookmark: Bookmarks + moderation: Moderation + search: + placeholder: Cari + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Ubah + loading: sedang memuat... + pic_auth_code: + title: Capthcha + placeholder: Masukkan teks di atas + msg: + empty: Captcha tidak boleh kosong. + inactive: + first: >- + Kamu hampir selesai! Kami telah mengirimkan email aktivasi ke {{mail}}. Silakan ikuti petunjuk dalam email untuk mengaktifkan akun Anda. + info: "Jika tidak ada email masuk, mohon periksa folder spam Anda." + another: >- + Kami telah mengirimkan email aktivasi lain kepada Anda di {{mail}}. Mungkin butuh beberapa menit untuk tiba; pastikan untuk memeriksa folder spam Anda. + btn_name: Kirim ulang email aktivasi + change_btn_name: Ganti email + msg: + empty: Tidak bisa kosong. + resend_email: + url_label: Are you sure you want to resend the activation email? + url_text: You can also give the activation link above to the user. + login: + login_to_continue: Masuk untuk melanjutkan + info_sign: Belum punya akun? <1>Daftar + info_login: Sudah punya akun? <1>Masuk + agreements: Dengan mendaftar, Anda menyetujui <1>kebijakan privasi dan <3>persyaratan layanan. + forgot_pass: Lupa password? + name: + label: Nama + msg: + empty: Nama tidak boleh kosong. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email tidak boleh kosong. + password: + label: Kata sandi + msg: + empty: Kata sandi tidak boleh kosong. + different: Kata sandi yang dimasukkan tidak sama + account_forgot: + page_title: Lupa kata sandi Anda + btn_name: Tulis email pemulihan + send_success: >- + Jika akun cocok dengan {{mail}}, Anda akan segera menerima email berisi petunjuk tentang cara menyetel ulang sandi. + email: + label: Email + msg: + empty: Email tidak boleh kosong. + change_email: + btn_cancel: Batal + btn_update: Perbarui alamat email + send_success: >- + Jika akun cocok dengan {{mail}}, Anda akan segera menerima email berisi petunjuk tentang cara menyetel ulang sandi. + email: + label: New email + msg: + empty: Email tidak boleh kosong. + oauth: + connect: Connect with {{ auth_name }} + remove: Remove {{ auth_name }} + oauth_bind_email: + subtitle: Add a recovery email to your account. + btn_update: Update email address + email: + label: Email + msg: + empty: Email cannot be empty. + modal_title: Email already existes. + modal_content: This email address already registered. Are you sure you want to connect to the existing account? + modal_cancel: Change email + modal_confirm: Connect to the existing account + password_reset: + page_title: Atur ulang kata sandi + btn_name: Atur ulang kata sandi saya + reset_success: >- + Anda berhasil mengubah kata sandi Anda; Anda akan dialihkan ke halaman login. + link_invalid: >- + Maaf, link setel ulang sandi ini sudah tidak valid. Mungkin kata sandi Anda sudah diatur ulang? + to_login: Lanjutkan ke halaman Login + password: + label: Kata sandi + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm new password + settings: + page_title: Settings + goto_modify: Go to modify + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile image + gravatar: Gravatar + gravatar_text: You can change image on + custom: Custom + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About me + website: + label: Website + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location + placeholder: "City, Country" + notification: + heading: Email Notifications + turn_on: Turn on + inbox: + label: Inbox notifications + description: Answers to your questions, comments, invites, and more. + all_new_question: + label: All new questions + description: Get notified of all new questions. Up to 50 questions per week. + all_new_question_for_following_tags: + label: All new questions for following tags + description: Get notified of new questions for following tags. + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + pass: + label: Current password + msg: Password cannot be empty. + password_title: Password + current_pass: + label: Current password + msg: + empty: Current password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New password + pass_confirm: + label: Confirm new password + interface: + heading: Interface + lang: + label: Interface language + text: Bahasa antarmuka pengguna. Itu akan berubah ketika Anda me-refresh halaman. + my_logins: + title: My logins + label: Log in or sign up on this site using these accounts. + modal_title: Remove login + modal_content: Are you sure you want to remove this login from your account? + modal_confirm_btn: Remove + remove_success: Removed successfully + toast: + update: pembaruan sukses + update_password: Kata sandi berhasil diganti. + flag_success: Terima kasih telah menandai. + forbidden_operate_self: Dilarang melakukan operasi ini pada diri sendiri + review: Revisi Anda akan ditampilkan setelah ditinjau. + sent_success: Sent successfully + related_question: + title: Related + answers: jawaban + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: People Asked + desc: Select people who you think might know the answer. + invite: Invite to answer + add: Add people + search: Search people + question_detail: + action: Action + created: Created + Asked: Ditanyakan + asked: ditanyakan + update: Diubah + Edited: Edited + edit: disunting + commented: commented + Views: Dilihat + Follow: Ikuti + Following: Mengikuti + follow_tip: Follow this question to receive notifications + answered: dijawab + closed_in: Ditutup pada + show_exist: Gunakan pertanyaan yang sudah ada. + useful: Useful + question_useful: It is useful and clear + question_un_useful: It is unclear or not useful + question_bookmark: Bookmark this question + answer_useful: It is useful + answer_un_useful: It is not useful + answers: + title: Jawaban + score: Nilai + newest: Terbaru + oldest: Oldest + btn_accept: Terima + btn_accepted: Diterima + write_answer: + title: Jawaban Anda + edit_answer: Edit my existing answer + btn_name: Kirimkan jawaban Anda + add_another_answer: Tambahkan jawaban lain + confirm_title: Lanjutkan menjawab + continue: Lanjutkan + confirm_info: >- +

        Yakin ingin menambahkan jawaban lain?

        Sebagai gantinya, Anda dapat menggunakan tautan edit untuk menyaring dan menyempurnakan jawaban anda.

        + empty: Jawaban tidak boleh kosong. + characters: content must be at least 6 characters in length. + tips: + header_1: Thanks for your answer + li1_1: Please be sure to answer the question. Provide details and share your research. + li1_2: Back up any statements you make with references or personal experience. + header_2: But avoid ... + li2_1: Asking for help, seeking clarification, or responding to other answers. + reopen: + confirm_btn: Reopen + title: Buka kembali postingan ini + content: Kamu yakin ingin membuka kembali? + list: + confirm_btn: List + title: List this post + content: Are you sure you want to list? + unlist: + confirm_btn: Unlist + title: Unlist this post + content: Are you sure you want to unlist? + pin: + title: Pin this post + content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. + confirm_btn: Pin + delete: + title: Hapus pos ini + question: >- + Kami tidak menyarankan menghapus pertanyaan dengan jawaban karena hal itu menghilangkan pengetahuan ini dari pembaca di masa mendatang.

        Penghapusan berulang atas pertanyaan yang dijawab dapat mengakibatkan akun Anda diblokir untuk bertanya. Apakah Anda yakin ingin menghapus? + answer_accepted: >- +

        Kami tidak menyarankan menghapus jawaban yang diterima karena hal itu menghilangkan pengetahuan ini dari pembaca di masa mendatang.

        Penghapusan berulang dari jawaban yang diterima dapat menyebabkan akun Anda diblokir dari menjawab. Apakah Anda yakin ingin menghapus? + other: Anda yakin ingin menghapusnya? + tip_answer_deleted: Jawaban ini telah dihapus + undelete_title: Undelete this post + undelete_desc: Are you sure you wish to undelete? + btns: + confirm: Konfirmasi + cancel: Batal + edit: Edit + save: Simpan + delete: Hapus + undelete: Undelete + list: List + unlist: Unlist + unlisted: Unlisted + login: Masuk + signup: Daftar + logout: Keluar + verify: Verifikasi + create: Create + approve: Approve + reject: Reject + skip: Skip + discard_draft: Discard draft + pinned: Pinned + all: All + question: Question + answer: Answer + comment: Comment + refresh: Refresh + resend: Resend + deactivate: Deactivate + active: Active + suspend: Suspend + unsuspend: Unsuspend + close: Close + reopen: Reopen + ok: OK + light: Light + dark: Dark + system_setting: System setting + default: Default + reset: Reset + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignore + submit: Submit + normal: Normal + closed: Closed + deleted: Deleted + deleted_permanently: Deleted permanently + pending: Pending + more: More + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + counts_loading: "... Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post. + modal_confirm: + title: Error... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + x_posts: "{{ count }} Posts" + questions: Questions + answers: Jawaban + newest: Terbaru + active: Aktif + hot: Hot + frequent: Frequent + recommend: Recommend + score: Nilai + unanswered: Belum dijawab + modified: diubah + answered: dijawab + asked: ditanyakan + closed: ditutup + follow_a_tag: Ikuti tagar + more: Lebih + personal: + overview: Ringkasan + answers: Jawaban + answer: jawaban + questions: Pertanyaan + question: pertanyaan + bookmarks: Bookmarks + reputation: Reputasi + comments: Komentar + votes: Vote + badges: Badges + newest: Terbaru + score: Nilai + edit_profile: Edit profile + visited_x_days: "Dikunjungi {{ count }} hari" + viewed: Dilihat + joined: Bergabung + comma: "," + last_login: Dilihat + about_me: Tentang Saya + about_me_empty: "// Hello, World !" + top_answers: Jawaban terpopuler + top_questions: Pertanyaan terpopuler + stats: Statistik + list_empty: Postingan tidak ditemukan.
        Mungkin Anda ingin memilih tab lain? + content_empty: No posts found. + accepted: Diterima + answered: dijawab + asked: ditanyakan + downvoted: downvoted + mod_short: MOD + mod_long: Moderator + x_reputation: reputasi + x_votes: vote diterima + x_answers: jawaban + x_questions: pertanyaan + recent_badges: Recent Badges + install: + title: Installation + next: Selanjutnya + done: Selesai + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please choose a language + db_type: + label: Database engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database host + placeholder: "db:3306" + msg: Database host cannot be empty. + db_name: + label: Database name + placeholder: answer + msg: Database name cannot be empty. + db_file: + label: Database file + placeholder: /data/answer.db + msg: Database file cannot be empty. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site name + msg: Site name cannot be empty. + msg_max_length: Site name must be at maximum 30 characters in length. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + max_length: Site URL must be at maximum 512 characters in length. + contact_email: + label: Contact email + text: Email address of key contact responsible for this site. + msg: + empty: Contact email cannot be empty. + incorrect: Contact email incorrect format. + login_required: + label: Private + switch: Login required + text: Only logged in users can access this community. + admin_name: + label: Name + msg: Name cannot be empty. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + msg_min_length: Password must be at least 8 characters in length. + msg_max_length: Password must be at maximum 32 characters in length. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Koneksi ke database gagal + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_error: + http_error: HTTP Error {{ code }} + desc_403: You don't have permission to access this page. + desc_404: Unfortunately, this page doesn't exist. + desc_50X: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dasbor + contents: Konten + questions: Pertanyaan + answers: Jawaban + users: Pengguna + badges: Badges + flags: Flags + settings: Pengaturan + general: Umum + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + terms: Terms + tos: Terms of Service + privacy: Privasi + seo: SEO + customize: Kostumisasi + themes: Tema + login: Masuk + privileges: Privileges + plugins: Plugins + installed_plugins: Installed Plugins + apperance: Appearance + website_welcome: Welcome to {{site_name}} + user_center: + login: Login + qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. + login_failed_email_tip: Login failed, please allow this app to access your email information before try again. + badges: + modal: + title: Congratulations + content: You've earned a new badge. + close: Close + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + admin: + admin_header: + title: Admin + dashboard: + title: Dasbor + welcome: Welcome to Admin! + site_statistics: Site statistics + questions: "Pertanyaan:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "Jawaban:" + comments: "Komentar:" + votes: "Vote:" + users: "Users:" + flags: "Flags:" + reviews: "Reviews:" + site_health: Site health + version: "Versi:" + https: "HTTPS:" + upload_folder: "Upload folder:" + run_mode: "Running mode:" + private: Private + public: Public + smtp: "SMTP:" + timezone: "Zona Waktu:" + system_info: System info + go_version: "Go version:" + database: "Database:" + database_size: "Database size:" + storage_used: "Penyimpanan yang terpakai:" + uptime: "Uptime:" + links: Links + plugins: Plugins + github: GitHub + blog: Blog + contact: Contact + forum: Forum + documents: Dokumen + feedback: Masukan + support: Dukungan + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + writable: Writable + not_writable: Not writable + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + flagged_type: Flagged {{ type }} + created: Created + action: Action + review: Review + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + edit_profile_modal: + title: Edit profile + form: + fields: + display_name: + label: Display name + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Invalid Email Address. + edit_success: Edited successfully + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + users: + label: Bulk add user + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separate “name, email, password” with commas. One user per line. + msg: "Please enter the user's email, one per line." + display_name: + label: Display name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Status + role: Role + action: Action + change: Ubah + all: Semua + staff: Staf + more: More + inactive: Tidak Aktif + suspended: Ditangguhkan + deleted: Dihapus + normal: Normal + Moderator: Moderator + Admin: Admin + User: Pengguna + filter: + placeholder: "Filter berdasarkan nama, user:id" + set_new_password: Atur password baru + edit_profile: Edit profile + change_status: Ubah status + change_role: Ubah role + show_logs: Tampilkan log + add_user: Tambahkan pengguna + deactivate_user: + title: Deactivate user + content: An inactive user must re-validate their email. + delete_user: + title: Delete this user + content: Are you sure you want to delete this user? This is permanent! + remove: Remove their content + label: Remove all questions, answers, comments, etc. + text: Don’t check this if you wish to only delete the user’s account. + suspend_user: + title: Suspend this user + content: A suspended user can't log in. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Pertanyaan + unlisted: Unlisted + post: Post + votes: Vote + answers: Jawaban + created: Dibuat + status: Status + action: Action + change: Ubah + pending: Pending + filter: + placeholder: "Filter berdasarkan judul, question:id" + answers: + page_title: Jawaban + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short site description + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site description + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + check_update: + label: Software updates + text: Automatically check for updates + interface: + page_title: Interface + language: + label: Interface language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: From email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Enkripsi + msg: Enkripsi tidak boleh kosong. + text: For most servers SSL is the recommended option. + ssl: SSL + tls: TLS + none: Tidak ada + smtp_port: + label: SMTP port + msg: SMTP port must be number 1 ~ 65535. + text: Port untuk server email Anda. + smtp_username: + label: SMTP username + msg: Nama Pengguna SMTP tidak boleh kosong. + smtp_password: + label: SMTP password + msg: Password SMTP tidak boleh kosong. + test_email_recipient: + label: Test email recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile logo + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square icon + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Write + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Each user can only write one answer for each question + text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Recommend tags + text: "Recommend tags will show in the dropdown list by default." + msg: + contain_reserved: "recommended tags cannot contain reserved tags" + required_tag: + title: Set required tags + label: Set “Recommend tags” as required tags + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved tags + text: "Reserved tags can only be used by moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + color_scheme: + label: Color scheme + navbar_style: + label: Navbar background style + primary_color: + label: Primary color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: > + + head: + label: Head + text: > + + header: + label: Header + text: > + + footer: + label: Footer + text: This will insert before </body>. + sidebar: + label: Sidebar + text: This will insert in sidebar. + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + email_registration: + title: Email registration + label: Allow email registration + text: Turn off to prevent anyone creating new account through email. + allowed_email_domains: + title: Allowed email domains + text: Email domains that users must register accounts with. One domain per line. Ignored when empty. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + password_login: + title: Password login + label: Allow email and password login + text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." + installed_plugins: + title: Installed Plugins + plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + filter: + all: All + active: Active + inactive: Inactive + outdated: Outdated + plugins: + label: Plugins + text: Select an existing plugin. + name: Name + version: Version + status: Status + action: Action + deactivate: Deactivate + activate: Activate + settings: Settings + settings_users: + title: Users + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar Base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + profile_editable: + title: Profile editable + allow_update_display_name: + label: Allow users to change their display name + allow_update_username: + label: Allow users to change their username + allow_update_avatar: + label: Allow users to change their profile image + allow_update_bio: + label: Allow users to change their about me + allow_update_website: + label: Allow users to change their website + allow_update_location: + label: Allow users to change their location + privilege: + title: Privileges + level: + label: Reputation required level + text: Choose the reputation required for the privileges + msg: + should_be_number: the input should be number + number_larger_1: number should be equal or larger than 1 + badges: + action: Action + active: Active + activate: Activate + all: All + awards: Awards + deactivate: Deactivate + filter: + placeholder: Filter by name, badge:id + group: Group + inactive: Inactive + name: Name + show_logs: Show logs + status: Status + title: Badges + form: + optional: (optional) + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + select: Select + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + approve_revision_tip: Do you approve this revision? + approve_flag_tip: Do you approve this flag? + approve_post_tip: Do you approve this post? + approve_user_tip: Do you approve this user? + suggest_edits: Suggested edits + flag_post: Flag post + flag_user: Flag user + queued_post: Queued post + queued_user: Queued user + filter_label: Type + reputation: reputation + flag_post_type: Flagged this post as {{ type }}. + flag_user_type: Flagged this user as {{ type }}. + edit_post: Edit post + list_post: List post + unlist_post: Unlist post + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + pin: pinned + unpin: unpinned + show: listed + hide: unlisted + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores this week + users_with_the_most_vote: Users who voted the most this week + staffs: Our community staff + reputation: reputation + votes: votes + prompt: + leave_page: Are you sure you want to leave the page? + changes_not_save: Your changes may not be saved. + draft: + discard_confirm: Are you sure you want to discard your draft? + messages: + post_deleted: This post has been deleted. + post_cancel_deleted: This post has been undeleted. + post_pin: This post has been pinned. + post_unpin: This post has been unpinned. + post_hide_list: This post has been hidden from list. + post_show_list: This post has been shown to list. + post_reopen: This post has been reopened. + post_list: This post has been listed. + post_unlist: This post has been unlisted. + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/it_IT.yaml b/data/i18n/it_IT.yaml new file mode 100644 index 000000000..ddc9723c6 --- /dev/null +++ b/data/i18n/it_IT.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Successo. + unknown: + other: Errore sconosciuto. + request_format_error: + other: Il formato della richiesta non è valido. + unauthorized_error: + other: Non autorizzato. + database_error: + other: Errore nel server dati. + forbidden_error: + other: Vietato. + duplicate_request_error: + other: Duplica invio. + action: + report: + other: Segnala + edit: + other: Modifica + delete: + other: Cancella + close: + other: Chiudi + reopen: + other: Riapri + forbidden_error: + other: Vietato. + pin: + other: Fissa sul profilo + hide: + other: Rimuovi dall'elenco + unpin: + other: Stacca dal profilo + show: + other: Aggiungi all'elenco + invite_someone_to_answer: + other: Modifica + undelete: + other: Ripristina + merge: + other: Unisci + role: + name: + user: + other: Utente + admin: + other: Amministratore + moderator: + other: Moderatore + description: + user: + other: Predefinito senza alcun accesso speciale. + admin: + other: Avere il pieno potere di accedere al sito. + moderator: + other: Ha accesso a tutti i post tranne le impostazioni di amministratore. + privilege: + level_1: + description: + other: 'Livello 1 (per team o gruppi privati: richiesta reputazione limitata)' + level_2: + description: + other: 'Livello 2 (per startup community: richiesta reputazione scarsa)' + level_3: + description: + other: 'Livello 3 (per community riconosciute: richiesta reputazione alta)' + level_custom: + description: + other: Livello personalizzato + rank_question_add_label: + other: Fai una domanda + rank_answer_add_label: + other: Scrivi una risposta + rank_comment_add_label: + other: Scrivi un commento + rank_report_add_label: + other: Segnala + rank_comment_vote_up_label: + other: Approva commento + rank_link_url_limit_label: + other: Pubblica più di 2 link alla volta + rank_question_vote_up_label: + other: Approva domanda + rank_answer_vote_up_label: + other: Approva risposta + rank_question_vote_down_label: + other: Disapprova domanda + rank_answer_vote_down_label: + other: Disapprova risposta + rank_invite_someone_to_answer_label: + other: Invita qualcuno a rispondere + rank_tag_add_label: + other: Crea un nuovo tag + rank_tag_edit_label: + other: Modifica descrizione tag (necessità di revisione) + rank_question_edit_label: + other: Modifica la domanda di altri (necessità di revisione) + rank_answer_edit_label: + other: Modifica la risposta di altri (necessità di revisione) + rank_question_edit_without_review_label: + other: Modifica la domanda di altri senza bisogno di revisione + rank_answer_edit_without_review_label: + other: Modifica la risposta di altri senza bisogno di revisione + rank_question_audit_label: + other: Rivedi modifiche alla domanda + rank_answer_audit_label: + other: Rivedi modifiche alla risposta + rank_tag_audit_label: + other: Esamina le modifiche ai tag + rank_tag_edit_without_review_label: + other: Modifica la descrizione del tag senza necessità di revisione + rank_tag_synonym_label: + other: Gestisci sinonimi dei tag + email: + other: E-mail + e_mail: + other: E-mail + password: + other: Chiave di accesso + pass: + other: Password + old_pass: + other: Password attuale + original_text: + other: Questo post + email_or_password_wrong_error: + other: Email o password errati. + error: + common: + invalid_url: + other: URL non valido. + status_invalid: + other: Status non valido. + password: + space_invalid: + other: La password non può contenere spazi. + admin: + cannot_update_their_password: + other: Non è possibile modificare la password. + cannot_edit_their_profile: + other: Non è possibile modificare il profilo. + cannot_modify_self_status: + other: Non è possibile modificare il tuo status. + email_or_password_wrong: + other: Email o password errati. + answer: + not_found: + other: Risposta non trovata. + cannot_deleted: + other: Permesso per cancellare mancante. + cannot_update: + other: Nessun permesso per l'aggiornamento. + question_closed_cannot_add: + other: Le domande sono chiuse e non possono essere aggiunte. + content_cannot_empty: + other: Il contenuto della risposta non può essere vuoto. + comment: + edit_without_permission: + other: Non si hanno di privilegi sufficienti per modificare il commento. + not_found: + other: Commento non trovato. + cannot_edit_after_deadline: + other: Il tempo per editare è scaduto. + content_cannot_empty: + other: Il commento non può essere vuoto. + email: + duplicate: + other: Email già esistente. + need_to_be_verified: + other: L'email deve essere verificata. + verify_url_expired: + other: L'url di verifica email è scaduto, si prega di reinviare l'email. + illegal_email_domain_error: + other: L'email non è consentita da quel dominio di posta elettronica. Si prega di usarne un altro. + lang: + not_found: + other: File lingua non trovato. + object: + captcha_verification_failed: + other: Captcha errato. + disallow_follow: + other: Non sei autorizzato a seguire + disallow_vote: + other: non sei autorizzato a votare + disallow_vote_your_self: + other: Non puoi votare un tuo post! + not_found: + other: oggetto non trovato + verification_failed: + other: verifica fallita + email_or_password_incorrect: + other: email o password incorretti + old_password_verification_failed: + other: la verifica della vecchia password è fallita + new_password_same_as_previous_setting: + other: La nuova password è identica alla precedente + already_deleted: + other: Questo post è stato eliminato. + meta: + object_not_found: + other: Meta oggetto non trovato + question: + already_deleted: + other: Questo post è stato eliminato. + under_review: + other: Il tuo post è in attesa di revisione. Sarà visibile dopo essere stato approvato. + not_found: + other: domanda non trovata + cannot_deleted: + other: Permesso per cancellare mancante. + cannot_close: + other: Nessun permesso per chiudere. + cannot_update: + other: Nessun permesso per l'aggiornamento. + content_cannot_empty: + other: Il contenuto non può essere vuoto. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Il rango di reputazione non soddisfa le condizioni. + vote_fail_to_meet_the_condition: + other: Grazie per il feedback. Hai bisogno di almeno una reputazione {{.Rank}} per votare. + no_enough_rank_to_operate: + other: Hai bisogno di almeno una reputazione {{.Rank}} per fare questo. + report: + handle_failed: + other: Gestione del report fallita + not_found: + other: Report non trovato + tag: + already_exist: + other: Tag già esistente. + not_found: + other: Etichetta non trovata + recommend_tag_not_found: + other: Il tag consigliato non esiste. + recommend_tag_enter: + other: Inserisci almeno un tag. + not_contain_synonym_tags: + other: Non deve contenere tag sinonimi. + cannot_update: + other: Nessun permesso per l'aggiornamento. + is_used_cannot_delete: + other: Non è possibile eliminare un tag in uso. + cannot_set_synonym_as_itself: + other: Non puoi impostare il sinonimo del tag corrente come se stesso. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: Il mittente non può essere un indirizzo email. + theme: + not_found: + other: tema non trovato + revision: + review_underway: + other: Non è possibile modificare al momento, c'è una versione nella coda di revisione. + no_permission: + other: Non è permessa la revisione. + user: + external_login_missing_user_id: + other: La piattaforma di terze parti non fornisce un utente ID unico, quindi non è possibile effettuare il login. Si prega di contattare l'amministratore del sito web. + external_login_unbinding_forbidden: + other: Per favore imposta una password di login per il tuo account prima di rimuovere questo accesso. + email_or_password_wrong: + other: + other: Email o password errati + not_found: + other: utente non trovato + suspended: + other: utente sospeso + username_invalid: + other: utente non valido + username_duplicate: + other: Nome utente già in uso + set_avatar: + other: Inserimento dell'Avatar non riuscito. + cannot_update_your_role: + other: Non puoi modificare il tuo ruolo. + not_allowed_registration: + other: Attualmente il sito non è aperto per la registrazione. + not_allowed_login_via_password: + other: Attualmente non è consentito accedere al sito tramite password. + access_denied: + other: Accesso negato + page_access_denied: + other: Non hai accesso a questa pagina. + add_bulk_users_format_error: + other: "Errore {{.Field}} formato vicino a '{{.Content}}' alla riga {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "Il numero di utenti che aggiungi contemporaneamente dovrebbe essere compreso tra 1 e {{.MaxAmount}}." + status_suspended_forever: + other: "Questo utente è stato sospeso per sempre. Questo utente non soddisfa le linee guida della comunità." + status_suspended_until: + other: "Questo utente è stato sospeso fino a {{.SuspendedUntil}}. Questo utente non soddisfa le linee guida della comunità." + status_deleted: + other: "Utente eliminato." + status_inactive: + other: "L'utente è inattivo." + config: + read_config_failed: + other: Configurazione lettura fallita + database: + connection_failed: + other: Connessione al database fallita + create_table_failed: + other: Creazione tabella non riuscita + install: + create_config_failed: + other: Impossibile creare il file config.yaml. + upload: + unsupported_file_format: + other: Formato file non supportato. + site_info: + config_not_found: + other: Configurazione del sito non trovata. + badge: + object_not_found: + other: Oggetto badge non trovato + reason: + spam: + name: + other: Spam + desc: + other: "Questo post è una pubblicità o spam. Non è utile o rilevante per l'argomento attuale.\n" + rude_or_abusive: + name: + other: scortese o offensivo + desc: + other: "Una persona ragionevole troverebbe questo contenuto inappropriato per un discorso rispettoso." + a_duplicate: + name: + other: duplicato + desc: + other: Questa domanda è già stata posta e ha già una risposta. + placeholder: + other: Inserisci il link alla domanda esistente + not_a_answer: + name: + other: Non è una risposta + desc: + other: "Questo è stato pubblicato come una risposta, ma non tenta di rispondere alla domanda. Dovrebbe forse essere una modifica, un commento, un'altra domanda,o cancellato del tutto." + no_longer_needed: + name: + other: Non più necessario + desc: + other: Questo commento è obsoleto, informale o non rilevante per questo post. + something: + name: + other: Qualcos'altro + desc: + other: Questo post richiede l'attenzione dello staff per un altro motivo non elencato sopra. + placeholder: + other: Facci sapere nello specifico cosa ti preoccupa + community_specific: + name: + other: Un motivo legato alla community + desc: + other: Questa domanda non soddisfa le linee guida della community. + not_clarity: + name: + other: Richiede maggiori dettagli o chiarezza + desc: + other: Questa domanda include più domande in una. Dovrebbe concentrarsi su un unico problema. + looks_ok: + name: + other: sembra OK + desc: + other: Questo post è corretto così com'è e non è di bassa qualità. + needs_edit: + name: + other: Necessita di modifiche che ho effettuato + desc: + other: Migliora e correggi tu stesso i problemi di questo post. + needs_close: + name: + other: necessita di chiusura + desc: + other: A una domanda chiusa non è possibile rispondere, ma è comunque possibile modificare, votare e commentare. + needs_delete: + name: + other: Necessario eliminare + desc: + other: Questo post verrà eliminato. + question: + close: + duplicate: + name: + other: posta indesiderata + desc: + other: Questa domanda è già stata posta e ha già una risposta. + guideline: + name: + other: motivo legato alla community + desc: + other: Questa domanda non soddisfa le linee guida della comunità. + multiple: + name: + other: richiede maggiori dettagli o chiarezza + desc: + other: Questa domanda attualmente include più domande in uno. Dovrebbe concentrarsi su un solo problema. + other: + name: + other: altro + desc: + other: Questo articolo richiede un'altro motivo non listato sopra. + operation_type: + asked: + other: chiesto + answered: + other: Risposto + modified: + other: Modificato + deleted_title: + other: "\nDomanda cancellata" + questions_title: + other: Domande + tag: + tags_title: + other: Tags + no_description: + other: Il tag non ha descrizioni. + notification: + action: + update_question: + other: domanda aggiornata + answer_the_question: + other: domanda risposta + update_answer: + other: risposta aggiornata + accept_answer: + other: risposta accettata + comment_question: + other: domanda commentata + comment_answer: + other: risposta commentata + reply_to_you: + other: hai ricevuto risposta + mention_you: + other: sei stato menzionato + your_question_is_closed: + other: la tua domanda è stata chiusa + your_question_was_deleted: + other: la tua domanda è stata rimossa + your_answer_was_deleted: + other: la tua risposta è stata rimossa + your_comment_was_deleted: + other: il tuo commento è stato rimosso + up_voted_question: + other: domanda approvata + down_voted_question: + other: domanda scartata + up_voted_answer: + other: risposta approvata + down_voted_answer: + other: risposta sfavorevole + up_voted_comment: + other: commento approvato + invited_you_to_answer: + other: sei invitato a rispondere + earned_badge: + other: Hai ottenuto il badge "{{.BadgeName}}" + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Conferma il tuo nuovo indirizzo email" + body: + other: "Conferma il tuo nuovo indirizzo email per {{.SiteName}} cliccando sul seguente link:
        \n{{.ChangeEmailUrl}}

        \n\nSe non hai richiesto questa modifica, ignora questa email.

        \n\n--
        \nNota: Si tratta di un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} ha risposto alla tua domanda" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nVisualizza su {{.SiteName}}

        \n\n--
        \nNota: Si tratta di un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata.

        \n\nCancellazione" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} ti ha invitato a rispondere" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Penso che tu possa sapere la risposta.

        \nVisualizza su {{.SiteName}}

        \n\n--
        \nNota: Questa è un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata.

        \n\nCancellazione" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} ha commentato il tuo post" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nVisualizza su {{.SiteName}}

        \n\n--
        \nNota: Si tratta di un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata.

        \n\nCancellazione" + new_question: + title: + other: "[{{.SiteName}}] Nuova domanda: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNota: Si tratta di un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non sarà visualizzata.

        \n\nCancellati" + pass_reset: + title: + other: "[{{.SiteName }}] Reimpostazione della password" + body: + other: "Qualcuno ha chiesto di reimpostare la tua password su {{.SiteName}}.

        \n\nSe non sei tu, puoi tranquillamente ignorare questa email.

        \n\nClicca sul seguente link per scegliere una nuova password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNota: Si tratta di un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata." + register: + title: + other: "[{{.SiteName}}] Conferma il tuo nuovo account" + body: + other: "Benvenuto in {{.SiteName}}!

        \n\nClicca il seguente link per confermare e attivare il tuo nuovo account:
        \n{{.RegisterUrl}}

        \n\nSe il link di cui sopra non è cliccabile, prova a copiarlo e incollarlo nella barra degli indirizzi del tuo browser web.\n

        \n\n--
        \nNota: Si tratta di un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata." + test: + title: + other: "[{{.SiteName}}] Email di prova" + body: + other: "Questa è una email di prova.\n

        \n\n--
        \nNota: Questa è un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata." + action_activity_type: + upvote: + other: voto a favore + upvoted: + other: voto a favore + downvote: + other: voto negativo + downvoted: + other: votato negativamente + accept: + other: Accetta + accepted: + other: Accettato + edit: + other: modifica + review: + queued_post: + other: Post in coda + flagged_post: + other: Post contrassegnato + suggested_post_edit: + other: Modifiche suggerite + reaction: + tooltip: + other: "{{ .Names }} e {{ .Count }} più..." + badge: + default_badges: + autobiographer: + name: + other: Autobiografo + desc: + other: Informazioni sul profilo completate. + certified: + name: + other: Certificato + desc: + other: "\nCompletato il nostro nuovo tutorial per l'utente." + editor: + name: + other: Editor + desc: + other: Prima modifica al post. + first_flag: + name: + other: Primo Contrassegno + desc: + other: Primo contrassegno di un post. + first_upvote: + name: + other: Primo Mi Piace + desc: + other: Primo Mi Piace a un post + first_link: + name: + other: Primo Link + desc: + other: Per prima cosa è stato aggiunto un link ad un altro post. + first_reaction: + name: + other: Prima Reazione + desc: + other: Prima reazione al post. + first_share: + name: + other: Prima Condivisione + desc: + other: Prima condivisione a un post. + scholar: + name: + other: Studioso + desc: + other: Ha posto una domanda e ha accettato una risposta + commentator: + name: + other: Commentatore + desc: + other: Lascia 5 commenti. + new_user_of_the_month: + name: + other: Nuovo Utente del Mese + desc: + other: Contributi straordinari nel primo mese. + read_guidelines: + name: + other: Leggi le Linee Guida + desc: + other: Leggi le [linee guida della community]. + reader: + name: + other: Lettore + desc: + other: Leggi ogni risposta in un argomento con più di 10 risposte. + welcome: + name: + other: Benvenuto + desc: + other: Ricevuto un voto positivo. + nice_share: + name: + other: Condivisione positiva. + desc: + other: Ha condiviso un post con 25 visitatori unici. + good_share: + name: + other: Condivisione positiva. + desc: + other: Condiviso un post con 300 visitatori unici. + great_share: + name: + other: Grande Condivisione + desc: + other: Condiviso un post con 1000 visitatori unici. + out_of_love: + name: + other: Fuori Amore + desc: + other: Usato 50 voti in su in un giorno. + higher_love: + name: + other: Amore Superiore + desc: + other: Usato 50 voti in su in un giorno 5 volte. + crazy_in_love: + name: + other: Pazzo innamorato + desc: + other: Utilizzato 50 voti in su in un giorno 20 volte. + promoter: + name: + other: Promotore + desc: + other: Invitato un utente. + campaigner: + name: + other: Campagnia + desc: + other: Invitato a 3 utenti di base. + champion: + name: + other: Campione + desc: + other: Invitati 5 membri. + thank_you: + name: + other: Grazie + desc: + other: Il post ha ricevuto 20 voti positivi e 10 voti positivi. + gives_back: + name: + other: Feedback + desc: + other: Post con 100 voti positivi e 100 voti positivi espressi. + empathetic: + name: + other: Empatico + desc: + other: Ha 500 posti votati e ha rinunciato a 1000 voti. + enthusiast: + name: + other: Entusiasta + desc: + other: Visitato 10 giorni consecutivi. + aficionado: + name: + other: Aficionado + desc: + other: Visitato 100 giorni consecutivi. + devotee: + name: + other: Devotee + desc: + other: Visitato 365 giorni consecutivi. + anniversary: + name: + other: Anniversario + desc: + other: Membro attivo per un anno, pubblicato almeno una volta. + appreciated: + name: + other: Apprezzato + desc: + other: Ricevuto 1 voto su 20 posti. + respected: + name: + other: Rispettati + desc: + other: Ricevuto 2 voto su 100 posti. + admired: + name: + other: Ammirato + desc: + other: Ricevuto 5 voto su 300 posti. + solved: + name: + other: Risolto + desc: + other: Avere una risposta accettata. + guidance_counsellor: + name: + other: Consulente Di Orientamento + desc: + other: Si accettano 10 risposte. + know_it_all: + name: + other: Sa tutto + desc: + other: Si accettano 50 risposte. + solution_institution: + name: + other: Istituzione Di Soluzione + desc: + other: Si accettano 150 risposte. + nice_answer: + name: + other: Bella risposta + desc: + other: Punteggio domande pari o superiore a 10. + good_answer: + name: + other: Buona risposta + desc: + other: Punteggio domande pari o superiore a 25. + great_answer: + name: + other: Risposta molto buona + desc: + other: Punteggio domande pari o superiore a 50. + nice_question: + name: + other: Bella domanda + desc: + other: Punteggio domande pari o superiore a 10. + good_question: + name: + other: Buona domanda + desc: + other: Punteggio della domanda di 25 o più + great_question: + name: + other: Ottima domanda + desc: + other: Punteggio domande pari o superiore a 50. + popular_question: + name: + other: Domanda popolare + desc: + other: "Domanda con 500 visualizzazioni\n" + notable_question: + name: + other: Domanda notevole + desc: + other: Domanda con 1.000 visualizzazioni. + famous_question: + name: + other: Domanda celebre + desc: + other: "Domanda con 5.000 visualizzazioni.\n." + popular_link: + name: + other: Link Popolare + desc: + other: Pubblicato un link esterno con 50 clic. + hot_link: + name: + other: Link popolare + desc: + other: Pubblicato un link esterno con 300 clic. + famous_link: + name: + other: Link celebre + desc: + other: Pubblicato un link esterno con 100 clic. + default_badge_groups: + getting_started: + name: + other: Primi passi + community: + name: + other: Community + posting: + name: + other: Pubblicazione in corso +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Come formattare + desc: >- +
        • menzionare un post: #post_id

        • per creare collegamenti

          <https://url.com>

          [Titolo](https://url.com)
        • mettere ritorni a capo tra i paragrafi

        • corsivo o **grassetto**

        • indentare il codice con 4 spazi

        • citare iniziando la riga con >

        • utilizzare il backtick per scapeggiare il codice `come _questo_`

        • creare recinti di codice con backticks `

          ```
          codice qui
          ```
        + pagination: + prev: Prec + next: Successivo + page_title: + question: Domanda + questions: Domande + tag: Tag + tags: Tags + tag_wiki: tag wiki + create_tag: Crea tag + edit_tag: Modifica Tag + ask_a_question: Crea domanda + edit_question: Modifica Domanda + edit_answer: Modifica risposta + search: Cerca + posts_containing: Post contenenti + settings: Impostazioni + notifications: Notifiche + login: Accedi + sign_up: Registrati + account_recovery: Recupero dell'account + account_activation: Attivazione account + confirm_email: Conferma Email + account_suspended: Account sospeso + admin: Amministratore + change_email: Modifica la tua email + install: Installazione di Answer + upgrade: Upgrade di Answer + maintenance: Manutenzione del sito + users: Utenti + oauth_callback: Elaborazione in corso + http_404: Errore HTTP 404 + http_50X: Errore HTTP 500 + http_403: Errore HTTP 403 + logout: Disconnetti + posts: Posts + notifications: + title: Notifiche + inbox: Posta in arrivo + achievement: Risultati + new_alerts: Nuovi avvisi + all_read: Segna tutto come letto + show_more: Mostra di più + someone: Qualcuno + inbox_type: + all: Tutti + posts: Messaggi + invites: Inviti + votes: Voti + answer: Risposta + question: Domanda + badge_award: Distintivo + suspended: + title: Il tuo account è stato sospeso + until_time: "Il tuo account è stato sospeso fino a {{ time }}." + forever: Questo utente è stato sospeso per sempre. + end: Non soddisfi le linee guida della community. + contact_us: Contattaci + editor: + blockquote: + text: Citazione + bold: + text: Forte + chart: + text: Grafico + flow_chart: Diagramma di flusso + sequence_diagram: Diagramma di sequenza + class_diagram: Diagramma di classe + state_diagram: Diagramma di stato + entity_relationship_diagram: Diagramma Entità-Relazione + user_defined_diagram: "\nDiagramma definito dall'utente" + gantt_chart: Diagramma di Gantt + pie_chart: Grafico a torta + code: + text: Esempio di codice + add_code: Aggiungi un esempio di codice + form: + fields: + code: + label: Codice + msg: + empty: Il codice non può essere vuoto + language: + label: Lingua + placeholder: Rilevamento automatico + btn_cancel: Cancella + btn_confirm: Aggiungi + formula: + text: Formula + options: + inline: Formula nella linea + block: "\nFormula di blocco" + heading: + text: Intestazione + options: + h1: Intestazione 1 + h2: Intestazione 2 + h3: Intestazione 3 + h4: Intestazione 4 + h5: Intestazione 5 + h6: Intestazione 6 + help: + text: Aiuto + hr: + text: Riga orizzontale + image: + text: Immagine + add_image: Aggiungi immagine + tab_image: Carica immagine + form_image: + fields: + file: + label: File d'immagine + btn: Scegli immagine + msg: + empty: Il file non può essere vuoto. + only_image: Sono ammesse solo le immagini + max_size: La dimensione del file non può superare {{size}} MB. + desc: + label: Descrizione + tab_url: Url dell'Immagine + form_url: + fields: + url: + label: URL dell'immagine + msg: + empty: L'URL dell'immagine non può essere vuoto. + name: + label: Descrizione + btn_cancel: Cancella + btn_confirm: Aggiungi + uploading: Caricamento in corso... + indent: + text: Indenta + outdent: + text: Deindenta + italic: + text: Corsivo + link: + text: Collegamento ipertestuale + add_link: Aggiungi collegamento + form: + fields: + url: + label: URL + msg: + empty: L'URL non può essere vuoto + name: + label: Descrizione + btn_cancel: Cancella + btn_confirm: Aggiungi + ordered_list: + text: Elenco numerato + unordered_list: + text: Elenco puntato + table: + text: Tabella + heading: Intestazione + cell: Cella + file: + text: Allega file + not_supported: "Non supportare quel tipo di file. Riprovare con {{file_type}}." + max_size: "Allega la dimensione dei file non può superare {{size}} MB." + close_modal: + title: Sto chiudendo questo post come... + btn_cancel: Cancella + btn_submit: Invia + remark: + empty: Non può essere vuoto. + msg: + empty: Per favore seleziona un motivo + report_modal: + flag_title: Sto segnalando questo post per riportarlo come... + close_title: Sto chiudendo questo post come... + review_question_title: Rivedi la domanda + review_answer_title: Rivedi la risposta + review_comment_title: Rivedi il commento + btn_cancel: Cancella + btn_submit: Invia + remark: + empty: Non può essere vuoto. + msg: + empty: Per favore seleziona un motivo + not_a_url: Formato URL errato. + url_not_match: L'origine dell'URL non corrisponde al sito web corrente. + tag_modal: + title: Crea un nuovo tag + form: + fields: + display_name: + label: Nome da visualizzare + msg: + empty: Il nome utente non può essere vuoto. + range: Nome utente fino a 35 caratteri. + slug_name: + label: Slug dell'URL + desc: URL slug fino a 35 caratteri. + msg: + empty: Lo slug dell'URL non può essere vuoto. + range: Slug dell'URL fino a 35 caratteri. + character: Lo slug dell'URL contiene un set di caratteri non consentiti. + desc: + label: Descrizione + revision: + label: Revisione + edit_summary: + label: Modifica il riepilogo + placeholder: >- + Spiega brevemente le tue modifiche (ortografia rifinita, grammatica corretta, formattazione migliorata) + btn_cancel: Cancella + btn_submit: Invia + btn_post: Pubblica un nuovo tag + tag_info: + created_at: Creato + edited_at: Modificato + history: Cronologia + synonyms: + title: Sinonimi + text: I seguenti tag verranno rimappati a + empty: Nessun sinonimo trovato. + btn_add: Aggiungi un sinonimo + btn_edit: Modifica + btn_save: Salva + synonyms_text: I seguenti tag verranno rimappati a + delete: + title: Elimina questo tag + tip_with_posts: >- +

        Non è consentita l'eliminazione di tag con post.

        Rimuovi prima questo tag dai post.

        + tip_with_synonyms: >- +

        Non è consentita l'eliminazione di tag con sinonimi.

        Per favore, rimuovi prima i sinonimi da questo tag.

        + tip: Sei sicuro di voler cancellare? + close: Chiudi + merge: + title: Unisci tag + source_tag_title: Cerca tag + source_tag_description: Il tag sorgente e i dati associati verranno rimappati al tag di destinazione. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Modifica Tag + default_reason: Modifica tag + default_first_reason: Aggiungi tag + btn_save_edits: Salva modifiche + btn_cancel: Cancella + dates: + long_date: Mese, giorno + long_date_with_year: "Giorno, Mese, Anno" + long_date_with_time: "MMM D, AAAA [at] HH:mm" + now: ora + x_seconds_ago: "{{count}}s fa" + x_minutes_ago: "{{count}}m fa" + x_hours_ago: "{{count}}h fa" + hour: ora + day: giorno + hours: ore + days: giorni + month: month + months: months + year: year + reaction: + heart: cuore + smile: sorriso + frown: disapprovare + btn_label: aggiungere o rimuovere le reazioni + undo_emoji: annulla reazione {{ emoji }} + react_emoji: reagire con {{ emoji }} + unreact_emoji: non reagire con {{ emoji }} + comment: + btn_add_comment: Aggiungi un commento + reply_to: Rispondi a + btn_reply: Rispondi + btn_edit: Modifica + btn_delete: Cancella + btn_flag: Segnala + btn_save_edits: Salva modifiche + btn_cancel: Cancella + show_more: "{{count}} altri commenti" + tip_question: >- + Usa i commenti per chiedere maggiori informazioni o per suggerire miglioramenti. Evita di rispondere alle domande nei commenti. + tip_answer: >- + Utilizza i commenti per rispondere ad altri utenti o avvisarli delle modifiche. Se stai aggiungendo nuove informazioni, modifica il tuo post invece di commentare. + tip_vote: Aggiunge qualcosa di utile al post + edit_answer: + title: Modifica risposta + default_reason: Modifica risposta + default_first_reason: Aggiungi risposta + form: + fields: + revision: + label: Revisione + answer: + label: Risposta + feedback: + characters: Il testo deve contenere almeno 6 caratteri. + edit_summary: + label: Modifica il riepilogo + placeholder: >- + Spiega brevemente le tue modifiche (ortografia rifinita, grammatica corretta, formattazione migliorata) + btn_save_edits: Salva modifiche + btn_cancel: Annulla + tags: + title: Tag + sort_buttons: + popular: Popolari + name: Nome + newest: Più recente + button_follow: Segui + button_following: Segui già + tag_label: domande + search_placeholder: Filtra per nome del tag + no_desc: Il tag non ha descrizioni. + more: Altro + wiki: Wiki + ask: + title: Create Question + edit_title: Modifica Domanda + default_reason: Modifica domanda + default_first_reason: Create question + similar_questions: Domande simili + form: + fields: + revision: + label: Revisione + title: + label: Titolo + placeholder: What's your topic? Be specific. + msg: + empty: Il titolo non può essere vuoto. + range: Il titolo non può superare i 150 caratteri + body: + label: Contenuto + msg: + empty: Il corpo del testo non può essere vuoto. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Tags + msg: + empty: I tag non possono essere vuoti. + answer: + label: Risposta + msg: + empty: La risposta non può essere vuota. + edit_summary: + label: Modifica riepilogo + placeholder: >- + Spiega brevemente le tue modifiche (ortografia corretta, grammatica corretta, formattazione migliorata) + btn_post_question: Posta la tua domanda + btn_save_edits: Salva modifiche + answer_question: Rispondi alla tua domanda + post_question&answer: Posta la tua domanda e risposta + tag_selector: + add_btn: Aggiungi tag + create_btn: Crea un nuovo tag + search_tag: Cerca tag + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: Nessun tag corrispondente + tag_required_text: Tag richiesto (almeno uno) + header: + nav: + question: Domande + tag: Tags + user: Utenti + badges: Badges + profile: Profilo + setting: Impostazioni + logout: Disconnetti + admin: Amministratore + review: Revisione + bookmark: Segnalibri + moderation: Moderazione + search: + placeholder: Cerca + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Modifica + loading: caricamento in corso... + pic_auth_code: + title: Captcha + placeholder: Digita il testo sopra + msg: + empty: Il Captcha non può essere vuoto. + inactive: + first: >- + Hai quasi finito! Abbiamo inviato un'e-mail di attivazione a {{mail}}. Segui le istruzioni contenute nella mail per attivare il tuo account. + info: "Se non arriva, controlla la cartella spam." + another: >- + Ti abbiamo inviato un'altra email di attivazione all'indirizzo {{mail}}. Potrebbero volerci alcuni minuti prima che arrivi; assicurati di controllare la cartella spam. + btn_name: Reinvia l'e-mail di attivazione + change_btn_name: Modifica e-mail + msg: + empty: Non può essere vuoto. + resend_email: + url_label: Sei sicuro di voler inviare nuovamente l'e-mail di attivazione? + url_text: Puoi anche fornire all'utente il link di attivazione riportato sopra. + login: + login_to_continue: Accedi per continuare + info_sign: Non hai un account? <1>Iscriviti + info_login: Hai già un account? <1>Accedi + agreements: Registrandoti, accetti l'<1>informativa sulla privacy e i <3>termini del servizio. + forgot_pass: Password dimenticata? + name: + label: Nome + msg: + empty: Il nome non può essere vuoto. + range: Il nome deve essere di lunghezza compresa tra 2 e 30 caratteri. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: E-mail + msg: + empty: L'email non può essere vuota. + password: + label: Password + msg: + empty: La password non può essere vuota. + different: Le password inserite su entrambi i lati non corrispondono + account_forgot: + page_title: Password dimenticata? + btn_name: Inviami email di recupero + send_success: >- + Se un account corrisponde a {{mail}}, a breve dovresti ricevere un'e-mail con le istruzioni su come reimpostare la password. + email: + label: E-mail + msg: + empty: Il campo email non può essere vuoto. + change_email: + btn_cancel: Cancella + btn_update: Aggiorna indirizzo email + send_success: >- + Se un account corrisponde a {{mail}}, a breve dovresti ricevere un'email con le istruzioni su come reimpostare la password. + email: + label: Nuova email + msg: + empty: L'email non può essere vuota. + oauth: + connect: Connettiti con {{ auth_name }} + remove: Rimuovi {{ auth_name }} + oauth_bind_email: + subtitle: Aggiungi un'email di recupero al tuo account. + btn_update: Aggiorna l'indirizzo email + email: + label: E-mail + msg: + empty: L'email non può essere vuota. + modal_title: Email già esistente + modal_content: Questo indirizzo email è già registrato. Sei sicuro che vuoi connetterti all'account esistente? + modal_cancel: Cambia email + modal_confirm: Connettiti all'account esistente + password_reset: + page_title: Reimposta la password + btn_name: Reimposta la mia password + reset_success: >- + Hai cambiato con successo la tua password; sarai reindirizzato alla pagina di accesso. + link_invalid: >- + Siamo spiacenti, questo link di reset della password non è più valido. Forse la password è già stata reimpostata? + to_login: Continua per effettuare il login + password: + label: Password + msg: + empty: La password non può essere vuota + length: La lunghezza deve essere compresa tra 8 e 32 + different: Le password inserite non corrispondono + password_confirm: + label: Conferma la nuova password + settings: + page_title: Impostazioni + goto_modify: Vai alle modifiche + nav: + profile: Profilo + notification: Notifiche + account: Profilo + interface: Interfaccia + profile: + heading: Profilo + btn_name: Salva + display_name: + label: Visualizza nome + msg: Il nome utente non può essere vuoto. + msg_range: Display name must be 2-30 characters in length. + username: + label: Nome utente + caption: Gli altri utenti possono menzionarti con @{{username}}. + msg: Il nome utente non può essere vuoto. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Immagine del profilo + gravatar: Gravatar + gravatar_text: Puoi cambiare l'immagine + custom: Personalizzato + custom_text: Puoi caricare la tua immagine. + default: Sistema + msg: Per favore carica un avatar + bio: + label: Chi sono + website: + label: Sito web + placeholder: "https://esempio.com" + msg: Formato non corretto del sito web + location: + label: Luogo + placeholder: "Città, Paese" + notification: + heading: Notifiche email + turn_on: Accendi + inbox: + label: Notifiche in arrivo + description: Risposte alle tue domande, commenti, inviti e altro ancora. + all_new_question: + label: Tutte le nuove domande + description: Ricevi una notifica per tutte le nuove domande. Fino a 50 domande a settimana. + all_new_question_for_following_tags: + label: Tutte le nuove domande per i seguenti tag + description: Ricevi una notifica delle nuove domande per i seguenti tag. + account: + heading: Profilo + change_email_btn: Modifica e-mail + change_pass_btn: Modifica password + change_email_info: >- + Abbiamo inviato una mail a quell'indirizzo. Si prega di seguire le istruzioni di conferma. + email: + label: E-mail + new_email: + label: Nuova mail + msg: La nuova email non può essere vuota. + pass: + label: Password attuale + msg: La password non può essere vuota + password_title: Password + current_pass: + label: Password attuale + msg: + empty: La password attuale non può essere vuota. + length: La lunghezza deve essere compresa tra 8 e 32. + different: Le due password inserite non corrispondono. + new_pass: + label: Nuova password + pass_confirm: + label: Conferma la nuova password + interface: + heading: Interfaccia + lang: + label: Lingua dell'interfaccia + text: La lingua dell'interfaccia utente cambierà quando aggiorni la pagina. + my_logins: + title: I miei login + label: Accedi o registrati su questo sito utilizzando questi account. + modal_title: Rimuovi login + modal_content: Sei sicuro di voler rimuovere questo login dal tuo account? + modal_confirm_btn: Rimuovi + remove_success: Rimosso con successo + toast: + update: Aggiornamento riuscito + update_password: Password modificata con successo. + flag_success: Grazie per la segnalazione. + forbidden_operate_self: Vietato operare su se stessi. + review: Le tue modifiche verranno visualizzata dopo la revisione. + sent_success: Inviato correttamente + related_question: + title: Related + answers: risposte + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Persone Interpellate + desc: Seleziona le persone che pensi potrebbero conoscere la risposta. + invite: Invita a rispondere + add: Aggiungi contatti + search: Cerca persone + question_detail: + action: Azione + created: Created + Asked: Chiesto + asked: chiesto + update: Modificato + Edited: Edited + edit: modificato + commented: commentato + Views: Visualizzati + Follow: Segui + Following: Segui già + follow_tip: Segui questa domanda per ricevere notifiche + answered: Risposto + closed_in: Chiuso in + show_exist: Mostra domanda esistente. + useful: Utile + question_useful: È utile e chiaro + question_un_useful: Non è chiaro né utile + question_bookmark: Aggiungi questa domanda ai segnalibri + answer_useful: È utile + answer_un_useful: Non è utile + answers: + title: Risposte + score: Punteggio + newest: Più recenti + oldest: Meno recente + btn_accept: Accetta + btn_accepted: Accettato + write_answer: + title: La tua risposta + edit_answer: Modifica la mia risposta attuale + btn_name: Pubblica la tua risposta + add_another_answer: Aggiungi un'altra risposta + confirm_title: Continua a rispondere + continue: Continua + confirm_info: >- +

        Sei sicuro di voler aggiungere un'altra risposta?

        In alternativa, puoi usare il link di modifica per perfezionare e migliorare la tua risposta esistente.

        + empty: La risposta non può essere vuota. + characters: Il contenuto deve avere una lunghezza di almeno 6 caratteri. + tips: + header_1: Grazie per la risposta + li1_1: Assicurati di rispondere alla domanda. Fornisci dettagli e condividi la tua ricerca. + li1_2: Effettua il backup di qualsiasi dichiarazione fatta con riferimenti o esperienze personali. + header_2: Ma evita... + li2_1: Chiedere aiuto, cercare chiarimenti o rispondere ad altre risposte. + reopen: + confirm_btn: Riapri + title: Riapri questo post + content: Sei sicuro di voler riaprire? + list: + confirm_btn: Listare + title: Lista questo post + content: Sei sicuro di volerlo listare? + unlist: + confirm_btn: Rimuovi dall'elenco + title: Rimuovi questo post + content: Sei sicuro di voler rimuovere dall'elenco? + pin: + title: Fissa questo post in cima al profilo + content: Sei sicuro di voler fissare in blocco? Questo post apparirà in cima a tutte le liste. + confirm_btn: Fissa sul profilo + delete: + title: Cancella questo post + question: >- + Non consigliamo di eliminaredomande con risposte perché ciò priva i futuri lettori di questa conoscenza.

        L'eliminazione ripetuta di domande con risposte può comportare il blocco delle domande nel tuo account. Sei sicuro di voler eliminare? + answer_accepted: >- +

        Non consigliamo di eliminare la risposta accettata perché così facendo si priva i futuri lettori di questa conoscenza.

        La cancellazione ripetuta delle risposte accettate può causare il blocco del tuo account dalla risposta. Sei sicuro di voler eliminare? + other: Sei sicuro di voler eliminare? + tip_answer_deleted: Questa risposta è stata cancellata + undelete_title: Ripristina questo post + undelete_desc: Sei sicuro di voler ripristinare? + btns: + confirm: Conferma + cancel: Cancella + edit: Modifica + save: Salva + delete: Elimina + undelete: Ripristina + list: Aggiungi all'elenco + unlist: Rimuovi dall'elenco + unlisted: Rimosso dall'elenco + login: Accedi + signup: Registrati + logout: Disconnetti + verify: Verifica + create: Create + approve: Approva + reject: Rifiuta + skip: Salta + discard_draft: Elimina bozza + pinned: Fissato in cima + all: Tutti + question: Domanda + answer: Risposta + comment: Commento + refresh: Aggiorna + resend: Rinvia + deactivate: Disattivare + active: Attivo + suspend: Sospendi + unsuspend: Riabilita + close: Chiudi + reopen: Riapri + ok: OK + light: Illuminazione + dark: Scuro + system_setting: Configurazione di sistema + default: Predefinito + reset: Resetta + tag: Tag + post_lowercase: post + filter: 'Filtra' + ignore: Ignora + submit: Invia + normal: Normale + closed: Chiuso + deleted: Eliminato + deleted_permanently: Deleted permanently + pending: In attesa + more: Altro + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Risultati della ricerca + keywords: Parole chiave + options: Opzioni + follow: Segui + following: Segui già + counts: "{{count}} Risultati" + counts_loading: "... Results" + more: Altro + sort_btns: + relevance: Rilevanza + newest: Più recenti + active: Attivo + score: Punteggio + more: Altro + tips: + title: Suggerimenti per ricerca avanzata + tag: "<1>[tag] cerca dentro un tag" + user: "<1>user:username ricerca per autore" + answer: "<1>risposte:0 domande senza risposta" + score: "<1>punteggio:3 messaggi con un punteggio di 3+" + question: "<1>is:question cerca domande" + is_answer: "<1>is:answer cerca risposte" + empty: Non siamo riusciti a trovare nulla.
        Prova parole chiave diverse o meno specifiche. + share: + name: Condividi + copy: Copia il link + via: Condividi il post via... + copied: Copiato + facebook: Condividi su Facebook + twitter: Share to X + cannot_vote_for_self: Non puoi votare un tuo post! + modal_confirm: + title: Errore... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Il tuo nuovo account è confermato; sarai reindirizzato alla home page. + link: Continua alla Homepage + oops: Oops! + invalid: Il link che hai usato non è più attivo. + confirm_new_email: La tua email è stata aggiornata. + confirm_new_email_invalid: >- + Siamo spiacenti, questo link di conferma non è più valido. Forse la tua email è già stata modificata? + unsubscribe: + page_title: Annulla l'iscrizione + success_title: Cancellazione effettuata con successo + success_desc: Sei stato rimosso con successo da questa lista e non riceverai ulteriori email + link: Cambia impostazioni + question: + following_tags: Tag seguenti + edit: Modifica + save: Salva + follow_tag_tip: Segui i tag per curare la tua lista di domande. + hot_questions: Domande scottanti + all_questions: Tutte le domande + x_questions: "{{ count }} Domande" + x_answers: "{{count}} risposte" + x_posts: "{{ count }} Posts" + questions: Domande + answers: Risposte + newest: Più recenti + active: Attivo + hot: Caldo + frequent: Frequenti + recommend: Raccomandato + score: Punteggio + unanswered: Senza risposta + modified: Modificato + answered: Risposte + asked: chiesto + closed: Chiuso + follow_a_tag: Segui un tag + more: Altro + personal: + overview: Informazioni Generali + answers: Risposte + answer: Risposta + questions: Domande + question: Domanda + bookmarks: Segnalibri + reputation: Reputazione + comments: Commenti + votes: Voti + badges: Badges + newest: Più recenti + score: Punteggio + edit_profile: Modifica profilo + visited_x_days: "{{ count }} giorni visitati" + viewed: Visualizzati + joined: Iscritto + comma: "," + last_login: Visto + about_me: Chi sono + about_me_empty: "// Ciao, mondo !" + top_answers: Migliori risposte + top_questions: Domande principali + stats: Statistiche + list_empty: Nessun post trovato.
        Forse desideri selezionare una scheda diversa? + content_empty: Nessun post trovato. + accepted: Accettato + answered: risposto + asked: chiesto + downvoted: votato negativamente + mod_short: Moderatore + mod_long: Moderatori + x_reputation: reputazione + x_votes: voti ricevuti + x_answers: risposte + x_questions: domande + recent_badges: Badges Recenti + install: + title: Installazione + next: Avanti + done: Fatto + config_yaml_error: Impossibile creare il file config.yaml. + lang: + label: Scegli una lingua + db_type: + label: Motore database + db_username: + label: Nome utente + placeholder: root + msg: Il nome utente non può essere vuoto. + db_password: + label: Password + placeholder: root + msg: La password non può essere vuota. + db_host: + label: Host del database + placeholder: "db:3306" + msg: L'host del database non può essere vuoto. + db_name: + label: Nome database + placeholder: risposta + msg: Il nome del database non può essere vuoto. + db_file: + label: File del database + placeholder: /data/answer.db + msg: Il file del database non può essere vuoto. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Crea config.yaml + label: File config.yaml creato. + desc: >- + Puoi creare manualmente il file <1>config.yaml nella directory <1>/var/wwww/xxx/ e incollarvi il seguente testo. + info: Una volta fatto, fai clic sul pulsante "Avanti". + site_information: Informazioni sul sito + admin_account: Account Amministratore + site_name: + label: Nome del sito + msg: Il nome del sito non può essere vuoto. + msg_max_length: Il nome del sito deve contenere un massimo di 30 caratteri. + site_url: + label: URL del sito + text: L'indirizzo del tuo sito. + msg: + empty: L'URL del sito non può essere vuoto. + incorrect: Formato errato dell'URL del sito. + max_length: L'URL del sito deve contenere un massimo di 512 caratteri. + contact_email: + label: Email di contatto + text: Indirizzo e-mail del contatto chiave responsabile di questo sito. + msg: + empty: L'email del contatto non può essere vuota. + incorrect: Formato errato dell'e-mail di contatto. + login_required: + label: Privato + switch: Login obbligatorio + text: Solo gli utenti registrati possono accedere a questa community. + admin_name: + label: Nome + msg: Il nome non può essere vuoto. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Password + text: >- + Avrai bisogno di questa password per accedere. Conservala in un luogo sicuro. + msg: La password non può essere vuota + msg_min_length: La password deve contenere almeno 8 caratteri. + msg_max_length: La password deve contenere un massimo di 32 caratteri. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: E-mail + text: Avrai bisogno di questa email per accedere. + msg: + empty: Il campo email non può essere vuoto. + incorrect: Formato dell'email errato. + ready_title: Il tuo sito è pronto + ready_desc: >- + Se vuoi cambiare più impostazioni, visita la sezione <1>admin che si trova nel menu del sito. + good_luck: "Divertiti e buona fortuna!" + warn_title: Pericolo + warn_desc: >- + Il file <1>config.yaml esiste già. Se vuoi reimpostare uno qualsiasi degli elementi di configurazione in questo file, eliminalo prima. + install_now: Puoi provare a <1>installare ora. + installed: Già installato + installed_desc: >- + Sembra che tu abbia già installato. Per reinstallare, cancella prima le vecchie tabelle del database. + db_failed: Connessione al database fallita + db_failed_desc: >- + Questo significa che le informazioni sul database nel file <1>config.yaml non sono corrette o che non è stato possibile stabilire il contatto con il server del database. Ciò potrebbe significare che il server del database del tuo host è inattivo. + counts: + views: visualizzazioni + votes: Voti + answers: risposte + accepted: Accettato + page_error: + http_error: Errore HTTP {{ code }} + desc_403: Non hai i permessi per accedere a questa pagina. + desc_404: Sfortunatamente, questa pagina non esiste. + desc_50X: Il server ha riscontrato un errore e non è stato possibile completare la richiesta. + back_home: Torna alla home page + page_maintenance: + desc: "Siamo in manutenzione, torneremo presto." + nav_menus: + dashboard: Pannello di controllo + contents: Contenuti + questions: Domande + answers: Risposte + users: Utenti + badges: Badges + flags: Contrassegni + settings: Impostazioni + general: Generale + interface: Interfaccia + smtp: Protocollo di Trasferimento Posta Semplice + branding: Marchio + legal: Legale + write: Scrivi + terms: Terms + tos: Termini del servizio + privacy: Privacy + seo: SEO + customize: Personalizza + themes: Temi + login: Accedi + privileges: Privilegi + plugins: Plugin + installed_plugins: Plugin installati + apperance: Appearance + website_welcome: Benvenuto/a su {{site_name}}! + user_center: + login: Accedi + qrcode_login_tip: Si prega di utilizzare {{ agentName }} per scansionare il codice QR e accedere. + login_failed_email_tip: Accesso non riuscito. Consenti a questa app di accedere alle tue informazioni email prima di riprovare. + badges: + modal: + title: Congratulazioni + content: Hai guadagnato un nuovo distintivo. + close: Chiudi + confirm: Visualizza badge + title: Badges + awarded: Premiati + earned_×: Ottenuto ×{{ number }} + ×_awarded: "{{ number }} premiato" + can_earn_multiple: Puoi guadagnare questo più volte. + earned: Ottenuti + admin: + admin_header: + title: Amministratore + dashboard: + title: Pannello di controllo + welcome: Benvenuto ad Admin! + site_statistics: Statistiche del sito + questions: "Domande:" + resolved: "Risolto:" + unanswered: "Senza risposta:" + answers: "Risposte:" + comments: "Commenti:" + votes: "Voti:" + users: "Utenti:" + flags: "Flags" + reviews: "Revisioni" + site_health: Stato del sito + version: "Versione:" + https: "HTTPS:" + upload_folder: "Carica Cartella" + run_mode: "Modalità di esecuzione:" + private: Privato + public: Pubblico + smtp: "Protocollo di Trasferimento Posta Semplice" + timezone: "Fuso orario:" + system_info: Info sistema + go_version: "Versione Go:" + database: "Banca dati:" + database_size: "Dimensioni del database" + storage_used: "Spazio di archiviazione utilizzato:" + uptime: "Tempo di attività:" + links: Collegamenti + plugins: Plugin + github: GitHub + blog: Blog + contact: Contatti + forum: Forum + documents: Documenti + feedback: Feedback + support: Assistenza + review: Revisione + config: Configurazione + update_to: Aggiornato a + latest: Recenti + check_failed: Controllo fallito + "yes": "Sì" + "no": "No" + not_allowed: Non autorizzato + allowed: Consentito + enabled: Abilitato + disabled: Disabilitato + writable: Editabile + not_writable: Non editabile + flags: + title: Contrassegni + pending: In attesa + completed: Completato + flagged: Contrassegnato + flagged_type: Contrassegnato {{ type }} + created: Creato + action: Azione + review: Revisione + user_role_modal: + title: Cambia ruolo utente in... + btn_cancel: Cancella + btn_submit: Invia + new_password_modal: + title: Imposta una nuova password + form: + fields: + password: + label: Password + text: L'utente sarà disconnesso e dovrà effettuare nuovamente il login. + msg: La password deve contenere da 8 a 32 caratteri. + btn_cancel: Cancella + btn_submit: Invia + edit_profile_modal: + title: Modifica profilo + form: + fields: + display_name: + label: Visualizza nome + msg_range: Il nome visualizzato deve essere di 2-30 caratteri di lunghezza. + username: + label: Nome utente + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Indirizzo e-mail non valido. + edit_success: Modificato con successo + btn_cancel: Annulla + btn_submit: Invia + user_modal: + title: Aggiungi un nuovo utente + form: + fields: + users: + label: Aggiungi utenti in blocco + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separare “nome, email, password” con delle virgole. Un utente per riga. + msg: "Inserisci l'email dell'utente, una per riga." + display_name: + label: Nome da visualizzare + msg: Il nome visualizzato deve essere di 2-30 caratteri di lunghezza. + email: + label: E-mail + msg: L'email non è valida. + password: + label: Password + msg: La password deve contenere da 8 a 32 caratteri. + btn_cancel: Cancella + btn_submit: Invia + users: + title: Utenti + name: Nome + email: E-mail + reputation: Reputazione + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Sospendi fino al + status: Stato + role: Ruolo + action: Azione + change: Modifica + all: Tutti + staff: Personale + more: Altro + inactive: Inattivo + suspended: Sospeso + deleted: Eliminato + normal: Normale + Moderator: Moderatore + Admin: Amministratore + User: Utente + filter: + placeholder: "Filtra per nome, utente:id" + set_new_password: Imposta una nuova password + edit_profile: Modifica profilo + change_status: Modifica lo stato + change_role: Cambia il ruolo + show_logs: Visualizza i log + add_user: Aggiungi utente + deactivate_user: + title: Disattiva utente + content: Un utente inattivo deve riconvalidare la propria email. + delete_user: + title: Rimuovi questo utente + content: Sei sicuro di voler eliminare questo utente? L'operazione è permanente. + remove: Rimuovi il loro contenuto + label: Rimuovi tutte le domande, risposte, commenti, ecc. + text: Non selezionare questa opzione se desideri eliminare solo l'account dell'utente. + suspend_user: + title: Sospendi questo utente + content: Un utente sospeso non può accedere. + label: Per quanto tempo vuoi sospendere l'utente? + forever: Per sempre + questions: + page_title: Domande + unlisted: Rimosso dall'elenco + post: Posta + votes: Voti + answers: Risposte + created: Creato + status: Stato + action: Azione + change: Modifica + pending: In attesa + filter: + placeholder: "Filtra per titolo, domanda:id" + answers: + page_title: Risposte + post: Post + votes: Voti + created: Creato + status: Stato + action: Azione + change: Cambio + filter: + placeholder: "Filtra per titolo, domanda:id" + general: + page_title: Generale + name: + label: Nome del sito + msg: Il nome del sito non può essere vuoto. + text: "Il nome di questo sito, come usato nel tag del titolo." + site_url: + label: URL del sito + msg: L'url del sito non può essere vuoto. + validate: Inserisci un URL valido. + text: L'indirizzo del tuo sito. + short_desc: + label: Descrizione breve del sito + msg: La descrizione breve del sito non può essere vuota. + text: "Breve descrizione, come utilizzata nel tag del titolo sulla home page." + desc: + label: Descrizione del sito + msg: La descrizione del sito non può essere vuota. + text: "Descrivi questo sito in una frase, come utilizzato nel tag meta description." + contact_email: + label: Email di contatto + msg: L'email del contatto non può essere vuota. + validate: Email di contatto non valida. + text: Indirizzo e-mail del contatto chiave responsabile di questo sito. + check_update: + label: Aggiornamenti Software + text: Controlla automaticamente gli aggiornamenti + interface: + page_title: Interfaccia + language: + label: Lingua dell'interfaccia + msg: La lingua dell'interfaccia non può essere vuota. + text: La lingua dell'interfaccia utente cambierà quando aggiorni la pagina. + time_zone: + label: Fuso orario + msg: Il fuso orario non può essere vuoto. + text: Scegli una città con il tuo stesso fuso orario. + avatar: + label: Avatar Predefinito + text: Per gli utenti senza un proprio avatar personalizzato. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: Protocollo di Trasferimento Posta Semplice + from_email: + label: Dall'email + msg: L'email del contatto non può essere vuota. + text: L'indirizzo email da cui vengono inviate le email. + from_name: + label: Dal nome + msg: "Il nome del mittente non può essere vuoto.\n" + text: Il nome da cui vengono inviate le email. + smtp_host: + label: Host SMTP + msg: L'host SMTP non può essere vuoto. + text: Il tuo server di posta. + encryption: + label: Crittografia + msg: La crittografia non può essere vuota. + text: Per la maggior parte dei server SSL è l'opzione consigliata. + ssl: SSL + tls: TLS + none: Nessuna + smtp_port: + label: Porta SMTP + msg: La porta SMTP deve essere numero 1 ~ 65535. + text: La porta del tuo server di posta. + smtp_username: + label: Nome utente SMTP + msg: Il nome utente SMTP non può essere vuoto. + smtp_password: + label: Password SMTP + msg: La password SMTP non può essere vuota. + test_email_recipient: + label: Verifica destinatari email + text: Fornisci l'indirizzo email che riceverà i test inviati. + msg: Destinatari email di prova non validi + smtp_authentication: + label: "\nAbilita l'autenticazione" + title: Autenticazione SMTP + msg: L'autenticazione SMTP non può essere vuota. + "yes": "Sì" + "no": "No" + branding: + page_title: Marchio + logo: + label: Logo + msg: Il logo non può essere vuoto. + text: L'immagine del logo in alto a sinistra del tuo sito. Utilizza un'immagine rettangolare ampia con un'altezza di 56 e proporzioni superiori a 3:1. Se lasciato vuoto, il testo del titolo del sito verrà mostrato. + mobile_logo: + label: Logo per versione mobile + text: "\nIl logo utilizzato nella versione mobile del tuo sito. Utilizza un'immagine rettangolare ampia con un'altezza di 56. Se lasciata vuota, verrà utilizzata l'immagine dell'impostazione \"logo\"." + square_icon: + label: Icona quadrata + msg: L'icona quadrata non può essere vuota. + text: "Immagine utilizzata come base per le icone dei metadata. Idealmente dovrebbe essere più grande di 512x512.\n" + favicon: + label: Favicon + text: Una icona favorita per il tuo sito. Per funzionare correttamente su un CDN deve essere un png. Verrà ridimensionato a 32x32. Se lasciato vuoto, verrà utilizzata l'"icona quadrata". + legal: + page_title: Legale + terms_of_service: + label: Termini del servizio + text: "Puoi aggiungere qui i termini del contenuto del servizio. Se hai già un documento ospitato altrove, fornisci qui l'URL completo." + privacy_policy: + label: Informativa sulla privacy + text: "Puoi aggiungere il contenuto della politica sulla privacy qui. Se hai già un documento ospitato altrove, fornisci l'URL completo qui." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Scrivi + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Risposta a scrivere + label: Ogni utente può scrivere una sola risposta per ogni domanda + text: "Disattiva per consentire agli utenti di scrivere risposte multiple alla stessa domanda, il che potrebbe causare una risposta sfocata." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Raccomanda tag + text: "I tag consigliati verranno mostrati nell'elenco a discesa per impostazione predefinita." + msg: + contain_reserved: "i tag consigliati non possono contenere tag riservati" + required_tag: + title: Imposta tag necessari + label: Imposta “Raccomanda tag” come tag richiesti + text: "Ogni nuova domanda deve avere almeno un tag raccomandato." + reserved_tags: + label: Tag riservati + text: "I tag riservati possono essere utilizzati solo dal moderatore." + image_size: + label: Dimensione massima dell'immagine (MB) + text: "La dimensione massima del caricamento dell'immagine." + attachment_size: + label: Dimensione massima degli allegati (MB) + text: "Dimensione massima del caricamento dei file allegati." + image_megapixels: + label: Massima immagine megapixel + text: "Numero massimo di megapixel consentiti per un'immagine." + image_extensions: + label: Estensioni di immagini autorizzate + text: "Un elenco di estensioni di file consentite per la visualizzazione dell'immagine, separate da virgole." + attachment_extensions: + label: Estensioni di allegati autorizzate + text: "Una lista di estensioni di file consentite per il caricamento, separate con virgole. ATTENZIONE: Consentire i caricamenti potrebbe causare problemi di sicurezza." + seo: + page_title: SEO + permalink: + label: Permalink + text: Le strutture URL personalizzate possono migliorare l'usabilità e la compatibilità futura dei tuoi link. + robots: + label: robots.txt + text: Questo sovrascriverà definitivamente tutte le impostazioni relative al sito. + themes: + page_title: Temi + themes: + label: Temi + text: Seleziona un tema esistente. + color_scheme: + label: Schema colore + navbar_style: + label: Navbar background style + primary_color: + label: Colore primario + text: Modifica i colori utilizzati dai tuoi temi + css_and_html: + page_title: CSS e HTML + custom_css: + label: CSS personalizzato + text: > + + head: + label: Testata + text: > + + header: + label: Intestazione + text: > + + footer: + label: Piè di pagina + text: Questo verrà inserito prima di </body>. + sidebar: + label: Barra laterale + text: Questo verrà inserito nella barra laterale. + login: + page_title: Accedi + membership: + title: Adesione + label: Consenti nuove registrazioni + text: Disattiva per impedire a chiunque di creare un nuovo account. + email_registration: + title: Registrazione email + label: Consenti registrazione email + text: Disattiva per impedire a chiunque di creare un nuovo account tramite email. + allowed_email_domains: + title: Domini email consentiti + text: "Domini email con cui gli utenti devono registrare gli account. Un dominio per riga. Verrà ignorato quando vuoto.\n" + private: + title: Privato + label: Login obbligatorio + text: Solo gli utenti registrati possono accedere a questa community. + password_login: + title: Password di accesso + label: Consenti il login di email e password + text: "ATTENZIONE: Se disattivi, potresti non essere in grado di accedere se non hai precedentemente configurato un altro metodo di login." + installed_plugins: + title: Plugin installati + plugin_link: I plugin estendono ed espandono le funzionalità. È possibile trovare plugin nel repository <1>Plugin. + filter: + all: Tutto + active: Attivo + inactive: Inattivo + outdated: Obsoleto + plugins: + label: Plugin + text: Seleziona un plugin esistente. + name: Nome + version: Versione + status: Stato + action: Azione + deactivate: Disattivare + activate: Attivare + settings: Impostazioni + settings_users: + title: Utenti + avatar: + label: Avatar Predefinito + text: Per gli utenti senza un proprio avatar personalizzato. + gravatar_base_url: + label: Gravatar Base URL + text: "\nURL della base API del provider Gravatar. Ignorato quando vuoto." + profile_editable: + title: Profilo modificabile + allow_update_display_name: + label: Consenti di cambiare il nome utente + allow_update_username: + label: Consenti di modificare il proprio nome utente + allow_update_avatar: + label: Consenti agli utenti di modificare l'immagine del profilo + allow_update_bio: + label: Consenti agli utenti di modificare la sezione "su di me" + allow_update_website: + label: Consenti agli utenti di modificare il proprio sito web + allow_update_location: + label: Consenti agli utenti di modificare la propria posizione + privilege: + title: Privilegi + level: + label: Livello di reputazione richiesto + text: Scegli la reputazione richiesta per i privilegi + msg: + should_be_number: l'input dovrebbe essere un numero + number_larger_1: il numero dovrebbe essere uguale o superiore a 1 + badges: + action: Azione + active: Attivo + activate: Attivare + all: Tutto + awards: Ricompense + deactivate: Disattivare + filter: + placeholder: Filtra per nome, badge:id + group: Gruppo + inactive: Inattivo + name: Nome + show_logs: Visualizza i log + status: Stato + title: Badges + form: + optional: (opzionale) + empty: non può essere vuoto + invalid: non è valido + btn_submit: Salva + not_found_props: "Proprietà richiesta {{ key }} non trovata." + select: Seleziona + page_review: + review: Revisione + proposed: Proposto + question_edit: Edita domanda + answer_edit: Edita risposta + tag_edit: Edita tag + edit_summary: Edita il riepilogo + edit_question: Edita la domanda + edit_answer: Edita la risposta + edit_tag: Edita tag + empty: Nessuna attività di revisione rimasta. + approve_revision_tip: Approvi questa revisione? + approve_flag_tip: Approvi questo contrassegno? + approve_post_tip: Approvi questo post? + approve_user_tip: Approvate questo utente? + suggest_edits: Modifiche suggerite + flag_post: Post contrassegnato + flag_user: Utente contrassegno + queued_post: "Posta in coda\n" + queued_user: Utente in coda + filter_label: Digita + reputation: reputazione + flag_post_type: Post contrassegnato come {{ type }}. + flag_user_type: Utente contrassegnato come {{ type }}. + edit_post: Modifica il post + list_post: Lista il post + unlist_post: Rimuovi post + timeline: + undeleted: Non cancellato + deleted: eliminato + downvote: voto negativo + upvote: voto a favore + accept: accetta + cancelled: Cancellato + commented: commentato + rollback: ripristino + edited: modificato + answered: risposto + asked: chiesto + closed: chiuso + reopened: riaperto + created: creato + pin: Fissa in cima + unpin: Rimosso dalla cima + show: elencato + hide: non elencato + title: "Cronologia per" + tag_title: "Timeline per" + show_votes: "Mostra voti" + n_or_a: N/D + title_for_question: "Timeline per" + title_for_answer: "Timeline per rispondere a {{ title }} di {{ author }}" + title_for_tag: "Timeline per tag" + datetime: Data e ora + type: Tipo + by: Di + comment: Commento + no_data: "Non abbiamo trovato nulla" + users: + title: Utenti + users_with_the_most_reputation: Utenti con i punteggi di reputazione più alti questa settimana + users_with_the_most_vote: Utenti che hanno votato di più questa settimana + staffs: Lo staff della community + reputation: reputazione + votes: voti + prompt: + leave_page: Sei sicuro di voler lasciare questa pagina? + changes_not_save: Le modifiche potrebbero non essere salvate. + draft: + discard_confirm: Sei sicuro di voler eliminare la bozza? + messages: + post_deleted: Questo post è stato eliminato. + post_cancel_deleted: Questo post è stato ripristinato. + post_pin: Questo post è stato selezionato. + post_unpin: Questo post è stato sbloccato. + post_hide_list: Questo post è stato nascosto dall'elenco. + post_show_list: Questo post è stato mostrato in elenco. + post_reopen: Questo post è stato riaperto. + post_list: Questo post è stato inserito. + post_unlist: Questo post è stato rimosso. + post_pending: Il tuo post è in attesa di revisione. Sarà visibile dopo essere stato approvato. + post_closed: Questo post è stato chiuso. + answer_deleted: Questa risposta è stata eliminata. + answer_cancel_deleted: Questa risposta è stata ripristinata. + change_user_role: Il ruolo di questo utente è stato cambiato. + user_inactive: Questo utente è già inattivo. + user_normal: Questo utente è già normale. + user_suspended: Questo utente è stato sospeso. + user_deleted: Questo utente è stato eliminato. + badge_activated: Questo badge è stato attivato. + badge_inactivated: Questo badge è stato disattivato. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/ja_JP.yaml b/data/i18n/ja_JP.yaml new file mode 100644 index 000000000..c0a24f57e --- /dev/null +++ b/data/i18n/ja_JP.yaml @@ -0,0 +1,2360 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: 成功 + unknown: + other: 不明なエラー + request_format_error: + other: リクエスト形式が無効です。 + unauthorized_error: + other: 権限がありません。 + database_error: + other: データサーバーエラー + forbidden_error: + other: アクセス権限がありません。 + duplicate_request_error: + other: 重複しています + action: + report: + other: 通報 + edit: + other: 編集 + delete: + other: 削除 + close: + other: 解決済み + reopen: + other: 再オープン + forbidden_error: + other: アクセス権限がありません。 + pin: + other: ピン留めする + hide: + other: 限定公開にする + unpin: + other: ピン留め解除 + show: + other: 限定公開を解除する + invite_someone_to_answer: + other: 編集 + undelete: + other: 復元する + merge: + other: Merge + role: + name: + user: + other: ユーザー + admin: + other: 管理者 + moderator: + other: モデレーター + description: + user: + other: 一般的なアクセスしか持ちません。 + admin: + other: すべてにアクセスできる大いなる力を持っています。 + moderator: + other: 管理者以外のすべての投稿へのアクセス権を持っています。 + privilege: + level_1: + description: + other: レベル1 必要最低の評判レベルで利用可(クローズサイト・グループ・特定の人数下での利用) + level_2: + description: + other: レベル2 少しだけ評判レベルが必要(スタートアップコミュニティ・不特定多数の人数での利用) + level_3: + description: + other: レベル3 高い評判レベルが必要(成熟したコミュニティ) + level_custom: + description: + other: カスタムレベル + rank_question_add_label: + other: 質問する + rank_answer_add_label: + other: 回答を書く + rank_comment_add_label: + other: コメントを書く + rank_report_add_label: + other: 通報 + rank_comment_vote_up_label: + other: コメントを高評価 + rank_link_url_limit_label: + other: 一度に2つ以上のリンクを投稿する + rank_question_vote_up_label: + other: 質問を高評価 + rank_answer_vote_up_label: + other: 回答を高評価 + rank_question_vote_down_label: + other: 質問を低評価 + rank_answer_vote_down_label: + other: 回答を低評価 + rank_invite_someone_to_answer_label: + other: 誰かを回答に招待する + rank_tag_add_label: + other: 新しいタグを作成 + rank_tag_edit_label: + other: タグの説明を編集(レビューが必要) + rank_question_edit_label: + other: 他の質問を編集(レビューが必要) + rank_answer_edit_label: + other: 他の回答を編集(レビューが必要) + rank_question_edit_without_review_label: + other: レビューなしで他の質問を編集する + rank_answer_edit_without_review_label: + other: レビューなしで他の回答を編集する + rank_question_audit_label: + other: 質問の編集をレビュー + rank_answer_audit_label: + other: 回答の編集をレビュー + rank_tag_audit_label: + other: タグの編集をレビュー + rank_tag_edit_without_review_label: + other: レビューなしでタグの説明を編集 + rank_tag_synonym_label: + other: タグの同義語を管理する + email: + other: メールアドレス + e_mail: + other: メールアドレス + password: + other: パスワード + pass: + other: パスワード + old_pass: + other: Current password + original_text: + other: 投稿 + email_or_password_wrong_error: + other: メールアドレスとパスワードが一致しません。 + error: + common: + invalid_url: + other: 無効なURL + status_invalid: + other: 無効なステータス + password: + space_invalid: + other: パスワードにスペースを含めることはできません。 + admin: + cannot_update_their_password: + other: パスワードは変更できません。 + cannot_edit_their_profile: + other: プロフィールを変更できません。 + cannot_modify_self_status: + other: ステータスを変更できません。 + email_or_password_wrong: + other: メールアドレスとパスワードが一致しません。 + answer: + not_found: + other: 回答が見つかりません。 + cannot_deleted: + other: 削除する権限がありません。 + cannot_update: + other: 更新する権限がありません。 + question_closed_cannot_add: + other: 質問はクローズされて、追加できません。 + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: コメントを編集することはできません。 + not_found: + other: コメントが見つかりません。 + cannot_edit_after_deadline: + other: コメント時間が長すぎて変更できません。 + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: メールアドレスは既に存在しています。 + need_to_be_verified: + other: 電子メールを確認する必要があります。 + verify_url_expired: + other: メール認証済みURLの有効期限が切れています。メールを再送信してください。 + illegal_email_domain_error: + other: そのメールドメインからのメールは許可されていません。別のメールアドレスを使用してください。 + lang: + not_found: + other: 言語ファイルが見つかりません。 + object: + captcha_verification_failed: + other: Captchaが間違っています。 + disallow_follow: + other: フォローが許可されていません。 + disallow_vote: + other: 投票が許可されていません。 + disallow_vote_your_self: + other: 自分の投稿には投票できません。 + not_found: + other: オブジェクトが見つかりません。 + verification_failed: + other: 認証に失敗しました。 + email_or_password_incorrect: + other: メールアドレスとパスワードが一致しません。 + old_password_verification_failed: + other: 古いパスワードの確認に失敗しました。 + new_password_same_as_previous_setting: + other: 新しいパスワードは前のパスワードと同じです。 + already_deleted: + other: この投稿は削除されました。 + meta: + object_not_found: + other: メタオブジェクトが見つかりません + question: + already_deleted: + other: この投稿は削除されました。 + under_review: + other: あなたの投稿はレビュー待ちです。承認されると表示されます。 + not_found: + other: 質問が見つかりません。 + cannot_deleted: + other: 削除する権限がありません。 + cannot_close: + other: クローズする権限がありません。 + cannot_update: + other: 更新する権限がありません。 + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: 評判ランクが条件を満たしていません + vote_fail_to_meet_the_condition: + other: フィードバックをありがとうございます。投票には少なくとも {{.Rank}} の評判が必要です。 + no_enough_rank_to_operate: + other: 少なくとも {{.Rank}} の評判が必要です。 + report: + handle_failed: + other: レポートの処理に失敗しました。 + not_found: + other: レポートが見つかりません。 + tag: + already_exist: + other: タグは既に存在します。 + not_found: + other: タグが見つかりません。 + recommend_tag_not_found: + other: おすすめタグは存在しません。 + recommend_tag_enter: + other: 少なくとも 1 つの必須タグを入力してください。 + not_contain_synonym_tags: + other: 同義語のタグを含めないでください。 + cannot_update: + other: 更新する権限がありません。 + is_used_cannot_delete: + other: 使用中のタグは削除できません。 + cannot_set_synonym_as_itself: + other: 現在のタグの同義語をそのものとして設定することはできません。 + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: Fromの名前はメールアドレスにできません。 + theme: + not_found: + other: テーマが見つかりません。 + revision: + review_underway: + other: 現在編集できません。レビューキューにバージョンがあります。 + no_permission: + other: 編集する権限がありません。 + user: + external_login_missing_user_id: + other: サードパーティのプラットフォームは一意のユーザーIDを提供していないため、ログインできません。ウェブサイト管理者にお問い合わせください。 + external_login_unbinding_forbidden: + other: ログインを削除する前に、アカウントのログインパスワードを設定してください。 + email_or_password_wrong: + other: + other: メールアドレスとパスワードが一致しません。 + not_found: + other: ユーザーが見つかりません。 + suspended: + other: このユーザーは凍結されています + username_invalid: + other: 無効なユーザー名です! + username_duplicate: + other: ユーザー名は既に使用されています! + set_avatar: + other: アバターを設定できませんでした + cannot_update_your_role: + other: ロールを変更できません + not_allowed_registration: + other: 現在、このサイトは新規登録を受け付けておりません + not_allowed_login_via_password: + other: 現在、このサイトはパスワードでログインできません + access_denied: + other: アクセスが拒否されました + page_access_denied: + other: このページへのアクセス権がありません + add_bulk_users_format_error: + other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "一度に追加するユーザーの数は、1 -{{.MaxAmount}} の範囲にする必要があります。" + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: configの読み込みに失敗しました + database: + connection_failed: + other: データベースの接続が失敗しました + create_table_failed: + other: テーブルの作成に失敗しました + install: + create_config_failed: + other: config.yaml を作成できません。 + upload: + unsupported_file_format: + other: サポートされていないファイル形式です。 + site_info: + config_not_found: + other: configが見つかりません。 + badge: + object_not_found: + other: バッジオブジェクトが見つかりません + reason: + spam: + name: + other: スパム + desc: + other: この投稿は広告です。現在のトピックには有用ではありません。 + rude_or_abusive: + name: + other: 誹謗中傷 + desc: + other: "合理的な人は、このコンテンツを尊重する言説には不適切と判断するでしょう。" + a_duplicate: + name: + other: 重複 + desc: + other: この質問は以前に質問されており、すでに回答があります。 + placeholder: + other: 既存の質問リンクを入力してください + not_a_answer: + name: + other: 回答では無い + desc: + other: "これは答えとして投稿されましたが、質問に答えようとしません。 それはおそらく編集、コメント、別の質問、または完全に削除されるべきです。" + no_longer_needed: + name: + other: 必要では無い + desc: + other: このコメントは古く、この投稿とは関係がありません。 + something: + name: + other: その他 + desc: + other: 上記以外の理由でスタッフの注意が必要です。 + placeholder: + other: あなたが懸念していることを私たちに教えてください + community_specific: + name: + other: コミュニティ固有の理由です + desc: + other: この質問はコミュニティガイドラインを満たしていません + not_clarity: + name: + other: 詳細や明快さが必要です + desc: + other: この質問には現在複数の質問が含まれています。1つの問題にのみ焦点を当てる必要があります。 + looks_ok: + name: + other: LGTM + desc: + other: この投稿はそのままで良く、改善する必要はありません! + needs_edit: + name: + other: 編集する必要があったため変更しました。 + desc: + other: 自分自身でこの投稿の問題を改善し修正します。 + needs_close: + name: + other: クローズする必要がある + desc: + other: クローズされた質問は回答できませんが、編集、投票、コメントはできます。 + needs_delete: + name: + other: 削除が必要です + desc: + other: この投稿は削除されました + question: + close: + duplicate: + name: + other: スパム + desc: + other: この質問は以前に質問されており、すでに回答があります。 + guideline: + name: + other: コミュニティ固有の理由です + desc: + other: この質問はコミュニティガイドラインを満たしていません + multiple: + name: + other: 詳細や明快さが必要です + desc: + other: この質問には現在複数の質問が含まれています。1つの問題にのみ焦点を当てる必要があります。 + other: + name: + other: その他 + desc: + other: 上記以外の理由でスタッフの注意が必要です。 + operation_type: + asked: + other: 質問済み + answered: + other: 回答済み + modified: + other: 修正済み + deleted_title: + other: 質問を削除 + questions_title: + other: 質問 + tag: + tags_title: + other: タグ + no_description: + other: タグには説明がありません。 + notification: + action: + update_question: + other: 質問を更新 + answer_the_question: + other: 回答済みの質問 + update_answer: + other: 回答を更新 + accept_answer: + other: 承認された回答 + comment_question: + other: コメントされた質問 + comment_answer: + other: コメントされた回答 + reply_to_you: + other: あなたへの返信 + mention_you: + other: メンションされました + your_question_is_closed: + other: あなたの質問はクローズされました + your_question_was_deleted: + other: あなたの質問は削除されました + your_answer_was_deleted: + other: あなたの質問は削除されました + your_comment_was_deleted: + other: あなたのコメントは削除されました + up_voted_question: + other: 質問を高評価 + down_voted_question: + other: 質問を低評価 + up_voted_answer: + other: 回答を高評価 + down_voted_answer: + other: 回答を低評価 + up_voted_comment: + other: コメントを高評価 + invited_you_to_answer: + other: あなたを回答に招待しました + earned_badge: + other: '"{{.BadgeName}}"バッジを獲得しました' + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] 新しいメールアドレスを確認してください" + body: + other: "{{.SiteName}}の新しいメールアドレスを確認しリンクをクリックしてください。
        \n{{.ChangeEmailUrl}}

        \n\n身に覚えがない場合はこのメールを無視してください。\n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。" + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} があなたの質問に回答しました" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \n{{.SiteName}}で確認

        \n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} があなたを回答に招待しました" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        あなたなら答えを知っているかもしれません。

        \n{{.SiteName}}で確認

        \n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。

        \n\n配信停止\n" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} があなたの投稿にコメントしました" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nで確認{{.SiteName}}

        \n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。

        \n\n配信停止" + new_question: + title: + other: "[{{.SiteName}}] 新しい質問: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] パスワードリセット" + body: + other: "{{.SiteName}}であなたのパスワードをリセットしようとしました。

        \n\nもしお心当たりがない場合は、このメールを無視してください。

        \n\n新しいパスワードを設定するには、以下のリンクをクリックしてください。
        \n{{.PassResetUrl}}\n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。

        \n" + register: + title: + other: "[{{.SiteName}}] 新しいアカウントを確認" + body: + other: "{{.SiteName}}へようこそ!

        \n\n以下のリンクをクリックして、新しいアカウントを確認・有効化してください。
        \n{{.RegisterUrl}}

        \n\n上記のリンクがクリックできない場合は、リンクをコピーしてブラウザのアドレスバーに貼り付けてみてください。\n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。

        " + test: + title: + other: "[{{.SiteName}}] テストメール" + body: + other: "これはテストメールです。\n

        \n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。

        " + action_activity_type: + upvote: + other: 高評価 + upvoted: + other: 高評価しました + downvote: + other: 低評価 + downvoted: + other: 低評価しました + accept: + other: 承認 + accepted: + other: 承認済み + edit: + other: 編集 + review: + queued_post: + other: キューに入れられた投稿 + flagged_post: + other: 投稿を通報 + suggested_post_edit: + other: 提案された編集 + reaction: + tooltip: + other: "{{ .Names }} と {{ .Count }} もっと..." + badge: + default_badges: + autobiographer: + name: + other: 自伝作家 + desc: + other: プロファイル 情報を入力しました。 + certified: + name: + other: 認定済み + desc: + other: 新しいユーザーがチュートリアルを完了しました。 + editor: + name: + other: 編集者 + desc: + other: 最初の投稿の編集 + first_flag: + name: + other: 初めての報告 + desc: + other: 初めての報告 + first_upvote: + name: + other: はじめての高評価 + desc: + other: はじめて投稿に高評価した + first_link: + name: + other: はじめてのリンク + desc: + other: First added a link to another post. + first_reaction: + name: + other: 初めてのリアクション + desc: + other: はじめて投稿にリアクションした + first_share: + name: + other: はじめての共有 + desc: + other: はじめて投稿を共有した + scholar: + name: + other: 研究生 + desc: + other: 質問をして回答が承認された + commentator: + name: + other: コメントマン + desc: + other: 5つコメントをした + new_user_of_the_month: + name: + other: 今月の新しいユーザー + desc: + other: 最初の月に優れた貢献 + read_guidelines: + name: + other: ガイドラインを読んだ + desc: + other: '「コミュニティガイドライン」をご覧ください。' + reader: + name: + other: リーダー + desc: + other: 10以上の回答を持つトピックのすべての回答を読んだ + welcome: + name: + other: ようこそ! + desc: + other: 高評価をされた + nice_share: + name: + other: Nice Share + desc: + other: 25人の訪問者と投稿を共有した + good_share: + name: + other: Good Share + desc: + other: 300の訪問者と投稿を共有した + great_share: + name: + other: Great Share + desc: + other: 1000人の訪問者と投稿を共有した + out_of_love: + name: + other: お隣さん + desc: + other: 1日に50票いれた + higher_love: + name: + other: お友達 + desc: + other: 5日目に50回投票した + crazy_in_love: + name: + other: 崇拝 + desc: + other: 一日に50回投票を20回した + promoter: + name: + other: プロモーター + desc: + other: ユーザーを招待した + campaigner: + name: + other: キャンペーン + desc: + other: 3人のベーシックユーザーを招待しました。 + champion: + name: + other: チャンピオン + desc: + other: 5人のメンバーを招待しました。 + thank_you: + name: + other: Thank you + desc: + other: 投稿が20件!投票数が10件! + gives_back: + name: + other: 返品 + desc: + other: 投稿が100件 !?!? 投票数が100件 !?!? + empathetic: + name: + other: 共感性 + desc: + other: 500の投稿を投票し、1000の投票を与えた。 + enthusiast: + name: + other: 楽天家 + desc: + other: 10日間連続ログイン + aficionado: + name: + other: Aficionado + desc: + other: 100日連続ログイン!!! + devotee: + name: + other: 献身者 + desc: + other: 365日連続訪問!!!!!!!! + anniversary: + name: + other: 周年記念 + desc: + other: 年に一回は... + appreciated: + name: + other: ありがとう! + desc: + other: 20件の投稿に1件の投票を受け取った + respected: + name: + other: 尊敬される + desc: + other: 100件の投稿で2件の投票を受け取った + admired: + name: + other: 崇拝された + desc: + other: 300の投稿に5票を獲得した + solved: + name: + other: 解決 + desc: + other: 答えを受け入れられた + guidance_counsellor: + name: + other: アドバイザー + desc: + other: 10個の回答が承認された + know_it_all: + name: + other: 物知り博士 + desc: + other: 50個の回答が承認された + solution_institution: + name: + other: 解決機関 + desc: + other: 150個の回答が承認された + nice_answer: + name: + other: 素敵な回答 + desc: + other: 回答スコアは10以上!! + good_answer: + name: + other: 良い回答 + desc: + other: 回答スコアは25以上!?! + great_answer: + name: + other: 素晴らしい回答 + desc: + other: 回答スコアは50以上!!!!1 + nice_question: + name: + other: ナイスな質問 + desc: + other: 質問スコアは10以上!! + good_question: + name: + other: よい質問 + desc: + other: 質問スコアは25以上!?! + great_question: + name: + other: 素晴らしい質問 + desc: + other: 50人の閲覧者!! + popular_question: + name: + other: 人気のある質問 + desc: + other: 500人の閲覧者!!! + notable_question: + name: + other: 注目すべき質問 + desc: + other: 1,000人の閲覧者!!!! + famous_question: + name: + other: 偉大な質問 + desc: + other: 5,000人の閲覧者!!!!! + popular_link: + name: + other: 人気のリンク + desc: + other: 外部リンクを50回クリック + hot_link: + name: + other: 激アツリンク + desc: + other: 外部リンクを300回クリック + famous_link: + name: + other: 有名なリンク + desc: + other: 外部リンクを100回クリック + default_badge_groups: + getting_started: + name: + other: はじめに + community: + name: + other: コミュニティ + posting: + name: + other: 投稿中 +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: 書式設定 + desc: \n + pagination: + prev: 前へ + next: 次へ + page_title: + question: 質問 + questions: 質問 + tag: タグ + tags: タグ + tag_wiki: タグ wiki + create_tag: タグを作成 + edit_tag: タグを編集 + ask_a_question: Create Question + edit_question: 質問を編集 + edit_answer: 回答を編集 + search: 検索 + posts_containing: 記事を含む投稿 + settings: 設定 + notifications: お知らせ + login: ログイン + sign_up: 新規登録 + account_recovery: アカウントの復旧 + account_activation: アカウント有効化 + confirm_email: メールアドレスを確認 + account_suspended: アカウントは凍結されています + admin: 管理者 + change_email: メールアドレスを変更 + install: 回答に応答する + upgrade: 回答を改善する + maintenance: ウェブサイトのメンテナンス + users: ユーザー + oauth_callback: 処理中 + http_404: HTTP エラー 404 + http_50X: HTTP エラー 500 + http_403: HTTP エラー 403 + logout: ログアウト + posts: Posts + notifications: + title: 通知 + inbox: 受信トレイ + achievement: 実績 + new_alerts: 新しい通知 + all_read: すべて既読にする + show_more: もっと見る + someone: 誰か + inbox_type: + all: すべて + posts: 投稿 + invites: 招待 + votes: 投票 + answer: 回答 + question: 質問 + badge_award: バッジ + suspended: + title: あなたのアカウントは停止されています。 + until_time: "あなたのアカウントは {{ time }} まで停止されました。" + forever: このユーザーは永久に停止されました。 + end: コミュニティガイドラインを満たしていません。 + contact_us: お問い合わせ + editor: + blockquote: + text: 引用 + bold: + text: 強い + chart: + text: チャート + flow_chart: フローチャート + sequence_diagram: シーケンス図 + class_diagram: クラス図 + state_diagram: 状態図 + entity_relationship_diagram: ER図 + user_defined_diagram: ユーザー定義図 + gantt_chart: ガントチャート + pie_chart: 円グラフ + code: + text: コードサンプル + add_code: コードサンプルを追加 + form: + fields: + code: + label: コード + msg: + empty: Code を空にすることはできません。 + language: + label: 言語 + placeholder: 自動検出 + btn_cancel: キャンセル + btn_confirm: 追加 + formula: + text: 数式 + options: + inline: インライン数式 + block: ブロック数式 + heading: + text: 見出し + options: + h1: 見出し1 + h2: 見出し2 + h3: 見出し3 + h4: 見出し4 + h5: 見出し5 + h6: 見出し6 + help: + text: ヘルプ + hr: + text: 水平方向の罫線 + image: + text: 画像 + add_image: 画像を追加する + tab_image: 画像をアップロードする + form_image: + fields: + file: + label: 画像ファイル + btn: 画像を選択する + msg: + empty: ファイルは空にできません。 + only_image: 画像ファイルのみが許可されています。 + max_size: ファイルサイズは {{size}} MBを超えることはできません。 + desc: + label: 説明 + tab_url: 画像URL + form_url: + fields: + url: + label: 画像URL + msg: + empty: 画像のURLは空にできません。 + name: + label: 説明 + btn_cancel: キャンセル + btn_confirm: 追加 + uploading: アップロード中 + indent: + text: インデント + outdent: + text: アウトデント + italic: + text: 斜体 + link: + text: ハイパーリンク + add_link: ハイパーリンクを追加 + form: + fields: + url: + label: URL + msg: + empty: URLを入力してください。 + name: + label: 説明 + btn_cancel: キャンセル + btn_confirm: 追加 + ordered_list: + text: 順序付きリスト + unordered_list: + text: 箇条書きリスト + table: + text: ' テーブル' + heading: 見出し + cell: セル + file: + text: ファイルを添付 + not_supported: "そのファイルタイプをサポートしていません。 {{file_type}} でもう一度お試しください。" + max_size: "添付ファイルサイズは {{size}} MB を超えることはできません。" + close_modal: + title: この投稿を次のように閉じます... + btn_cancel: キャンセル + btn_submit: 送信 + remark: + empty: 入力してください。 + msg: + empty: 理由を選んでください。 + report_modal: + flag_title: この投稿を報告するフラグを立てています... + close_title: この投稿を次のように閉じます... + review_question_title: 質問の編集をレビュー + review_answer_title: 答えをレビューする + review_comment_title: レビューコメント + btn_cancel: キャンセル + btn_submit: 送信 + remark: + empty: 入力してください。 + msg: + empty: 理由を選んでください。 + not_a_url: URL形式が正しくありません。 + url_not_match: URL の原点が現在のウェブサイトと一致しません。 + tag_modal: + title: 新しいタグを作成 + form: + fields: + display_name: + label: 表示名 + msg: + empty: 表示名を入力してください。 + range: 表示名は最大 35 文字までです。 + slug_name: + label: URLスラッグ + desc: '文字セット「a-z」、「0-9」、「+ # -」を使用する必要があります。' + msg: + empty: URL スラッグを空にすることはできません。 + range: タイトルは最大35文字までです. + character: URL スラグに許可されていない文字セットが含まれています。 + desc: + label: 説明 + revision: + label: 修正 + edit_summary: + label: 概要を編集 + placeholder: >- + 簡単にあなたの変更を説明します(修正スペル、固定文法、改善されたフォーマット) + btn_cancel: キャンセル + btn_submit: 送信 + btn_post: 新しいタグを投稿 + tag_info: + created_at: 作成 + edited_at: 編集済 + history: 履歴 + synonyms: + title: 類義語 + text: 次のタグが再マップされます + empty: 同義語は見つかりません。 + btn_add: 同義語を追加 + btn_edit: 編集 + btn_save: 保存 + synonyms_text: 次のタグが再マップされます + delete: + title: このタグを削除 + tip_with_posts: >- +

        同義語でタグを削除することはできません。

        最初にこのタグから同義語を削除してください。

        + tip_with_synonyms: >- +

        同義語でタグを削除することはできません。

        最初にこのタグから同義語を削除してください。

        + tip: 本当に削除してもよろしいですか? + close: クローズ + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: タグを編集 + default_reason: タグを編集 + default_first_reason: タグを追加 + btn_save_edits: 編集を保存 + btn_cancel: キャンセル + dates: + long_date: MMM D + long_date_with_year: "YYYY年MM月D日" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: 今 + x_seconds_ago: "{{count}}秒前" + x_minutes_ago: "{{count}}分前" + x_hours_ago: "{{count}}時間前" + hour: 時 + day: 日 + hours: 時 + days: 日 + month: month + months: months + year: year + reaction: + heart: ハート + smile: 笑顔 + frown: 眉をひそめる + btn_label: リアクションの追加または削除 + undo_emoji: '{{ emoji }} のリアクションを元に戻す' + react_emoji: '{{ emoji }} に反応する' + unreact_emoji: '{{ emoji }} に反応しない' + comment: + btn_add_comment: コメントを追加 + reply_to: 返信: + btn_reply: 返信 + btn_edit: 編集 + btn_delete: 削除 + btn_flag: フラグ + btn_save_edits: 編集内容を保存 + btn_cancel: キャンセル + show_more: "{{count}} 件のその他のコメント" + tip_question: >- + コメントを使用して、より多くの情報を求めたり、改善を提案したりします。コメントで質問に答えることは避けてください。 + tip_answer: >- + コメントを使用して他のユーザーに返信したり、変更を通知します。新しい情報を追加する場合は、コメントの代わりに投稿を編集します。 + tip_vote: 投稿に役に立つものを追加します + edit_answer: + title: 回答を編集 + default_reason: 回答を編集 + default_first_reason: 回答を追加 + form: + fields: + revision: + label: 修正 + answer: + label: 回答 + feedback: + characters: コンテンツは6文字以上でなければなりません。 + edit_summary: + label: 概要を編集 + placeholder: >- + 簡単にあなたの変更を説明します(修正スペル、固定文法、改善されたフォーマット) + btn_save_edits: 編集を保存 + btn_cancel: キャンセル + tags: + title: タグ + sort_buttons: + popular: 人気 + name: 名前 + newest: 最新 + button_follow: フォロー + button_following: フォロー中 + tag_label: 質問 + search_placeholder: タグ名でフィルタ + no_desc: タグには説明がありません。 + more: もっと見る + wiki: Wiki + ask: + title: Create Question + edit_title: 質問を編集 + default_reason: 質問を編集 + default_first_reason: Create question + similar_questions: 類似の質問 + form: + fields: + revision: + label: 修正 + title: + label: タイトル + placeholder: What's your topic? Be specific. + msg: + empty: タイトルを空にすることはできません。 + range: タイトルは最大150文字までです + body: + label: 本文 + msg: + empty: 本文を空にすることはできません。 + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: タグ + msg: + empty: 少なくとも一つ以上のタグが必要です。 + answer: + label: 回答 + msg: + empty: 回答は空欄にできません + edit_summary: + label: 概要を編集 + placeholder: >- + 簡単にあなたの変更を説明します(修正スペル、固定文法、改善されたフォーマット) + btn_post_question: 質問を投稿する + btn_save_edits: 編集内容を保存 + answer_question: ご自身の質問に答えてください + post_question&answer: 質問と回答を投稿する + tag_selector: + add_btn: タグを追加 + create_btn: 新しタグを作成 + search_tag: タグを検索 + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: 一致するタグはありません + tag_required_text: 必須タグ (少なくとも 1 つ) + header: + nav: + question: 質問 + tag: タグ + user: ユーザー + badges: バッジ + profile: プロフィール + setting: 設定 + logout: ログアウト + admin: 管理者 + review: レビュー + bookmark: ブックマーク + moderation: モデレーション + search: + placeholder: 検索 + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: 変更 + loading: 読み込み中… + pic_auth_code: + title: CAPTCHA + placeholder: 上記のテキストを入力してください + msg: + empty: Code を空にすることはできません。 + inactive: + first: >- + {{mail}}にアクティベーションメールを送信しました。メールの指示に従ってアカウントをアクティベーションしてください。 + info: "届かない場合は、迷惑メールフォルダを確認してください。" + another: >- + {{mail}}に別のアクティベーションメールを送信しました。 到着には数分かかる場合があります。スパムフォルダを確認してください。 + btn_name: 認証メールを再送信 + change_btn_name: メールアドレスを変更 + msg: + empty: 空にすることはできません + resend_email: + url_label: 本当に認証メールを再送信してもよろしいですか? + url_text: ユーザーに上記のアクティベーションリンクを渡すこともできます。 + login: + login_to_continue: ログインして続行 + info_sign: アカウントをお持ちではありませんか?<1>サインアップ + info_login: すでにアカウントをお持ちですか?<1>ログイン + agreements: 登録することにより、<1>プライバシーポリシーおよび<3>サービス規約に同意するものとします。 + forgot_pass: パスワードをお忘れですか? + name: + label: 名前 + msg: + empty: 名前を空にすることはできません。 + range: 2~30文字の名前を設定してください。 + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: メールアドレス + msg: + empty: メールアドレスを入力してください。 + password: + label: パスワード + msg: + empty: パスワードを入力してください。 + different: 入力されたパスワードが一致しません + account_forgot: + page_title: パスワードを忘れた方はこちら + btn_name: 回復用のメールを送る + send_success: >- + アカウントが {{mail}}と一致する場合は、パスワードをすぐにリセットする方法に関するメールが送信されます。 + email: + label: メールアドレス + msg: + empty: メールアドレスを入力してください。 + change_email: + btn_cancel: キャンセル + btn_update: メールアドレスを更新 + send_success: >- + アカウントが {{mail}}と一致する場合は、パスワードをすぐにリセットする方法に関するメールが送信されます。 + email: + label: 新しいメールアドレス + msg: + empty: メールアドレス欄を空白にしておくことはできません + oauth: + connect: '{{ auth_name }} と接続' + remove: '{{ auth_name }} を削除' + oauth_bind_email: + subtitle: アカウントに回復用のメールアドレスを追加します。 + btn_update: メールアドレスを更新 + email: + label: メールアドレス + msg: + empty: メールアドレスは空にできません。 + modal_title: このメールアドレスはすでに存在しています。 + modal_content: このメールアドレスは既に登録されています。既存のアカウントに接続してもよろしいですか? + modal_cancel: メールアドレスを変更する + modal_confirm: 既存のアカウントに接続 + password_reset: + page_title: パスワード再設定 + btn_name: パスワードをリセット + reset_success: >- + パスワードを変更しました。ログインページにリダイレクトされます。 + link_invalid: >- + 申し訳ありませんが、このパスワードリセットのリンクは無効になりました。パスワードが既にリセットされている可能性がありますか? + to_login: ログインページへ + password: + label: パスワード + msg: + empty: パスワードを入力してください。 + length: 長さは 8 から 32 の間である必要があります + different: 両側に入力されたパスワードが一致しません + password_confirm: + label: 新しいパスワードの確認 + settings: + page_title: 設定 + goto_modify: 変更を開く + nav: + profile: プロフィール + notification: お知らせ + account: アカウント + interface: 外観 + profile: + heading: プロフィール + btn_name: 保存 + display_name: + label: 表示名 + msg: 表示名は必須です。 + msg_range: Display name must be 2-30 characters in length. + username: + label: ユーザー名 + caption: ユーザーは "@username" としてあなたをメンションできます。 + msg: ユーザー名は空にできません。 + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: プロフィール画像 + gravatar: Gravatar + gravatar_text: 画像を変更できます: + custom: カスタム + custom_text: 画像をアップロードできます。 + default: システム + msg: アバターをアップロードしてください + bio: + label: 自己紹介 + website: + label: ウェブサイト + placeholder: "http://example.com" + msg: ウェブサイトの形式が正しくありません + location: + label: ロケーション + placeholder: "都道府県,国" + notification: + heading: メール通知 + turn_on: ONにする + inbox: + label: 受信トレイの通知 + description: 質問、コメント、招待状などへの回答。 + all_new_question: + label: すべての新規質問 + description: すべての新しい質問の通知を受け取ります。週に最大50問まで。 + all_new_question_for_following_tags: + label: 以下のタグに対するすべての新しい質問 + description: タグをフォローするための新しい質問の通知を受け取る。 + account: + heading: アカウント + change_email_btn: メールアドレスを変更する + change_pass_btn: パスワードを変更する + change_email_info: >- + このアドレスにメールを送信しました。メールの指示に従って確認処理を行ってください。 + email: + label: メールアドレス + new_email: + label: 新しいメールアドレス + msg: 新しいメールアドレスは空にできません。 + pass: + label: 現在のパスワード + msg: パスワードは空白にできません + password_title: パスワード + current_pass: + label: 現在のパスワード + msg: + empty: 現在のパスワードが空欄です + length: 長さは 8 から 32 の間である必要があります. + different: パスワードが一致しません。 + new_pass: + label: 新しいパスワード + pass_confirm: + label: 新しいパスワードの確認 + interface: + heading: 外観 + lang: + label: インタフェース言語 + text: ユーザーインターフェイスの言語。ページを更新すると変更されます。 + my_logins: + title: ログイン情報 + label: これらのアカウントを使用してログインまたはこのサイトでサインアップします。 + modal_title: ログイン情報を削除 + modal_content: このログイン情報をアカウントから削除してもよろしいですか? + modal_confirm_btn: 削除 + remove_success: 削除に成功しました + toast: + update: 更新に成功しました + update_password: パスワードの変更に成功しました。 + flag_success: フラグを付けてくれてありがとう + forbidden_operate_self: 自分自身で操作することはできません + review: レビュー後にあなたのリビジョンが表示されます。 + sent_success: 正常に送信されました。 + related_question: + title: Related + answers: 回答 + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: People Asked + desc: Select people who you think might know the answer. + invite: 回答に招待する + add: ユーザーを追加 + search: ユーザーを検索 + question_detail: + action: 動作 + created: Created + Asked: 質問済み + asked: 質問済み + update: 修正済み + Edited: Edited + edit: 編集済み + commented: コメントしました + Views: 閲覧回数 + Follow: フォロー + Following: フォロー中 + follow_tip: この質問をフォローして通知を受け取る + answered: 回答済み + closed_in: クローズまで + show_exist: 既存の質問を表示します + useful: 役に立った + question_useful: それは有用で明確です。 + question_un_useful: 不明確または有用ではない + question_bookmark: この質問をブックマークする + answer_useful: 役に立った + answer_un_useful: 役に立たない + answers: + title: 回答 + score: スコア + newest: 最新 + oldest: 古い順 + btn_accept: 承認 + btn_accepted: 承認済み + write_answer: + title: あなたの回答 + edit_answer: 既存の回答を編集する + btn_name: 回答を投稿する + add_another_answer: 別の回答を追加 + confirm_title: 回答を続ける + continue: 続行 + confirm_info: >- +

        本当に別の答えを追加したいのですか?

        代わりに、編集リンクを使って既存の答えを洗練させ、改善することができます。

        + empty: 回答は空欄にできません + characters: コンテンツは6文字以上でなければなりません。 + tips: + header_1: ご回答ありがとうございます。 + li1_1: " 必ず質問に答えてください。詳細を述べ、あなたの研究を共有してください。\n" + li1_2: 参考文献や個人的な経験による裏付けを取ること。. + header_2: しかし、 を避けてください... + li2_1: 助けを求める、説明を求める、または他の答えに応答する。 + reopen: + confirm_btn: 再オープン + title: この投稿を再度開く + content: 再オープンしてもよろしいですか? + list: + confirm_btn: 一覧 + title: この投稿の一覧 + content: 一覧表示してもよろしいですか? + unlist: + confirm_btn: 限定公開にする + title: この投稿を元に戻す + content: 本当に元に戻しますか? + pin: + title: この投稿をピン留めする + content: "グローバルに固定してもよろしいですか?\nこの投稿はすべての投稿リストの上部に表示されます。" + confirm_btn: ピン留めする + delete: + title: この投稿を削除 + question: >- +

        承認された回答を削除することはお勧めしません。削除すると、今後の読者がこの知識を得られなくなってしまうからです。

        承認された回答を繰り返し削除すると、回答機能が制限され、アカウントがブロックされる場合があります。本当に削除しますか? + + answer_accepted: >- +

        承認された回答を削除することはお勧めしません。削除すると、今後の読者がこの知識を得られなくなってしまうからです。

        承認された回答を繰り返し削除すると、回答機能が制限され、アカウントがブロックされる場合があります。本当に削除しますか? + + other: 本当に削除してもよろしいですか? + tip_answer_deleted: この回答は削除されました + undelete_title: この投稿を元に戻す + undelete_desc: 本当に元に戻しますか? + btns: + confirm: 確認 + cancel: キャンセル + edit: 編集 + save: 保存 + delete: 削除 + undelete: 元に戻す + list: 限定公開を解除する + unlist: 限定公開にする + unlisted: 限定公開済み + login: ログイン + signup: 新規登録 + logout: ログアウト + verify: 認証 + create: Create + approve: 承認 + reject: 却下 + skip: スキップする + discard_draft: 下書きを破棄 + pinned: ピン留めしました + all: すべて + question: 質問 + answer: 回答 + comment: コメント + refresh: 更新 + resend: 再送 + deactivate: 無効化する + active: 有効 + suspend: 凍結 + unsuspend: 凍結解除 + close: クローズ + reopen: 再オープン + ok: OK + light: ライト + dark: ダーク + system_setting: システム設定 + default: 既定 + reset: リセット + tag: タグ + post_lowercase: 投稿 + filter: フィルター + ignore: 除外 + submit: 送信 + normal: 通常 + closed: クローズ済み + deleted: 削除済み + deleted_permanently: Deleted permanently + pending: 処理待ち + more: もっと見る + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: 検索結果 + keywords: キーワード + options: オプション + follow: フォロー + following: フォロー中 + counts: "結果:{{count}}" + counts_loading: "... Results" + more: もっと見る + sort_btns: + relevance: 関連性 + newest: 最新 + active: アクティブ + score: スコア + more: もっと見る + tips: + title: 詳細検索のヒント + tag: "<1>[tag] タグで検索" + user: "<1>ユーザー:ユーザー名作成者による検索" + answer: "<1>回答:0未回答の質問" + score: "<1>スコア:33以上のスコアを持つ投稿" + question: "<1>質問質問を検索" + is_answer: "<1>は答え答えを検索" + empty: 何も見つかりませんでした。
        別のキーワードまたはそれ以下の特定のキーワードをお試しください。 + share: + name: シェア + copy: リンクをコピー + via: 投稿を共有... + copied: コピーしました + facebook: Facebookで共有 + twitter: Share to X + cannot_vote_for_self: 自分の投稿には投票できません。 + modal_confirm: + title: エラー... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: 新しいアカウントが確認されました。ホームページにリダイレクトされます。 + link: ホームページへ + oops: おっと! + invalid: 使用したリンクは機能しません。 + confirm_new_email: メールアドレスが更新されました。 + confirm_new_email_invalid: >- + 申し訳ありませんが、この確認リンクは無効です。メールアドレスが既に変更されている可能性があります。 + unsubscribe: + page_title: 購読解除 + success_title: 購読解除成功 + success_desc: 配信リストから削除され、その他のメールの送信が停止されました。 + link: 設定の変更 + question: + following_tags: フォロー中のタグ + edit: 編集 + save: 保存 + follow_tag_tip: タグに従って質問のリストをキュレートします。 + hot_questions: ホットな質問 + all_questions: すべての質問 + x_questions: "{{ count }} の質問" + x_answers: "{{ count }} の回答" + x_posts: "{{ count }} Posts" + questions: 質問 + answers: 回答 + newest: 最新 + active: 有効 + hot: 人気 + frequent: Frequent + recommend: おすすめ + score: スコア + unanswered: 未回答 + modified: 修正済み + answered: 回答済み + asked: 質問済み + closed: 解決済み + follow_a_tag: タグをフォロー + more: その他 + personal: + overview: 概要 + answers: 回答 + answer: 回答 + questions: 質問 + question: 質問 + bookmarks: ブックマーク + reputation: 評判 + comments: コメント + votes: 投票 + badges: バッジ + newest: 最新 + score: スコア + edit_profile: プロファイルを編集 + visited_x_days: "{{ count }}人の閲覧者" + viewed: 閲覧回数 + joined: 参加しました + comma: "," + last_login: 閲覧数 + about_me: 自己紹介 + about_me_empty: "// Hello, World !" + top_answers: よくある回答 + top_questions: よくある質問 + stats: 統計情報 + list_empty: 投稿が見つかりませんでした。
        他のタブを選択しますか? + content_empty: 投稿が見つかりませんでした。 + accepted: 承認済み + answered: 回答済み + asked: 質問済み + downvoted: 低評価しました + mod_short: MOD + mod_long: モデレーター + x_reputation: 評価 + x_votes: 投票を受け取りました + x_answers: 回答 + x_questions: 質問 + recent_badges: 最近のバッジ + install: + title: Installation + next: 次へ + done: 完了 + config_yaml_error: config.yaml を作成できません。 + lang: + label: 言語を選択してください + db_type: + label: データベースエンジン + db_username: + label: ユーザー名 + placeholder: root + msg: ユーザー名は空にできません。 + db_password: + label: パスワード + placeholder: root + msg: パスワードを入力してください。 + db_host: + label: データベースのホスト。 + placeholder: "db:3306" + msg: データベースホストは空にできません。 + db_name: + label: データベース名 + placeholder: 回答 + msg: データベース名を空にすることはできません。 + db_file: + label: データベースファイル + placeholder: /data/answer.db + msg: データベースファイルは空にできません。 + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: config.yamlを作成 + label: config.yaml ファイルが作成されました。 + desc: >- + <1>/var/www/xxx/ディレクトリに<1>config.yamlファイルを手動で作成し、その中に次のテキストを貼り付けます。 + info: 完了したら、「次へ」ボタンをクリックします。 + site_information: サイト情報 + admin_account: 管理者アカウント + site_name: + label: サイト名: + msg: サイト名は空にできません. + msg_max_length: サイト名は最大30文字でなければなりません。 + site_url: + label: サイトURL + text: あなたのサイトのアドレス + msg: + empty: サイト URL は空にできません. + incorrect: サイトURLの形式が正しくありません。 + max_length: サイトのURLは最大512文字でなければなりません + contact_email: + label: 連絡先メール アドレス + text: このサイトを担当するキーコンタクトのメールアドレスです。 + msg: + empty: 連絡先メールアドレスを空にすることはできません。 + incorrect: 連絡先メールアドレスの形式が正しくありません。 + login_required: + label: 非公開 + switch: ログインが必要です + text: ログインしているユーザーのみがこのコミュニティにアクセスできます。 + admin_name: + label: 名前 + msg: 名前を空にすることはできません。 + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: パスワード + text: >- + ログインするにはこのパスワードが必要です。安全な場所に保存してください。 + msg: パスワードは空白にできません + msg_min_length: パスワードは8文字以上でなければなりません。 + msg_max_length: パスワードは最大 32 文字でなければなりません。 + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: メールアドレス + text: ログインするにはこのメールアドレスが必要です。 + msg: + empty: メールアドレスは空にできません。 + incorrect: メールアドレスの形式が正しくありません. + ready_title: サイトの準備ができました + ready_desc: >- + もっと設定を変更したいと思ったことがある場合は、<1>管理者セクションをご覧ください。サイトメニューで見つけてください。 + good_luck: "楽しんで、幸運を!" + warn_title: 警告 + warn_desc: >- + ファイル<1>config.yamlは既に存在します。このファイルのいずれかの設定アイテムをリセットする必要がある場合は、最初に削除してください。 + install_now: <1>今すぐインストールを試してみてください。 + installed: 既にインストール済みです + installed_desc: >- + 既にインストールされているようです。再インストールするには、最初に古いデータベーステーブルをクリアしてください。 + db_failed: データベースの接続が失敗しました + db_failed_desc: >- + これは、<1>設定内のデータベース情報を意味します。 amlファイルが正しくないか、データベースサーバーとの連絡先が確立できませんでした。ホストのデータベースサーバーがダウンしている可能性があります。 + counts: + views: ビュー + votes: 投票数 + answers: 回答 + accepted: 承認済み + page_error: + http_error: HTTP Error {{ code }} + desc_403: このページにアクセスする権限がありません。 + desc_404: 残念ながら、このページは存在しません。 + desc_50X: サーバーにエラーが発生し、リクエストを完了できませんでした。 + back_home: ホームページに戻ります + page_maintenance: + desc: "メンテナンス中です。まもなく戻ります。" + nav_menus: + dashboard: ダッシュボード + contents: コンテンツ + questions: 質問 + answers: 回答 + users: ユーザー + badges: バッジ + flags: フラグ + settings: 設定 + general: 一般 + interface: 外観 + smtp: SMTP + branding: ブランディング + legal: 法的事項 + write: 書き + terms: Terms + tos: 利用規約 + privacy: プライバシー + seo: SEO + customize: カスタマイズ + themes: テーマ + login: ログイン + privileges: 特典 + plugins: プラグイン + installed_plugins: 使用中のプラグイン + apperance: Appearance + website_welcome: '{{site_name}} へようこそ' + user_center: + login: ログイン + qrcode_login_tip: QRコードをスキャンしてログインするには {{ agentName }} を使用してください。 + login_failed_email_tip: ログインに失敗しました。もう一度やり直す前に、このアプリがあなたのメール情報にアクセスすることを許可してください。 + badges: + modal: + title: お疲れ様でした! + content: 新しいバッジを獲得しました。 + close: クローズ + confirm: バッジを表示 + title: バッジ + awarded: 受賞済み + earned_×: 獲得×{{ number }} + ×_awarded: "{{ number }} 受賞" + can_earn_multiple: これを複数回獲得できます。 + earned: 獲得済み + admin: + admin_header: + title: 管理者 + dashboard: + title: ダッシュボード + welcome: Adminへようこそ! + site_statistics: サイト統計 + questions: "質問:" + resolved: "解決済み:" + unanswered: "未回答:" + answers: "回答:" + comments: "評論:" + votes: "投票:" + users: "ユーザー数:" + flags: "フラグ:" + reviews: "レビュー:" + site_health: サイトの状態 + version: "バージョン:" + https: "HTTPS:" + upload_folder: "フォルダを上げる" + run_mode: "実行中モード:" + private: 非公開 + public: 公開 + smtp: "SMTP:" + timezone: "Timezone:" + system_info: システム情報 + go_version: "バージョン:" + database: "データベース:" + database_size: "データベースのサイズ:" + storage_used: "使用されているストレージ" + uptime: "稼働時間:" + links: リンク + plugins: プラグイン + github: GitHub + blog: ブログ + contact: 連絡先 + forum: Forum + documents: ドキュメント + feedback: フィードバック + support: サポート + review: レビュー + config: 設定 + update_to: 更新日時 + latest: 最新 + check_failed: チェックに失敗しました + "yes": "はい" + "no": "いいえ" + not_allowed: 許可されていません + allowed: 許可 + enabled: 有効 + disabled: 無効 + writable: 書き込み可 + not_writable: 書き込み不可 + flags: + title: フラグ + pending: 処理待ち + completed: 完了済 + flagged: フラグ付き + flagged_type: フラグを立てた {{ type }} + created: 作成 + action: 動作 + review: レビュー + user_role_modal: + title: ユーザーロールを変更... + btn_cancel: キャンセル + btn_submit: 送信 + new_password_modal: + title: 新しいパスワードを設定 + form: + fields: + password: + label: パスワード + text: ユーザーはログアウトされ、再度ログインする必要があります。 + msg: パスワードの長さは 8 ~ 32 文字である必要があります。 + btn_cancel: キャンセル + btn_submit: 送信 + edit_profile_modal: + title: プロファイルを編集 + form: + fields: + display_name: + label: 表示名 + msg_range: Display name must be 2-30 characters in length. + username: + label: ユーザー名 + msg_range: Username must be 2-30 characters in length. + email: + label: メールアドレス + msg_invalid: 無効なメールアドレス + edit_success: 更新が成功しました + btn_cancel: キャンセル + btn_submit: 送信 + user_modal: + title: 新しいユーザーを追加 + form: + fields: + users: + label: ユーザーを一括追加 + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: '「名前、メールアドレス、パスワード」をカンマで区切ってください。' + msg: "ユーザーのメールアドレスを1行に1つ入力してください。" + display_name: + label: 表示名 + msg: 表示名の長さは 2 ~ 30 文字にする必要があります。 + email: + label: メールアドレス + msg: メールアドレスが無効です。 + password: + label: パスワード + msg: パスワードの長さは 8 ~ 32 文字である必要があります。 + btn_cancel: キャンセル + btn_submit: 送信 + users: + title: ユーザー + name: 名前 + email: メールアドレス + reputation: 評価 + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: ステータス + role: ロール + action: 操作 + change: 変更 + all: すべて + staff: スタッフ + more: もっと見る + inactive: 非アクティブ + suspended: 凍結済み + deleted: 削除済み + normal: 通常 + Moderator: モデレーター + Admin: 管理者 + User: ユーザー + filter: + placeholder: "ユーザー名でフィルタ" + set_new_password: 新しいパスワードを設定します。 + edit_profile: プロファイルを編集 + change_status: ステータスを変更 + change_role: ロールを変更 + show_logs: ログを表示 + add_user: ユーザを追加 + deactivate_user: + title: ユーザーを非アクティブにする + content: アクティブでないユーザーはメールアドレスを再認証する必要があります。 + delete_user: + title: このユーザの削除 + content: このユーザーを削除してもよろしいですか?これは永久的です! + remove: このコンテンツを削除 + label: すべての質問、回答、コメントなどを削除 + text: ユーザーのアカウントのみ削除したい場合は、これを確認しないでください。 + suspend_user: + title: ユーザーをサスペンドにする + content: 一時停止中のユーザーはログインできません。 + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: 質問 + unlisted: 限定公開済み + post: 投稿 + votes: 投票 + answers: 回答 + created: 作成 + status: ステータス + action: 動作 + change: 変更 + pending: 処理待ち + filter: + placeholder: "タイトル、質問:id でフィルター" + answers: + page_title: 回答 + post: 投稿 + votes: 投票 + created: 作成 + status: ステータス + action: 操作 + change: 変更 + filter: + placeholder: "タイトル、質問:id でフィルター" + general: + page_title: 一般 + name: + label: サイト名 + msg: サイト名は空にできません. + text: "タイトルタグで使用されるこのサイトの名前。" + site_url: + label: サイトURL + msg: サイト URL は空にできません. + validate: 正しいURLを入力してください。 + text: あなたのサイトのアドレス + short_desc: + label: 短いサイトの説明 + msg: 短いサイト説明は空にできません. + text: "ホームページのタイトルタグで使用されている簡単な説明。" + desc: + label: サイトの説明 + msg: サイト説明を空にすることはできません。 + text: "メタ説明タグで使用されるように、このサイトを1つの文で説明します。" + contact_email: + label: 連絡先メール アドレス + msg: 連絡先メールアドレスを空にすることはできません。 + validate: 連絡先のメールアドレスが無効です。 + text: このサイトを担当するキーコンタクトのメールアドレスです。 + check_update: + label: ソフトウェアアップデート + text: 自動的に更新を確認 + interface: + page_title: 外観 + language: + label: インタフェース言語 + msg: インターフェース言語は空にできません。 + text: ユーザーインターフェイスの言語。ページを更新すると変更されます。 + time_zone: + label: タイムゾーン + msg: タイムゾーンを空にすることはできません。 + text: あなたのタイムゾーンを選択してください。 + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: 差出人 + msg: 差出人メールアドレスは空にできません。 + text: 送信元のメールアドレス + from_name: + label: 差出人名 + msg: 差出人名は空にできません + text: メールの送信元の名前 + smtp_host: + label: SMTP ホスト + msg: SMTPホストは空にできません。 + text: メールサーバー + encryption: + label: 暗号化 + msg: 暗号化は空にできません。 + text: ほとんどのサーバではSSLが推奨されます。 + ssl: SSL + tls: TLS + none: なし + smtp_port: + label: SMTPポート + msg: SMTPポートは1〜65535でなければなりません。 + text: メールサーバーへのポート番号 + smtp_username: + label: SMTPユーザ名 + msg: SMTP ユーザー名を空にすることはできません。 + smtp_password: + label: SMTPパスワード + msg: SMTP パスワードを入力してください。 + test_email_recipient: + label: テストメールの受信者 + text: テスト送信を受信するメールアドレスを入力してください。 + msg: テストメールの受信者が無効です + smtp_authentication: + label: 認証を有効にする + title: SMTP認証 + msg: SMTP認証は空にできません。 + "yes": "はい" + "no": "いいえ" + branding: + page_title: ブランディング + logo: + label: ロゴ + msg: ロゴは空にできません。 + text: あなたのサイトの左上にあるロゴ画像。 高さが56、アスペクト比が3:1を超える広い矩形画像を使用します。 空白の場合、サイトタイトルテキストが表示されます。 + mobile_logo: + label: モバイルロゴ + text: サイトのモバイル版で使用されるロゴです。高さが56の横長の長方形の画像を使用してください。空白のままにすると、"ロゴ"設定の画像が使用されます。 + square_icon: + label: アイコン画像 + msg: アイコン画像は空にできません。 + text: メタデータアイコンのベースとして使用される画像。理想的には512x512より大きくなければなりません。 + favicon: + label: Favicon + text: あなたのサイトのファビコン。CDN上で正しく動作するにはpngである必要があります。 32x32にリサイズされます。空白の場合は、"正方形のアイコン"が使用されます。 + legal: + page_title: 法的情報 + terms_of_service: + label: 利用規約 + text: "ここで利用規約のサービスコンテンツを追加できます。すでに他の場所でホストされているドキュメントがある場合は、こちらにフルURLを入力してください。" + privacy_policy: + label: プライバシーポリシー + text: "ここにプライバシーポリシーの内容を追加できます。すでに他の場所でホストされているドキュメントを持っている場合は、こちらにフルURLを入力してください。" + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: 編集 + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: 回答を書く + label: 各ユーザーは同じ質問に対して1つの回答しか書けません + text: "ユーザが同じ質問に複数の回答を書き込めるようにするにはオフにします。これにより回答がフォーカスされていない可能性があります。" + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: おすすめタグ + text: "デフォルトでドロップダウンリストに推奨タグが表示されます。" + msg: + contain_reserved: "推奨されるタグは予約済みタグを含めることはできません" + required_tag: + title: 必須タグを設定 + label: 必須タグに「推奨タグ」を設定 + text: "新しい質問には少なくとも1つの推奨タグが必要です。" + reserved_tags: + label: 予約済みタグ + text: "予約済みのタグはモデレータのみ使用できます。" + image_size: + label: 画像ファイルの最大サイズ(MB) + text: "画像ファイルの最大アップロードサイズ。" + attachment_size: + label: 添付ファイルの最大サイズ (MB) + text: "添付ファイルの最大アップロードサイズ。" + image_megapixels: + label: 画像の最大解像度 + text: "画像ファイルに許可する最大メガピクセル数。" + image_extensions: + label: 認可された画像ファイルの拡張子 + text: "イメージ表示に許可されるファイル拡張子のリスト(コンマで区切り)" + attachment_extensions: + label: 認可された添付ファイルの拡張子 + text: "アップロードを許可するファイル拡張子のリスト(カンマ区切り)\n警告: アップロードを許可するとセキュリティ上の問題が発生する可能性があります。" + seo: + page_title: SEO + permalink: + label: 固定リンク + text: カスタム URL 構造は、ユーザビリティとリンクの前方互換性を向上させることができます。 + robots: + label: robots.txt + text: これにより、関連するサイト設定が永久に上書きされます。 + themes: + page_title: テーマ + themes: + label: テーマ + text: 既存のテーマを選択してください + color_scheme: + label: 配色 + navbar_style: + label: Navbar background style + primary_color: + label: メインカラー + text: テーマで使用される色を変更する + css_and_html: + page_title: CSS と HTML + custom_css: + label: カスタム CSS + text: > + + head: + label: ヘッド + text: > + + header: + label: ヘッダー + text: > + + footer: + label: フッター + text: これは </body> の前に挿入されます。 + sidebar: + label: サイドバー + text: サイドバーに挿入されます。 + login: + page_title: ログイン + membership: + title: メンバー + label: 新しい登録を許可する + text: 誰もが新しいアカウントを作成できないようにするには、オフにしてください。 + email_registration: + title: メールアドレスの登録 + label: メールアドレスの登録を許可 + text: オフにすると、メールで新しいアカウントを作成できなくなります。 + allowed_email_domains: + title: 許可されたメールドメイン + text: ユーザーがアカウントを登録する必要があるメールドメインです。1行に1つのドメインがあります。空の場合は無視されます。 + private: + title: 非公開 + label: ログインが必要です + text: ログインしているユーザーのみがこのコミュニティにアクセスできます。 + password_login: + title: パスワードログイン + label: メールアドレスとパスワードのログインを許可する + text: "警告: オフにすると、他のログイン方法を設定していない場合はログインできない可能性があります。" + installed_plugins: + title: インストール済みプラグイン + plugin_link: プラグインは機能を拡張します。<1>プラグインリポジトリにプラグインがあります。 + filter: + all: すべて + active: アクティブ + inactive: 非アクティブ + outdated: 期限切れ + plugins: + label: プラグイン + text: 既存のプラグインを選択します + name: 名前 + version: バージョン + status: ステータス + action: 操作 + deactivate: 非アクティブ化 + activate: アクティベート + settings: 設定 + settings_users: + title: ユーザー + avatar: + label: デフォルトのアバター + text: 自分のカスタムアバターのないユーザー向け。 + gravatar_base_url: + label: Gravatar Base URL + text: GravatarプロバイダーのAPIベースのURL。空の場合は無視されます。 + profile_editable: + title: プロフィール編集可能 + allow_update_display_name: + label: ユーザーが表示名を変更できるようにする + allow_update_username: + label: ユーザー名の変更を許可する + allow_update_avatar: + label: ユーザーのプロフィール画像の変更を許可する + allow_update_bio: + label: ユーザーが自分についての変更を許可する + allow_update_website: + label: ユーザーのウェブサイトの変更を許可する + allow_update_location: + label: ユーザーの位置情報の変更を許可する + privilege: + title: 特権 + level: + label: 評判の必要レベル + text: 特権に必要な評判を選択します + msg: + should_be_number: 入力は数値でなければなりません + number_larger_1: 数値は 1 以上でなければなりません + badges: + action: 操作 + active: アクティブ + activate: アクティベート + all: すべて + awards: 賞 + deactivate: 非アクティブ化 + filter: + placeholder: 名前、バッジ:id でフィルター + group: グループ + inactive: 非アクティブ + name: 名前 + show_logs: ログを表示 + status: ステータス + title: バッジ + form: + optional: (任意) + empty: 空にすることはできません + invalid: 無効です + btn_submit: 保存 + not_found_props: "必須プロパティ {{ key }} が見つかりません。" + select: 選択 + page_review: + review: レビュー + proposed: 提案された + question_edit: 質問の編集 + answer_edit: 回答の編集 + tag_edit: タグの編集 + edit_summary: 概要を編集 + edit_question: 質問を編集 + edit_answer: 回答を編集 + edit_tag: タグを編集 + empty: レビュータスクは残っていません。 + approve_revision_tip: この修正を承認しますか? + approve_flag_tip: このフラグを承認しますか? + approve_post_tip: この投稿を承認しますか? + approve_user_tip: このユーザーを承認しますか? + suggest_edits: 提案された編集 + flag_post: 報告された投稿 + flag_user: 報告されたユーザー + queued_post: キューに入れられた投稿 + queued_user: キューに入れられたユーザー + filter_label: タイプ + reputation: 評価 + flag_post_type: この投稿は {{ type }} として報告されました + flag_user_type: このユーザーは {{ type }} として報告されました + edit_post: 投稿を編集 + list_post: 投稿一覧 + unlist_post: 限定公開投稿 + timeline: + undeleted: 復元する + deleted: 削除済み + downvote: 低評価 + upvote: 高評価 + accept: 承認 + cancelled: キャンセル済み + commented: コメントしました + rollback: rollback + edited: 編集済み + answered: 回答済み + asked: 質問済み + closed: クローズ済み + reopened: 再オープン + created: 作成済み + pin: ピン留め済 + unpin: ピン留め解除 + show: 限定公開解除済み + hide: 限定公開済み + title: "履歴:" + tag_title: "タイムライン:" + show_votes: "投票を表示" + n_or_a: N/A + title_for_question: "タイムライン:" + title_for_answer: "{{ title }} の {{ author }} 回答のタイムライン" + title_for_tag: "タグのタイムライン:" + datetime: 日付時刻 + type: タイプ + by: By + comment: コメント + no_data: "何も見つけられませんでした" + users: + title: ユーザー + users_with_the_most_reputation: 今週最も高い評価スコアを持つユーザ + users_with_the_most_vote: 今週一番多く投票したユーザー + staffs: コミュニティのスタッフ + reputation: 評価 + votes: 投票 + prompt: + leave_page: このページから移動してもよろしいですか? + changes_not_save: 変更が保存されない可能性があります + draft: + discard_confirm: 下書きを破棄してもよろしいですか? + messages: + post_deleted: この投稿は削除されました。 + post_cancel_deleted: この投稿の削除が取り消されました。 + post_pin: この投稿はピン留めされています。 + post_unpin: この投稿のピン留めが解除されました。 + post_hide_list: この投稿は一覧から非表示になっています。 + post_show_list: この投稿は一覧に表示されています。 + post_reopen: この投稿は再オープンされました。 + post_list: この投稿は一覧に表示されています。 + post_unlist: この投稿は一覧に登録されていません。 + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: この投稿はクローズされました。 + answer_deleted: この回答は削除されました。 + answer_cancel_deleted: この回答の削除が取り消されました。 + change_user_role: このユーザーのロールが変更されました。 + user_inactive: このユーザーは既に無効です。 + user_normal: このユーザーは既に有効です。 + user_suspended: このユーザーは凍結されています。 + user_deleted: このユーザーは削除されました。 + badge_activated: このバッジは有効化されました。 + badge_inactivated: このバッジは無効化されています。 + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/ko_KR.yaml b/data/i18n/ko_KR.yaml new file mode 100644 index 000000000..abea1556c --- /dev/null +++ b/data/i18n/ko_KR.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: 성공. + unknown: + other: 알 수 없는 오류. + request_format_error: + other: 요청 형식이 잘못되었습니다. + unauthorized_error: + other: 권한이 없습니다. + database_error: + other: 데이터 서버 오류. + forbidden_error: + other: 접근 금지. + duplicate_request_error: + other: 중복된 제출입니다. + action: + report: + other: 신고하기 + edit: + other: 편집 + delete: + other: 삭제 + close: + other: 닫기 + reopen: + other: 다시 열기 + forbidden_error: + other: 접근 금지. + pin: + other: 고정 + hide: + other: 리스트 제거 + unpin: + other: 고정 해제 + show: + other: 리스트 + invite_someone_to_answer: + other: 편집 + undelete: + other: 삭제 취소 + merge: + other: 병합 + role: + name: + user: + other: 유저 + admin: + other: 관리자 + moderator: + other: 중재자 + description: + user: + other: 특별한 접근 권한이 없는 기본 사용자입니다. + admin: + other: 사이트에 대한 모든 권한을 가집니다. + moderator: + other: 관리자 설정을 제외한 모든 게시물에 접근할 수 있습니다. + privilege: + level_1: + description: + other: 레벨 1 (비공개 팀, 그룹에 적은 평판 필요) + level_2: + description: + other: 레벨 2 (스타트업 커뮤니티에 낮은 평판 필요) + level_3: + description: + other: 레벨 3 (성숙한 커뮤니티에 높은 평판 필요) + level_custom: + description: + other: 커스텀 레벨 + rank_question_add_label: + other: 질문하기 + rank_answer_add_label: + other: 답변하기 + rank_comment_add_label: + other: 댓글 작성하기 + rank_report_add_label: + other: 신고하기 + rank_comment_vote_up_label: + other: 댓글 추천 + rank_link_url_limit_label: + other: 한번에 2개 이상의 링크를 게시하세요 + rank_question_vote_up_label: + other: 질문 추천 + rank_answer_vote_up_label: + other: 답변 추천 + rank_question_vote_down_label: + other: 질문 비추천 + rank_answer_vote_down_label: + other: 답변 비추천 + rank_invite_someone_to_answer_label: + other: 답변할 사람 초대 + rank_tag_add_label: + other: 새 태그 만들기 + rank_tag_edit_label: + other: 태그 설명 편집 (검토 필요) + rank_question_edit_label: + other: 다른 사람의 질문 편집 (검토 필요) + rank_answer_edit_label: + other: 다른 사람의 답변 편집 (검토 필요) + rank_question_edit_without_review_label: + other: 검토 없이 다른 사람의 질문 편집 + rank_answer_edit_without_review_label: + other: 검토 없이 다른 사람의 답변 편집 + rank_question_audit_label: + other: 질문 편집 검토하기 + rank_answer_audit_label: + other: 답변 편집 검토하기 + rank_tag_audit_label: + other: 태그 편집 검토하기 + rank_tag_edit_without_review_label: + other: 검토 없이 태그 설명 편집 + rank_tag_synonym_label: + other: 태그 동의어 관리 + email: + other: 이메일 + e_mail: + other: 이메일 + password: + other: 비밀번호 + pass: + other: 비밀번호 + old_pass: + other: 현재 비밀번호 + original_text: + other: 이 게시물 + email_or_password_wrong_error: + other: 이메일과 비밀번호가 일치하지 않습니다. + error: + common: + invalid_url: + other: 잘못된 URL 입니다. + status_invalid: + other: 유효하지 않은 상태. + password: + space_invalid: + other: 암호에는 공백을 포함할 수 없습니다. + admin: + cannot_update_their_password: + other: 암호를 변경할 수 없습니다. + cannot_edit_their_profile: + other: 수정할 수 없습니다. + cannot_modify_self_status: + other: 상태를 변경할 수 없습니다. + email_or_password_wrong: + other: 이메일과 비밀번호가 일치하지 않습니다. + answer: + not_found: + other: 답변을 찾을 수 없습니다. + cannot_deleted: + other: 삭제 권한이 없습니다. + cannot_update: + other: 편집 권한이 없습니다. + question_closed_cannot_add: + other: 질문이 닫혔으며, 추가할 수 없습니다. + content_cannot_empty: + other: 답변 내용은 비워둘 수 없습니다. + comment: + edit_without_permission: + other: 편집이 가능하지 않은 댓글입니다. + not_found: + other: 댓글을 찾을 수 없습니다. + cannot_edit_after_deadline: + other: 수정 허용 시간을 초과했습니다. + content_cannot_empty: + other: 댓글 내용은 비워둘 수 없습니다. + email: + duplicate: + other: 이미 존재하는 이메일입니다. + need_to_be_verified: + other: 이메일을 확인해주세요. + verify_url_expired: + other: URL이 만료되었습니다. 이메일을 다시 보내주세요. + illegal_email_domain_error: + other: 해당 도메인을 사용할 수 없습니다. 다른 전자 메일을 사용하십시오. + lang: + not_found: + other: 언어 파일을 찾을 수 없습니다. + object: + captcha_verification_failed: + other: 잘못된 Captcha입니다. + disallow_follow: + other: 팔로우할 수 없습니다. + disallow_vote: + other: 추천할 수 없습니다. + disallow_vote_your_self: + other: 자신의 게시물에는 추천할 수 없습니다. + not_found: + other: 오브젝트를 찾을 수 없습니다. + verification_failed: + other: 확인 실패. + email_or_password_incorrect: + other: 이메일과 비밀번호가 일치하지 않습니다. + old_password_verification_failed: + other: 이전 암호 확인에 실패했습니다 + new_password_same_as_previous_setting: + other: 새 비밀번호는 이전 비밀번호와 다르게 입력해주세요. + already_deleted: + other: 이 게시물은 삭제되었습니다. + meta: + object_not_found: + other: 메타 객체를 찾을 수 없습니다 + question: + already_deleted: + other: 삭제된 게시물입니다. + under_review: + other: 검토를 기다리고 있습니다. 승인된 후에 볼 수 있습니다. + not_found: + other: 질문을 찾을 수 없습니다. + cannot_deleted: + other: 삭제 권한이 없습니다. + cannot_close: + other: 닫을 권한이 없습니다. + cannot_update: + other: 업데이트 권한이 없습니다. + content_cannot_empty: + other: 내용은 비워둘 수 없습니다. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: 등급이 조건을 충족하지 못합니다. + vote_fail_to_meet_the_condition: + other: 피드백 감사합니다. 투표를 하려면 최소 {{.Rank}} 평판이 필요합니다. + no_enough_rank_to_operate: + other: 이 작업을 하려면 최소 {{.Rank}} 평판이 필요합니다. + report: + handle_failed: + other: 신고 처리에 실패했습니다. + not_found: + other: 신고를 찾을 수 없습니다. + tag: + already_exist: + other: 이미 존재하는 태그입니다. + not_found: + other: 태그를 찾을 수 없습니다. + recommend_tag_not_found: + other: 추천 태그가 존재하지 않습니다. + recommend_tag_enter: + other: 하나 이상의 태그를 입력해주세요. + not_contain_synonym_tags: + other: 동일한 태그를 포함하지 않아야 합니다. + cannot_update: + other: 편집 권한이 없습니다. + is_used_cannot_delete: + other: 사용 중인 태그는 삭제할 수 없습니다. + cannot_set_synonym_as_itself: + other: 현재 태그의 동의어로 자기 자신을 설정할 수 없습니다. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: 발신자 이름은 이메일 주소가 될 수 없습니다. + theme: + not_found: + other: 테마를 찾을 수 없습니다. + revision: + review_underway: + other: 검토 대기열에 있기 때문에 현재 편집할 수 없습니다. + no_permission: + other: 수정권한이 없습니다. + user: + external_login_missing_user_id: + other: 서드파티 플랫폼에서 고유 사용자 ID를 제공하지 않아 로그인할 수 없습니다. 웹사이트 관리자에게 문의하세요. + external_login_unbinding_forbidden: + other: 이 로그인을 제거하기 전에 계정에 로그인 비밀번호를 설정하세요. + email_or_password_wrong: + other: + other: 이메일 또는 비밀번호가 일치하지 않습니다. + not_found: + other: 사용자를 찾을 수 없습니다. + suspended: + other: 사용자가 정지되었습니다. + username_invalid: + other: 유효하지 않은 이름입니다. + username_duplicate: + other: 이미 사용중인 이름입니다. + set_avatar: + other: 아바타 설정에 실패했습니다. + cannot_update_your_role: + other: 수정할 수 없습니다. + not_allowed_registration: + other: 현재 사이트는 등록할 수 없습니다. + not_allowed_login_via_password: + other: 현재 사이트는 비밀번호를 통해 로그인할 수 없습니다. + access_denied: + other: 접근이 거부당했습니다. + page_access_denied: + other: 이 페이지에 대한 접근 권한이 없습니다. + add_bulk_users_format_error: + other: "줄 {{.Line}}의 '{{.Content}}' 근처 {{.Field}} 형식 오류입니다. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "한 번에 추가할 수 있는 사용자 수는 1-{{.MaxAmount}} 범위 내에 있어야 합니다." + status_suspended_forever: + other: "이 사용자는 무기한 접근이 금지 되었습니다. 이 사용자는 커뮤니티의 지침을 충족시키지 않았습니다." + status_suspended_until: + other: "이 사용자는 {{.SuspendedUntil}} 까지 접근이 금지 되었습니다. 이 사용자는 커뮤니티의 지침을 충족시키지 않았습니다." + status_deleted: + other: "삭제된 사용자입니다." + status_inactive: + other: "비활성 사용자입니다." + config: + read_config_failed: + other: 컨피그파일 읽기를 실패했습니다 + database: + connection_failed: + other: 데이터베이스 연결을 실패했습니다 + create_table_failed: + other: 테이블 생성을 실패했습니다 + install: + create_config_failed: + other: config.yaml 파일을 생성할 수 없습니다. + upload: + unsupported_file_format: + other: 지원하지 않는 파일 형식입니다. + site_info: + config_not_found: + other: 사이트 설정을 찾을 수 없습니다. + badge: + object_not_found: + other: 배지 객체를 찾을 수 없습니다 + reason: + spam: + name: + other: 스팸 + desc: + other: 이 게시물은 광고로 인식되었습니다. 현재 주제와 관련이 없습니다. + rude_or_abusive: + name: + other: 폭언 또는 무례한 언행입니다. + desc: + other: "대화에 부적절한 내용입니다." + a_duplicate: + name: + other: 중복 + desc: + other: 이 질문은 이전에 질문한 적이 있으며 이미 답변이 있습니다. + placeholder: + other: 이미 존재하는 질문입니다 + not_a_answer: + name: + other: 답변이 아닙니다 + desc: + other: "이 내용은 답변으로 게시 되었지만, 질문에 대한 답변 시도가 아닙니다. 이는 수정, 댓글, 다른 질문으로 올리는 것이 적절하거나, 삭제하는 것이 적절할 수도 있습니다." + no_longer_needed: + name: + other: 더 이상 필요하지 않습니다. + desc: + other: 이 의견은 구식이거나 대화 중이거나 이 게시물과 관련이 없습니다. + something: + name: + other: 다른 항목 + desc: + other: 이 게시물은 위에 나열되지 않은 다른 이유로 직원의 주의가 필요합니다. + placeholder: + other: 귀하가 우려하는 사항을 구체적으로 알려주세요. + community_specific: + name: + other: 커뮤니티별 특정 이유 + desc: + other: 이 질문은 커뮤니티 가이드라인에 부합하지 않습니다. + not_clarity: + name: + other: 세부사항 또는 명확성이 필요합니다. + desc: + other: 이 질문은 현재 하나에 여러 개의 질문이 포함되어 있습니다. 하나의 문제에만 초점을 맞추어야 합니다. + looks_ok: + name: + other: 괜찮아 보입니다. + desc: + other: 이 게시물은 괜찮으며 품질이 낮지 않습니다. + needs_edit: + name: + other: 편집이 필요하고, 제가 했습니다. + desc: + other: 이 게시물에 대한 문제를 직접 개선하고 수정합니다. + needs_close: + name: + other: 닫혀야 함 + desc: + other: 닫힌 질문은 대답할 수 없지만 편집, 투표 및 댓글 작성을 할 수 있습니다. + needs_delete: + name: + other: 삭제해야 함 + desc: + other: 이 게시물은 삭제되었습니다. + question: + close: + duplicate: + name: + other: 스팸 + desc: + other: 이 질문은 이전에 질문한 적이 있으며 이미 답변이 있습니다. + guideline: + name: + other: 커뮤니티 특정 이유 + desc: + other: 이 질문은 커뮤니티 가이드라인에 부합하지 않습니다. + multiple: + name: + other: 세부사항 또는 명확성이 필요합니다. + desc: + other: 이 질문은 현재 하나에 여러 개의 질문이 포함되어 있습니다. 하나의 문제에만 초점을 맞추어야 합니다. + other: + name: + other: 다른 이유 + desc: + other: 이 게시물에는 위에 나열되지 않은 다른 이유가 필요합니다. + operation_type: + asked: + other: 질문됨 + answered: + other: 답변됨 + modified: + other: 수정됨 + deleted_title: + other: 이미 삭제된 게시물입니다. + questions_title: + other: 질문들 + tag: + tags_title: + other: 태그 + no_description: + other: 이 태그에는 설명이 없습니다. + notification: + action: + update_question: + other: 수정된 질문 + answer_the_question: + other: 대답한 질문 + update_answer: + other: 수정된 대답 + accept_answer: + other: 채택된 답변 + comment_question: + other: 질문에 댓글 달림 + comment_answer: + other: 답변에 댓글 달림 + reply_to_you: + other: 당신에게 답변함 + mention_you: + other: 당신을 언급함 + your_question_is_closed: + other: 당신의 질문이 닫혔습니다 + your_question_was_deleted: + other: 당신의 질문이 삭제되었습니다 + your_answer_was_deleted: + other: 당신의 답변이 삭제되었습니다 + your_comment_was_deleted: + other: 당신의 댓글이 삭제되었습니다 + up_voted_question: + other: 질문에 추천함 + down_voted_question: + other: 질문에 비추천함 + up_voted_answer: + other: 답변에 추천함 + down_voted_answer: + other: 답변에 비추천함 + up_voted_comment: + other: 댓글에 추천함 + invited_you_to_answer: + other: 답변에 초대함 + earned_badge: + other: '"{{.BadgeName}}" 배지를 획득했습니다' + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] 새 이메일 주소 확인" + body: + other: "다음 링크를 클릭하여 {{.SiteName}} 의 새 이메일 주소를 확인하세요:
        \n{{.ChangeEmailUrl}}

        \n\n이 변경을 요청하지 않았다면 이 이메일을 무시하세요.

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} 님이 답변을 작성했습니다" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \n{{.SiteName}} 에서 보기

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요.

        \n\n구독 취소" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} 님이 답변을 요청했습니다" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        답변을 아실 것 같습니다.

        \n{{.SiteName}} 에서 보기

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요.

        \n\n구독 취소" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} 님이 당신의 게시물에 댓글을 남겼습니다" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \n{{.SiteName}} 에서 보기

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요.

        \n\n구독 취소" + new_question: + title: + other: "[{{.SiteName}}] 새 질문: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요.

        \n\n구독 취소" + pass_reset: + title: + other: "[{{.SiteName }}] 비밀번호 재설정" + body: + other: "누군가가 {{.SiteName}} 에서 당신의 비밀번호 재설정을 요청했습니다.

        \n\n당신이 요청하지 않았다면 이 이메일을 무시해도 됩니다.

        \n\n새 비밀번호를 선택하려면 다음 링크를 클릭하세요:
        \n{{.PassResetUrl}}\n

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요." + register: + title: + other: "[{{.SiteName}}] 새 계정 확인" + body: + other: "{{.SiteName}} 에 오신 것을 환영합니다!

        \n\n새 계정을 확인하고 활성화하려면 다음 링크를 클릭하세요:
        \n{{.RegisterUrl}}

        \n\n위 링크가 동작하지 않으면 복사하여 브라우저의 주소 입력에 직접 붙여넣으세요.\n

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요." + test: + title: + other: "[{{.SiteName}}] 테스트 이메일" + body: + other: "이것은 테스트 이메일입니다.\n

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요." + action_activity_type: + upvote: + other: 추천 + upvoted: + other: 추천함 + downvote: + other: 비추천 + downvoted: + other: 비추천함 + accept: + other: 채택 + accepted: + other: 채택됨 + edit: + other: 수정 + review: + queued_post: + other: 대기 중인 게시물 + flagged_post: + other: 신고된 게시물 + suggested_post_edit: + other: 건의된 수정 + reaction: + tooltip: + other: "{{ .Names }} 외 {{ .Count }} 명..." + badge: + default_badges: + autobiographer: + name: + other: 자서전 작가 + desc: + other: 프로필 정보를 작성했습니다. + certified: + name: + other: 인증됨 + desc: + other: 신규 사용자 튜토리얼을 완료했습니다. + editor: + name: + other: 에디터 + desc: + other: 첫 게시물 편집. + first_flag: + name: + other: 첫 번째 플래그 + desc: + other: 첫 번째로 게시물에 플래그를 설정했습니다. + first_upvote: + name: + other: 첫 번째 추천 + desc: + other: 첫 번째로 게시물을 추천했습니다. + first_link: + name: + other: 첫 번째 링크 + desc: + other: 첫 번째로 다른 게시물에 링크를 추가했습니다. + first_reaction: + name: + other: 첫 번째 반응 + desc: + other: 첫 번째로 게시물에 반응했습니다. + first_share: + name: + other: 첫 번째 공유 + desc: + other: 첫 번째로 게시물을 공유했습니다. + scholar: + name: + other: 학자 + desc: + other: 질문을 하고 답변을 채택했습니다. + commentator: + name: + other: 해설자 + desc: + other: 댓글 5 개 남기기. + new_user_of_the_month: + name: + other: 이달의 신규 사용자 + desc: + other: 첫 달의 뛰어난 기여. + read_guidelines: + name: + other: 가이드라인 읽음 + desc: + other: '[커뮤니티 가이드라인] 을 읽어보세요.' + reader: + name: + other: 리더 + desc: + other: 10 개 이상의 답변이 있는 주제의 모든 답변을 읽어보세요. + welcome: + name: + other: 환영합니다 + desc: + other: 추천을 받았습니다. + nice_share: + name: + other: 좋은 공유 + desc: + other: 25 명의 고유 방문자와 게시물을 공유했습니다. + good_share: + name: + other: 더 좋은 공유 + desc: + other: 300 명의 고유 방문자와 게시물을 공유했습니다. + great_share: + name: + other: 훌륭한 공유 + desc: + other: 1000 명의 고유 방문자와 게시물을 공유했습니다. + out_of_love: + name: + other: 사랑이 식어서 + desc: + other: 하루에 50 개의 추천을 사용했습니다. + higher_love: + name: + other: 더 큰 사랑 + desc: + other: 하루에 50 개의 추천을 5 번 사용했습니다. + crazy_in_love: + name: + other: 사랑에 미치다 + desc: + other: 하루에 50 개의 추천을 20 번 사용했습니다. + promoter: + name: + other: 홍보자 + desc: + other: 사용자를 초대했습니다. + campaigner: + name: + other: 캠페인 담당자 + desc: + other: 3 명의 기본 사용자를 초대했습니다. + champion: + name: + other: 챔피언 + desc: + other: 5 명의 멤버를 초대했습니다. + thank_you: + name: + other: 감사합니다 + desc: + other: 20 개의 추천받은 게시물을 보유하고 10 개의 추천을 주었습니다. + gives_back: + name: + other: 보답 + desc: + other: 100 개의 추천받은 게시물을 보유하고 100 개의 추천을 주었습니다. + empathetic: + name: + other: 공감적 + desc: + other: 500 개의 추천받은 게시물을 보유하고 1000 개의 추천을 주었습니다. + enthusiast: + name: + other: 열성팬 + desc: + other: 10 일 연속으로 방문했습니다. + aficionado: + name: + other: 애호가 + desc: + other: 100 일 연속으로 방문했습니다. + devotee: + name: + other: 열성 지지자 + desc: + other: 365 일 연속으로 방문했습니다. + anniversary: + name: + other: 기념일 + desc: + other: 1 년 동안 활발한 멤버로 활동하며 최소 한 번 이상 게시했습니다. + appreciated: + name: + other: 감사합니다 + desc: + other: 20 개의 게시물에서 1 번의 추천을 받았습니다. + respected: + name: + other: 존경받는 + desc: + other: 100 개의 게시물에서 2 번의 추천을 받았습니다. + admired: + name: + other: 존경받는 + desc: + other: 300 개의 게시물에서 5 번의 추천을 받았습니다. + solved: + name: + other: 해결됨 + desc: + other: 답변이 채택되었습니다. + guidance_counsellor: + name: + other: 지도 상담사 + desc: + other: 10 개의 답변이 채택되었습니다. + know_it_all: + name: + other: 만물박사 + desc: + other: 50 개의 답변이 채택되었습니다. + solution_institution: + name: + other: 솔루션 기관 + desc: + other: 150 개의 답변이 채택되었습니다. + nice_answer: + name: + other: 좋은 답변 + desc: + other: 답변 점수가 10 점 이상입니다. + good_answer: + name: + other: 더 좋은 답변 + desc: + other: 답변 점수가 25 점 이상입니다. + great_answer: + name: + other: 훌륭한 답변 + desc: + other: 답변 점수가 50 점 이상입니다. + nice_question: + name: + other: 좋은 질문 + desc: + other: 질문 점수가 10 점 이상입니다. + good_question: + name: + other: 좋은 질문 + desc: + other: 질문 점수가 25 점 이상입니다. + great_question: + name: + other: 훌륭한 질문 + desc: + other: 질문 점수가 50 점 이상입니다. + popular_question: + name: + other: 인기 질문 + desc: + other: 500 회 조회된 질문입니다. + notable_question: + name: + other: 중요 질문 + desc: + other: 1,000 회 조회된 질문입니다. + famous_question: + name: + other: 유명 질문 + desc: + other: 5,000 회 조회된 질문입니다. + popular_link: + name: + other: 인기 링크 + desc: + other: 50 번 클릭된 외부 링크를 게시했습니다. + hot_link: + name: + other: 핫 링크 + desc: + other: 300 번 클릭된 외부 링크를 게시했습니다. + famous_link: + name: + other: 유명한 링크 + desc: + other: 100 번 클릭된 외부 링크를 게시했습니다. + default_badge_groups: + getting_started: + name: + other: 시작하기 + community: + name: + other: 커뮤니티 + posting: + name: + other: 포스팅 +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: 포맷 방법 + desc: >- +
        • 게시물 언급: #post_id

        • 링크 만들기

          <https://url.com>

          [제목](https://url.com)
        • 단락 사이에 줄바꿈 넣기

        • _기울임체_ 또는 **굵게**

        • 코드는 4 칸 들여쓰기

        • 줄 시작에 > 를 넣어 인용

        • 백틱으로 이스케이프 `_이렇게_`

        • 백틱 ` 으로 코드 펜스 생성

          ```
          여기에 코드
          ```
        + pagination: + prev: 이전 + next: 다음 + page_title: + question: 질문 + questions: 질문들 + tag: 태그 + tags: 태그들 + tag_wiki: 태그 위키 + create_tag: 태그 생성 + edit_tag: 태그 수정 + ask_a_question: 질문 생성 + edit_question: 질문 수정 + edit_answer: 답변 수정 + search: 검색 + posts_containing: 포함된 게시물 + settings: 설정 + notifications: 알림 + login: 로그인 + sign_up: 회원 가입 + account_recovery: 계정 복구 + account_activation: 계정 활성화 + confirm_email: 이메일 확인 + account_suspended: 계정 정지 + admin: 관리자 + change_email: 이메일 수정 + install: 답변 설치 + upgrade: 답변 업그레이드 + maintenance: 웹사이트 유지보수 + users: 사용자 + oauth_callback: 처리 중 + http_404: HTTP 오류 404 + http_50X: HTTP 오류 500 + http_403: HTTP 오류 403 + logout: 로그아웃 + posts: Posts + notifications: + title: 알림 + inbox: 받은 편지함 + achievement: 업적 + new_alerts: 새로운 알림 + all_read: 모두 읽음 처리 + show_more: 더 보기 + someone: 누군가 + inbox_type: + all: 전체 + posts: 게시물 + invites: 초대 + votes: 투표 + answer: 답변 + question: 질문 + badge_award: 뱃지 + suspended: + title: 계정이 정지되었습니다 + until_time: "당신의 계정은 {{ time }}까지 정지되었습니다." + forever: 이 사용자는 영구 정지되었습니다. + end: 커뮤니티 가이드라인을 준수하지 않았습니다. + contact_us: 문의하기 + editor: + blockquote: + text: 인용구 + bold: + text: 강조 + chart: + text: 차트 + flow_chart: 플로우 차트 + sequence_diagram: 시퀀스 다이어그램 + class_diagram: 클래스 다이어그램 + state_diagram: 상태 다이어그램 + entity_relationship_diagram: 엔터티 관계 다이어그램 + user_defined_diagram: 사용자 정의 다이어그램 + gantt_chart: 간트 차트 + pie_chart: 파이 차트 + code: + text: 코드 예시 + add_code: 코드 예시 추가 + form: + fields: + code: + label: 코드 + msg: + empty: 코드를 입력하세요. + language: + label: 언어 + placeholder: 자동 감지 + btn_cancel: 취소 + btn_confirm: 추가 + formula: + text: 수식 + options: + inline: 인라인 수식 + block: 블록 수식 + heading: + text: 제목 + options: + h1: 제목 1 + h2: 제목 2 + h3: 제목 3 + h4: 제목 4 + h5: 제목 5 + h6: 제목 6 + help: + text: 도움말 + hr: + text: 가로규칙 + image: + text: 이미지 + add_image: 이미지 추가 + tab_image: 이미지 업로드 + form_image: + fields: + file: + label: 이미지 파일 + btn: 이미지 선택 + msg: + empty: 파일을 선택하세요. + only_image: 이미지 파일만 허용됩니다. + max_size: 파일 크기는 {{size}} MB 를 초과할 수 없습니다. + desc: + label: 설명 + tab_url: 이미지 URL + form_url: + fields: + url: + label: 이미지 URL + msg: + empty: 이미지 URL을 입력하세요. + name: + label: 설명 + btn_cancel: 취소 + btn_confirm: 추가 + uploading: 업로드 중 + indent: + text: 들여쓰기 + outdent: + text: 내어쓰기 + italic: + text: 이탤릭체 + link: + text: 링크 + add_link: 링크 추가 + form: + fields: + url: + label: URL + msg: + empty: URL을 입력하세요. + name: + label: 설명 + btn_cancel: 취소 + btn_confirm: 추가 + ordered_list: + text: 번호 매긴 목록 + unordered_list: + text: 글머리 기호 목록 + table: + text: 표 + heading: 제목 + cell: 셀 + file: + text: 파일 첨부 + not_supported: "해당 파일 형식을 지원하지 않습니다. {{file_type}} 로 다시 시도해 주세요." + max_size: "첨부 파일 크기는 {{size}} MB 를 초과할 수 없습니다." + close_modal: + title: 이 게시물을 다음과 같은 이유로 닫습니다... + btn_cancel: 취소 + btn_submit: 제출 + remark: + empty: 비어 있을 수 없습니다. + msg: + empty: 이유를 선택해 주세요. + report_modal: + flag_title: 이 게시물을 신고합니다... + close_title: 이 게시물을 다음과 같은 이유로 닫습니다... + review_question_title: 질문 검토 + review_answer_title: 답변 검토 + review_comment_title: 댓글 검토 + btn_cancel: 취소 + btn_submit: 제출 + remark: + empty: 비어 있을 수 없습니다. + msg: + empty: 이유를 선택해 주세요. + not_a_url: URL 형식이 올바르지 않습니다. + url_not_match: URL 원본이 현재 웹사이트와 일치하지 않습니다. + tag_modal: + title: 새로운 태그 생성 + form: + fields: + display_name: + label: 표시 이름 + msg: + empty: 표시 이름을 입력하세요. + range: 표시 이름은 최대 35자까지 입력 가능합니다. + slug_name: + label: URL 슬러그 + desc: '"a-z", "0-9", "+ # - ." 문자 집합을 사용해야 합니다.' + msg: + empty: URL 슬러그를 입력하세요. + range: URL 슬러그는 최대 35자까지 입력 가능합니다. + character: 허용되지 않은 문자 집합이 포함되어 있습니다.' + desc: + label: 설명 + revision: + label: 개정 + edit_summary: + label: 편집 요약 + placeholder: >- + 수정 사항을 간략히 설명하세요 (철자 수정, 문법 수정, 서식 개선 등) + btn_cancel: 취소 + btn_submit: 제출 + btn_post: 새 태그 게시 + tag_info: + created_at: 생성됨 + edited_at: 편집됨 + history: 히스토리 + synonyms: + title: 동의어 + text: 다음 태그가 다음으로 다시 매핑됩니다 + empty: 동의어가 없습니다. + btn_add: 동의어 추가 + btn_edit: 편집 + btn_save: 저장 + synonyms_text: 다음 태그가 다음으로 다시 매핑됩니다 + delete: + title: 이 태그 삭제 + tip_with_posts: >- +

        게시물이 있는 태그 삭제는 허용되지 않습니다.

        먼저 게시물에서 이 태그를 제거해 주세요.

        + tip_with_synonyms: >- +

        동의어가 있는 태그 삭제는 허용되지 않습니다.

        먼저 이 태그에서 동의어를 제거해 주세요.

        + tip: 정말로 삭제하시겠습니까? + close: 닫기 + merge: + title: 태그 병합 + source_tag_title: 원본 태그 + source_tag_description: 원본 태그와 관련 데이터가 대상 태그로 재매핑됩니다. + target_tag_title: 대상 태그 + target_tag_description: 병합 후 이 두 태그 간 동의어가 생성됩니다. + no_results: 일치하는 태그가 없습니다 + btn_submit: 제출 + btn_close: 닫기 + edit_tag: + title: 태그 수정 + default_reason: 태그 수정 + default_first_reason: 태그 추가 + btn_save_edits: 수정 저장 + btn_cancel: 취소 + dates: + long_date: MMM D + long_date_with_year: "YYYY년 M월 D일" + long_date_with_time: "YYYY년 MMM D일 HH:mm" + now: 방금 전 + x_seconds_ago: "{{count}}초 전" + x_minutes_ago: "{{count}}분 전" + x_hours_ago: "{{count}}시간 전" + hour: 시간 + day: 일 + hours: 시간 + days: 일 + month: 월 + months: 개월 + year: 년 + reaction: + heart: 하트 + smile: 스마일 + frown: 찡그린 표정 + btn_label: 반응 추가 또는 제거 + undo_emoji: '{{ emoji }} 반응 취소' + react_emoji: '{{ emoji }} 로 반응' + unreact_emoji: '{{ emoji }} 반응 취소' + comment: + btn_add_comment: 댓글 추가 + reply_to: 답글 달기 + btn_reply: 답글 + btn_edit: 수정 + btn_delete: 삭제 + btn_flag: 신고 + btn_save_edits: 수정 저장 + btn_cancel: 취소 + show_more: "{{count}}개의 댓글 더 보기" + tip_question: >- + 더 많은 정보를 요청하거나 개선을 제안하기 위해 댓글을 사용하세요. 댓글에서 질문에 답변하지는 마세요. + tip_answer: >- + 다른 사용자에게 답변하거나 변경 사항을 알릴 때 댓글을 사용하세요. 새로운 정보를 추가하는 경우에는 게시물을 수정하세요. + tip_vote: 게시물에 유용한 정보를 추가합니다. + edit_answer: + title: 답변 수정 + default_reason: 답변 수정 + default_first_reason: 답변 추가 + form: + fields: + revision: + label: 개정 + answer: + label: 답변 + feedback: + characters: 내용은 최소 6자 이상이어야 합니다. + edit_summary: + label: 편집 요약 + placeholder: >- + 수정 사항을 간략히 설명하세요 (철자 수정, 문법 수정, 서식 개선 등) + btn_save_edits: 수정 저장 + btn_cancel: 취소 + tags: + title: 태그들 + sort_buttons: + popular: 인기순 + name: 이름 + newest: 최신순 + button_follow: 팔로우 + button_following: 팔로잉 중 + tag_label: 질문들 + search_placeholder: 태그 이름으로 필터링 + no_desc: 이 태그에는 설명이 없습니다. + more: 더 보기 + wiki: 위키 + ask: + title: 질문 생성 + edit_title: 질문 수정 + default_reason: 질문 수정 + default_first_reason: 질문 생성 + similar_questions: 유사한 질문 + form: + fields: + revision: + label: 개정 + title: + label: 제목 + placeholder: 주제는 무엇인가요? 상세하게 작성해주세요. + msg: + empty: 제목을 입력하세요. + range: 제목은 최대 150자까지 입력 가능합니다. + body: + label: 본문 + msg: + empty: 본문을 입력하세요. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: 태그 + msg: + empty: 태그를 입력하세요. + answer: + label: 답변 + msg: + empty: 답변을 입력하세요. + edit_summary: + label: 편집 요약 + placeholder: >- + 수정 사항을 간략히 설명하세요 (철자 수정, 문법 수정, 서식 개선 등) + btn_post_question: 질문 게시하기 + btn_save_edits: 수정사항 저장 + answer_question: 질문에 대한 답변 작성 + post_question&answer: 질문과 답변 게시하기 + tag_selector: + add_btn: 태그 추가 + create_btn: 새 태그 생성 + search_tag: 태그 검색 + hint: 질문의 주제를 설명하세요. 적어도 하나의 태그가 필요합니다. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: 일치하는 태그가 없습니다. + tag_required_text: 필수 태그 (적어도 하나) + header: + nav: + question: 질문 + tag: 태그 + user: 사용자 + badges: 뱃지 + profile: 프로필 + setting: 설정 + logout: 로그아웃 + admin: 관리자 + review: 리뷰 + bookmark: 즐겨찾기 + moderation: 운영 + search: + placeholder: 검색 + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: 변경 + loading: 로딩 중... + pic_auth_code: + title: 캡차 + placeholder: 위의 텍스트를 입력하세요 + msg: + empty: 캡차를 입력하세요. + inactive: + first: >- + 거의 다 되었습니다! {{mail}}로 활성화 메일을 보냈습니다. 계정을 활성화하려면 메일 안의 지침을 따르세요. + info: "메일이 도착하지 않았다면, 스팸 메일함도 확인해 주세요." + another: >- + {{mail}}로 또 다른 활성화 이메일을 보냈습니다. 메일이 도착하는 데 몇 분 정도 걸릴 수 있으니 스팸 메일함도 확인해 주세요. + btn_name: 활성화 이메일 재전송 + change_btn_name: 이메일 변경 + msg: + empty: 비어 있을 수 없습니다. + resend_email: + url_label: 활성화 이메일을 재전송하시겠습니까? + url_text: 위의 활성화 링크를 사용자에게 제공할 수도 있습니다. + login: + login_to_continue: 계속하려면 로그인하세요 + info_sign: 계정이 없으신가요? <1>가입하기 + info_login: 이미 계정이 있으신가요? <1>로그인하기 + agreements: 가입하면 <1>개인정보 보호 정책과 <3>이용 약관에 동의하게 됩니다. + forgot_pass: 비밀번호를 잊으셨나요? + name: + label: 이름 + msg: + empty: 이름을 입력하세요. + range: 이름은 2 자에서 30 자 사이여야 합니다. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: 이메일 + msg: + empty: 이메일을 입력하세요. + password: + label: 비밀번호 + msg: + empty: 비밀번호를 입력하세요. + different: 입력된 비밀번호가 일치하지 않습니다. + account_forgot: + page_title: 비밀번호를 잊으셨나요? + btn_name: 비밀번호 재설정 이메일 보내기 + send_success: >- + {{mail}}에 해당하는 계정이 있다면 곧 비밀번호 재설정 방법을 안내하는 이메일을 받으실 수 있습니다. + email: + label: 이메일 + msg: + empty: 이메일을 입력하세요. + change_email: + btn_cancel: 취소 + btn_update: 이메일 주소 업데이트 + send_success: >- + {{mail}}에 해당하는 계정이 있다면 곧 이메일 주소 변경 방법을 안내하는 이메일을 받으실 수 있습니다. + email: + label: 새 이메일 + msg: + empty: 이메일을 입력하세요. + oauth: + connect: '{{ auth_name }}로 연결' + remove: '{{ auth_name }} 연결 해제' + oauth_bind_email: + subtitle: 계정에 복구 이메일 추가 + btn_update: 이메일 주소 업데이트 + email: + label: 이메일 + msg: + empty: 이메일을 입력하세요. + modal_title: 이미 등록된 이메일 + modal_content: 이 이메일 주소는 이미 등록되어 있습니다. 기존 계정에 연결하시겠습니까? + modal_cancel: 이메일 변경 + modal_confirm: 기존 계정에 연결하기 + password_reset: + page_title: 비밀번호 재설정 + btn_name: 비밀번호 재설정 + reset_success: >- + 비밀번호가 성공적으로 변경되었습니다. 로그인 페이지로 이동합니다. + link_invalid: >- + 죄송합니다. 이 비밀번호 재설정 링크는 더 이상 유효하지 않습니다. 이미 비밀번호를 재설정하셨을 수 있습니다. + to_login: 로그인 페이지로 이동 + password: + label: 비밀번호 + msg: + empty: 비밀번호를 입력하세요. + length: 비밀번호는 8자에서 32자 사이여야 합니다. + different: 입력한 비밀번호가 일치하지 않습니다. + password_confirm: + label: 새 비밀번호 확인 + settings: + page_title: 설정 + goto_modify: 수정으로 이동 + nav: + profile: 프로필 + notification: 알림 + account: 계정 + interface: 인터페이스 + profile: + heading: 프로필 + btn_name: 저장 + display_name: + label: 표시 이름 + msg: 표시 이름을 입력하세요. + msg_range: 표시 이름은 2-30 자 길이여야 합니다. + username: + label: 사용자 이름 + caption: 다른 사용자가 "@사용자이름"으로 멘션할 수 있습니다. + msg: 사용자 이름을 입력하세요. + msg_range: 유저 이름은 2-30 자 길이여야 합니다. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: 프로필 이미지 + gravatar: Gravatar + gravatar_text: Gravatar에서 이미지를 변경할 수 있습니다. + custom: 사용자 정의 + custom_text: 사용자 이미지를 업로드할 수 있습니다. + default: 시스템 기본 이미지 + msg: 프로필 이미지를 업로드하세요. + bio: + label: 자기 소개 + website: + label: 웹사이트 + placeholder: "https://example.com" + msg: 웹사이트 형식이 올바르지 않습니다. + location: + label: 위치 + placeholder: "도시, 국가" + notification: + heading: 이메일 알림 + turn_on: 켜기 + inbox: + label: 받은 편지함 알림 + description: 질문에 대한 답변, 댓글, 초대 등을 받습니다. + all_new_question: + label: 모든 새 질문 + description: 모든 새 질문에 대해 알림을 받습니다. 주당 최대 50개의 질문까지. + all_new_question_for_following_tags: + label: 팔로우 태그의 모든 새 질문 + description: 팔로우하는 태그의 새로운 질문에 대해 알림을 받습니다. + account: + heading: 계정 + change_email_btn: 이메일 변경 + change_pass_btn: 비밀번호 변경 + change_email_info: >- + 해당 주소로 이메일을 보냈습니다. 확인 지침을 따라주세요. + email: + label: 이메일 + new_email: + label: 새 이메일 + msg: 새 이메일을 입력하세요. + pass: + label: 현재 비밀번호 + msg: 비밀번호를 입력하세요. + password_title: 비밀번호 + current_pass: + label: 현재 비밀번호 + msg: + empty: 현재 비밀번호를 입력하세요. + length: 비밀번호는 8자에서 32자 사이여야 합니다. + different: 입력한 두 비밀번호가 일치하지 않습니다. + new_pass: + label: 새 비밀번호 + pass_confirm: + label: 새 비밀번호 확인 + interface: + heading: 인터페이스 + lang: + label: 인터페이스 언어 + text: 사용자 인터페이스 언어입니다. 페이지를 새로고침하면 변경됩니다. + my_logins: + title: 내 로그인 정보 + label: 이 사이트에서 이 계정으로 로그인하거나 가입하세요. + modal_title: 로그인 제거 + modal_content: 이 계정에서 이 로그인을 제거하시겠습니까? + modal_confirm_btn: 제거 + remove_success: 제거되었습니다. + toast: + update: 업데이트 성공 + update_password: 비밀번호가 성공적으로 변경되었습니다. + flag_success: 신고 감사합니다. + forbidden_operate_self: 자신에 대한 작업은 금지되어 있습니다. + review: 검토 후에 귀하의 수정 사항이 표시됩니다. + sent_success: 전송 성공 + related_question: + title: 관련된 질문 + answers: 답변 + linked_question: + title: 링크된 질문 + description: 이 질문을 링크한 질문 + no_linked_question: 이 질문에 연결된 질문 없음. + invite_to_answer: + title: 질문자 초대 + desc: 답변을 알고 있을 것으로 생각되는 사람을 선택하세요. + invite: 답변 초대 + add: 사람 추가 + search: 사람 검색 + question_detail: + action: 동작 + created: Created + Asked: 질문함 + asked: 질문 작성 + update: 수정됨 + Edited: Edited + edit: 편집됨 + commented: 댓글 작성 + Views: 조회수 + Follow: 팔로우 + Following: 팔로잉 중 + follow_tip: 이 질문을 팔로우하여 알림을 받으세요. + answered: 답변 작성 + closed_in: 답변 종료 + show_exist: 기존 질문 표시 + useful: 유용함 + question_useful: 유용하고 명확함 + question_un_useful: 불명확하거나 유용하지 않음 + question_bookmark: 이 질문 즐겨찾기 + answer_useful: 유용함 + answer_un_useful: 유용하지 않음 + answers: + title: 답변 + score: 점수 + newest: 최신순 + oldest: 오래된 순 + btn_accept: 채택 + btn_accepted: 채택됨 + write_answer: + title: 당신의 답변 + edit_answer: 내 답변 편집하기 + btn_name: 답변 게시하기 + add_another_answer: 다른 답변 추가 + confirm_title: 답변 계속하기 + continue: 계속 + confirm_info: >- +

        다른 답변을 추가하시겠습니까?

        대신 기존 답변을 향상시키고 개선할 수 있는 수정 링크를 사용할 수 있습니다.

        + empty: 답변을 입력해주세요. + characters: 내용은 최소 6자 이상이어야 합니다. + tips: + header_1: 답변해 주셔서 감사합니다 + li1_1: 질문에 답변을 제공하세요. 세부 사항을 설명하고 연구 결과를 공유하세요. + li1_2: 발언을 뒷받침하는 자료나 개인적인 경험을 통해 주장을 뒷받침하세요. + header_2: 하지만 피해야 할 것들 ... + li2_1: 도움을 요청하거나 해명을 구하거나 다른 답변에 응답하는 것. + reopen: + confirm_btn: 다시 열기 + title: 이 게시물 다시 열기 + content: 정말 다시 열기를 원하시나요? + list: + confirm_btn: 목록 + title: 이 게시물 목록에 추가하기 + content: 정말 목록에 추가하시겠습니까? + unlist: + confirm_btn: 목록 해제 + title: 이 게시물 목록에서 제외하기 + content: 정말 목록에서 제외하시겠습니까? + pin: + title: 이 게시물 고정하기 + content: 글로벌로 고정하시겠습니까? 이 게시물은 모든 게시물 목록 상단에 표시됩니다. + confirm_btn: 고정하기 + delete: + title: 이 게시물 삭제하기 + question: >- +

        답변이 있는 질문을 삭제하는 것은 권장하지 않습니다 이는 이 지식을 필요로 하는 사용자에게 정보를 제공하지 못하게 될 수 있습니다.

        답변이 있는 질문을 반복적으로 삭제하는 경우 질문 권한이 차단될 수 있습니다. 정말 삭제하시겠습니까? + answer_accepted: >- +

        채택된 답변을 삭제하는 것은 권장하지 않습니다 이는 이 지식을 필요로 하는 사용자에게 정보를 제공하지 못하게 될 수 있습니다.

        채택된 답변을 반복적으로 삭제하는 경우 답변 권한이 차단될 수 있습니다. 정말 삭제하시겠습니까? + other: 정말 삭제하시겠습니까? + tip_answer_deleted: 이 답변은 삭제되었습니다. + undelete_title: 이 게시물 복구하기 + undelete_desc: 정말 복구하시겠습니까? + btns: + confirm: 확인 + cancel: 취소 + edit: 편집 + save: 저장 + delete: 삭제 + undelete: 복구 + list: 목록 + unlist: 목록 해제 + unlisted: 목록에서 해제됨 + login: 로그인 + signup: 가입하기 + logout: 로그아웃 + verify: 확인 + create: 생성 + approve: 승인 + reject: 거부 + skip: 건너뛰기 + discard_draft: 임시 저장 삭제 + pinned: 고정됨 + all: 모두 + question: 질문 + answer: 답변 + comment: 댓글 + refresh: 새로 고침 + resend: 재전송 + deactivate: 비활성화 + active: 활성화 + suspend: 정지 + unsuspend: 정지 해제 + close: 닫기 + reopen: 다시 열기 + ok: 확인 + light: 밝게 + dark: 어둡게 + system_setting: 시스템 설정 + default: 기본 + reset: 재설정 + tag: 태그 + post_lowercase: 게시물 + filter: 필터 + ignore: 무시 + submit: 제출 + normal: 일반 + closed: 닫힘 + deleted: 삭제됨 + deleted_permanently: 영구 삭제 + pending: 보류 중 + more: 더 보기 + view: 보기 + card: 카드 + compact: 간단히 + display_below: 아래에 표시 + always_display: 항상 표시 + or: 또는 + back_sites: 사이트로 돌아가기 + search: + title: 검색 결과 + keywords: 키워드 + options: 옵션 + follow: 팔로우 + following: 팔로잉 중 + counts: "{{count}} 개의 결과" + counts_loading: "... 개의 결과" + more: 더 보기 + sort_btns: + relevance: 관련성 + newest: 최신순 + active: 활성순 + score: 평점순 + more: 더 보기 + tips: + title: 고급 검색 팁 + tag: "<1>[태그] 태그로 검색" + user: "<1>user:사용자명 작성자로 검색" + answer: "<1>answers:0 답변이 없는 질문" + score: "<1>score:3 평점이 3 이상인 글" + question: "<1>is:question 질문만 검색" + is_answer: "<1>is:answer 답변만 검색" + empty: 아무것도 찾지 못했습니다.
        다른 키워드를 사용하거나 덜 구체적인 검색을 시도하세요. + share: + name: 공유 + copy: 링크 복사 + via: 포스트 공유하기... + copied: 복사됨 + facebook: Facebook에 공유 + twitter: X에 공유하기 + cannot_vote_for_self: 자신의 글에 투표할 수 없습니다. + modal_confirm: + title: 오류... + delete_permanently: + title: 영구 삭제 + content: 영구적으로 삭제하시겠습니까? + account_result: + success: 새 계정이 확인되었습니다. 홈페이지로 이동합니다. + link: 홈페이지로 이동 + oops: 이런! + invalid: 사용하신 링크가 더 이상 작동하지 않습니다. + confirm_new_email: 이메일이 업데이트되었습니다. + confirm_new_email_invalid: >- + 죄송합니다, 이 확인 링크는 더 이상 유효하지 않습니다. 이미 이메일이 변경된 상태일 수 있습니다. + unsubscribe: + page_title: 구독 해지 + success_title: 구독 해지 완료 + success_desc: 이 구독자 목록에서 성공적으로 제거되었으며, 더 이상 우리로부터 어떠한 이메일도 받지 않게 됩니다. + link: 설정 변경하기 + question: + following_tags: 팔로우 태그 + edit: 수정 + save: 저장 + follow_tag_tip: 질문 목록을 관리하기 위해 태그를 팔로우하세요. + hot_questions: 인기 질문 + all_questions: 모든 질문 + x_questions: "{{ count }} 개의 질문" + x_answers: "{{ count }} 개의 답변" + x_posts: "{{ count }} 개의 글" + questions: 질문 + answers: 답변 + newest: 최신순 + active: 활성순 + hot: 인기 + frequent: 빈도 + recommend: 추천 + score: 평점순 + unanswered: 답변이 없는 질문 + modified: 수정됨 + answered: 답변됨 + asked: 질문됨 + closed: 닫힘 + follow_a_tag: 태그 팔로우하기 + more: 더 보기 + personal: + overview: 개요 + answers: 답변 + answer: 답변 + questions: 질문 + question: 질문 + bookmarks: 즐겨찾기 + reputation: 평판 + comments: 댓글 + votes: 투표 + badges: 뱃지 + newest: 최신순 + score: 평점순 + edit_profile: 프로필 수정 + visited_x_days: "{{ count }} 일 방문함" + viewed: 조회됨 + joined: 가입일 + comma: "," + last_login: 최근 접속 + about_me: 자기 소개 + about_me_empty: "// 안녕하세요, 세상아 !" + top_answers: 최고 답변 + top_questions: 최고 질문 + stats: 통계 + list_empty: 게시물을 찾을 수 없습니다.
        다른 탭을 선택하실 수 있습니다. + content_empty: 게시물을 찾을 수 없습니다. + accepted: 채택됨 + answered: 답변됨 + asked: 질문됨 + downvoted: 다운투표됨 + mod_short: MOD + mod_long: 관리자 + x_reputation: 평판 + x_votes: 받은 투표 + x_answers: 답변 + x_questions: 질문 + recent_badges: 최근 배지 + install: + title: 설치 + next: 다음 + done: 완료 + config_yaml_error: config.yaml 파일을 생성할 수 없습니다. + lang: + label: 언어 선택 + db_type: + label: 데이터베이스 엔진 + db_username: + label: 사용자 이름 + placeholder: root + msg: 사용자 이름은 비워둘 수 없습니다. + db_password: + label: 비밀번호 + placeholder: root + msg: 비밀번호는 비워둘 수 없습니다. + db_host: + label: 데이터베이스 호스트 + placeholder: "db:3306" + msg: 데이터베이스 호스트는 비워둘 수 없습니다. + db_name: + label: 데이터베이스 이름 + placeholder: 답변 + msg: 데이터베이스 이름은 비워둘 수 없습니다. + db_file: + label: 데이터베이스 파일 + placeholder: /data/answer.db + msg: 데이터베이스 파일은 비워둘 수 없습니다. + ssl_enabled: + label: SSL 활성화 + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL 모드 + ssl_root_cert: + placeholder: sslrootcert 파일 경로 + msg: sslrootcert 파일 경로는 비워둘 수 없습니다 + ssl_cert: + placeholder: sslcert 파일 경로 + msg: sslcert 파일 경로는 비워둘 수 없습니다 + ssl_key: + placeholder: sslkey 파일 경로 + msg: sslkey 파일 경로는 비워둘 수 없습니다 + config_yaml: + title: config.yaml 파일 생성 + label: config.yaml 파일이 생성되었습니다. + desc: >- + config.yaml 파일을 <1>/var/wwww/xxx/ 디렉터리에 수동으로 생성하고 아래 텍스트를 붙여넣을 수 있습니다. + info: 위 작업을 완료한 후 "다음" 버튼을 클릭하세요. + site_information: 사이트 정보 + admin_account: 관리자 계정 + site_name: + label: 사이트 이름 + msg: 사이트 이름을 입력하세요. + msg_max_length: 사이트 이름은 최대 30자여야 합니다. + site_url: + label: 사이트 URL + text: 사이트의 주소입니다. + msg: + empty: 사이트 URL을 입력하세요. + incorrect: 올바른 형식의 사이트 URL을 입력하세요. + max_length: 사이트 URL은 최대 512자여야 합니다. + contact_email: + label: 연락처 이메일 + text: 이 사이트에 책임을 지는 주요 연락 이메일 주소입니다. + msg: + empty: 연락처 이메일을 입력하세요. + incorrect: 올바른 형식의 연락처 이메일을 입력하세요. + login_required: + label: 비공개 + switch: 로그인 필요 + text: 로그인한 사용자만 이 커뮤니티에 접근할 수 있습니다. + admin_name: + label: 이름 + msg: 이름을 입력하세요. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: 이름은 2 자 이상 30 자 이하여야 합니다. + admin_password: + label: 비밀번호 + text: >- + 로그인에 필요한 비밀번호입니다. 안전한 위치에 보관하세요. + msg: 비밀번호를 입력하세요. + msg_min_length: 비밀번호는 최소 8자여야 합니다. + msg_max_length: 비밀번호는 최대 32자여야 합니다. + admin_confirm_password: + label: "비밀번호 확인" + text: "확인을 위해 비밀번호를 다시 입력해주세요." + msg: "비밀번호 확인이 일치하지 않습니다." + admin_email: + label: 이메일 + text: 로그인에 필요한 이메일입니다. + msg: + empty: 이메일을 입력하세요. + incorrect: 올바른 형식의 이메일을 입력하세요. + ready_title: 귀하의 사이트가 준비되었습니다 + ready_desc: >- + 추가 설정을 원하시면 <1>관리자 섹션에서 찾아보세요; 사이트 메뉴에서 확인할 수 있습니다. + good_luck: "재미있고 행운을 빕니다!" + warn_title: 경고 + warn_desc: >- + 파일 <1>config.yaml이 이미 존재합니다. 이 파일의 구성 항목 중 재설정이 필요하면 먼저 삭제하세요. + install_now: <1>지금 설치해보세요. + installed: 이미 설치됨 + installed_desc: >- + 이미 설치된 것으로 보입니다. 재설치하려면 먼저 이전 데이터베이스 테이블을 삭제하세요. + db_failed: 데이터베이스 연결 실패 + db_failed_desc: >- + <1>config.yaml 파일에 있는 데이터베이스 정보가 올바르지 않거나 데이터베이스 서버와 연결할 수 없습니다. 호스트의 데이터베이스 서버가 다운된 경우입니다. + counts: + views: 조회수 + votes: 투표 + answers: 답변 + accepted: 채택됨 + page_error: + http_error: HTTP 오류 {{ code }} + desc_403: 이 페이지에 접근할 권한이 없습니다. + desc_404: 죄송합니다. 이 페이지는 존재하지 않습니다. + desc_50X: 서버에서 오류가 발생하여 요청을 완료할 수 없습니다. + back_home: 홈페이지로 돌아가기 + page_maintenance: + desc: "저희는 현재 유지보수 중입니다. 곧 돌아오겠습니다." + nav_menus: + dashboard: 대시보드 + contents: 콘텐츠 + questions: 질문 + answers: 답변 + users: 사용자 + badges: 뱃지 + flags: 신고하기 + settings: 설정 + general: 일반 + interface: 인터페이스 + smtp: SMTP + branding: 브랜딩 + legal: 법적 사항 + write: 글 작성 + terms: Terms + tos: 이용 약관 + privacy: 개인정보 보호 + seo: 검색 엔진 최적화 + customize: 사용자 정의 + themes: 테마 + login: 로그인 + privileges: 권한 + plugins: 플러그인 + installed_plugins: 설치된 플러그인 + apperance: 모양 + website_welcome: '{{site_name}}에 오신 것을 환영합니다' + user_center: + login: 로그인 + qrcode_login_tip: '{{ agentName }}을(를) 사용하여 QR 코드를 스캔하고 로그인하세요.' + login_failed_email_tip: 로그인 실패, 다시 시도하기 전에 이 앱이 이메일 정보에 접근할 수 있도록 허용하세요. + badges: + modal: + title: 축하합니다 + content: 새로운 뱃지를 획득했습니다. + close: 닫기 + confirm: 뱃지 보기 + title: 뱃지 + awarded: 수여됨 + earned_×: '{{ number }} 개 획득' + ×_awarded: "{{ number }} 개 수여됨" + can_earn_multiple: 이 뱃지는 여러 번 획득할 수 있습니다. + earned: 획득함 + admin: + admin_header: + title: 관리자 + dashboard: + title: 대시보드 + welcome: 관리자에 오신 것을 환영합니다! + site_statistics: 사이트 통계 + questions: "질문:" + resolved: "해결됨:" + unanswered: "답변이 없는 질문:" + answers: "답변:" + comments: "댓글:" + votes: "투표:" + users: "사용자:" + flags: "신고:" + reviews: "리뷰:" + site_health: 사이트 상태 + version: "버전:" + https: "HTTPS:" + upload_folder: "업로드 폴더:" + run_mode: "실행 모드:" + private: 비공개 + public: 공개 + smtp: "SMTP:" + timezone: "시간대:" + system_info: 시스템 정보 + go_version: "Go 버전:" + database: "데이터베이스:" + database_size: "데이터베이스 크기:" + storage_used: "사용 중인 저장 공간:" + uptime: "가동 시간:" + links: 링크 + plugins: 플러그인 + github: GitHub + blog: 블로그 + contact: 연락처 + forum: 포럼 + documents: 문서 + feedback: 피드백 + support: 지원 + review: 검토 + config: 설정 + update_to: 업데이트 + latest: 최신 버전 + check_failed: 확인 실패 + "yes": "예" + "no": "아니요" + not_allowed: 허용되지 않음 + allowed: 허용됨 + enabled: 활성화됨 + disabled: 비활성화됨 + writable: 쓰기 가능 + not_writable: 쓰기 불가능 + flags: + title: 신고 + pending: 처리 대기 중 + completed: 완료됨 + flagged: 신고됨 + flagged_type: '{{ type }}로 신고됨' + created: 생성됨 + action: 동작 + review: 검토 + user_role_modal: + title: 사용자 역할 변경 + btn_cancel: 취소 + btn_submit: 제출 + new_password_modal: + title: 새 비밀번호 설정 + form: + fields: + password: + label: 비밀번호 + text: 사용자가 로그아웃되고 다시 로그인해야 합니다. + msg: 비밀번호는 8-32자여야 합니다. + btn_cancel: 취소 + btn_submit: 제출 + edit_profile_modal: + title: 프로필 수정 + form: + fields: + display_name: + label: 표시 이름 + msg_range: 표시 이름은 2-30 자 길이여야 합니다. + username: + label: 사용자 이름 + msg_range: 유저 이름은 2-30 자 길이여야 합니다. + email: + label: 이메일 + msg_invalid: 유효하지 않은 이메일 주소. + edit_success: 성공적으로 수정되었습니다 + btn_cancel: 취소 + btn_submit: 제출 + user_modal: + title: 새 사용자 추가 + form: + fields: + users: + label: 대량 사용자 추가 + placeholder: "홍길동, hong@example.com, BUSYopr2\n김철수, kim@example.com, fpDntV8q" + text: 쉼표로 구분하여 “이름, 이메일, 비밀번호”를 입력하세요. 한 줄에 한 명의 사용자. + msg: "사용자의 이메일을 입력하세요. 한 줄에 한 명씩 입력하세요." + display_name: + label: 표시 이름 + msg: 표시 이름은 2-30 자 길이여야 합니다. + email: + label: 이메일 + msg: 이메일이 유효하지 않습니다. + password: + label: 비밀번호 + msg: 비밀번호는 8-32자여야 합니다. + btn_cancel: 취소 + btn_submit: 제출 + users: + title: 사용자 + name: 이름 + email: 이메일 + reputation: 평판 + created_at: 생성 시간 + delete_at: 삭제된 시간 + suspend_at: 정지된 시간 + suspend_until: 정지 기한 + status: 상태 + role: 역할 + action: 동작 + change: 변경 + all: 전체 + staff: 스탭 + more: 더 보기 + inactive: 비활성화됨 + suspended: 정지됨 + deleted: 삭제됨 + normal: 일반 + Moderator: 관리자 + Admin: 관리자 + User: 사용자 + filter: + placeholder: "이름 또는 사용자 ID로 필터링" + set_new_password: 새 비밀번호 설정 + edit_profile: 프로필 수정 + change_status: 상태 변경 + change_role: 역할 변경 + show_logs: 로그 표시 + add_user: 사용자 추가 + deactivate_user: + title: 사용자 비활성화 + content: 비활성화된 사용자는 이메일을 다시 확인해야 합니다. + delete_user: + title: 이 사용자 삭제 + content: 정말로 이 사용자를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다! + remove: 사용자의 모든 질문, 답변, 댓글 등을 삭제합니다. + label: 사용자의 계정만 삭제하려면 이 옵션을 선택하지 마세요. + text: 사용자의 계정만 삭제하려면 이 항목을 선택하지 마십시오. + suspend_user: + title: 이 사용자 정지 + content: 정지된 사용자는 로그인할 수 없습니다. + label: 사용자를 며칠 접근 금지 하시겠습니까? + forever: 무기한 + questions: + page_title: 질문 + unlisted: 비공개 + post: 게시물 + votes: 투표 + answers: 답변 + created: 생성됨 + status: 상태 + action: 동작 + change: 변경 + pending: 대기 중 + filter: + placeholder: "제목 또는 질문 ID로 필터링" + answers: + page_title: 답변 + post: 게시물 + votes: 투표 + created: 생성됨 + status: 상태 + action: 동작 + change: 변경 + filter: + placeholder: "제목 또는 답변 ID로 필터링" + general: + page_title: 일반 + name: + label: 사이트 이름 + msg: 사이트 이름을 입력하세요. + text: "사이트 이름, 타이틀 태그에 사용됩니다." + site_url: + label: 사이트 URL + msg: 사이트 URL을 입력하세요. + validate: 유효한 URL을 입력하세요. + text: 사이트 주소입니다. + short_desc: + label: 짧은 사이트 설명 + msg: 짧은 사이트 설명을 입력하세요. + text: "홈페이지에서 사용되는 짧은 설명입니다." + desc: + label: 사이트 설명 + msg: 사이트 설명을 입력하세요. + text: "메타 설명 태그에 사용되는 한 문장 설명입니다." + contact_email: + label: 연락처 이메일 + msg: 연락처 이메일을 입력하세요. + validate: 유효한 이메일 주소를 입력하세요. + text: 사이트를 책임지는 주요 연락처 이메일 주소입니다. + check_update: + label: 소프트웨어 업데이트 + text: 소프트웨어 업데이트 자동 확인 + interface: + page_title: 인터페이스 + language: + label: 인터페이스 언어 + msg: 인터페이스 언어를 선택하세요. + text: 페이지를 새로고침하면 언어가 변경됩니다. + time_zone: + label: 시간대 + msg: 시간대를 선택하세요. + text: 본인과 같은 시간대의 도시를 선택하세요. + avatar: + label: 기본 아바타 + text: 사용자 정의 아바타가 없는 사용자에게 표시됩니다. + gravatar_base_url: + label: Gravatar 기본 URL + text: Gravatar 공급자의 API 기본 URL입니다. 비어 있으면 무시됩니다. + smtp: + page_title: SMTP + from_email: + label: 발신 이메일 + msg: 발신 이메일을 입력하세요. + text: 이메일 발신 주소입니다. + from_name: + label: 발신자 이름 + msg: 발신자 이름을 입력하세요. + text: 이메일 발신 시 사용될 이름입니다. + smtp_host: + label: SMTP 호스트 + msg: SMTP 호스트를 입력하세요. + text: 메일 서버 주소입니다. + encryption: + label: 암호화 + msg: 암호화 방식을 선택하세요. + text: 대부분의 서버에서 SSL을 권장합니다. + ssl: SSL + tls: TLS + none: 없음 + smtp_port: + label: SMTP 포트 + msg: SMTP 포트는 1에서 65535 사이의 숫자여야 합니다. + text: 메일 서버의 포트 번호입니다. + smtp_username: + label: SMTP 사용자 이름 + msg: SMTP 사용자 이름을 입력하세요. + smtp_password: + label: SMTP 비밀번호 + msg: SMTP 비밀번호를 입력하세요. + test_email_recipient: + label: 테스트 이메일 수신자 + text: 테스트 이메일을 받을 이메일 주소를 입력하세요. + msg: 테스트 이메일 수신자가 유효하지 않습니다. + smtp_authentication: + label: 인증 사용 + title: SMTP 인증 + msg: SMTP 인증을 선택하세요. + "yes": "예" + "no": "아니오" + branding: + page_title: 브랜딩 + logo: + label: 로고 + msg: 로고를 입력하세요. + text: 사이트 좌측 상단에 표시될 로고 이미지입니다. 넓은 직사각형 이미지로, 높이는 56 이상이어야 하며 가로 세로 비율은 3:1 이상이어야 합니다. 비워 둘 경우 사이트 제목 텍스트가 표시됩니다. + mobile_logo: + label: 모바일 로고 + text: 사이트의 모바일 버전에서 사용할 로고 이미지입니다. 넓은 직사각형 이미지로, 높이는 56 이상이어야 합니다. 비워 둘 경우 "로고" 설정에서 이미지가 사용됩니다. + square_icon: + label: 정사각형 아이콘 + msg: 정사각형 아이콘을 입력하세요. + text: 메타데이터 아이콘의 기본 이미지로 사용됩니다. 이상적으로는 512x512보다 큰 이미지여야 합니다. + favicon: + label: 파비콘 + text: 사이트의 파비콘 이미지입니다. CDN에서 정상적으로 작동하려면 png 형식이어야 하며, 크기는 32x32로 조정됩니다. 비워 둘 경우 "정사각형 아이콘"이 사용됩니다. + legal: + page_title: 법적 고지 + terms_of_service: + label: 서비스 이용 약관 + text: "여기에 서비스 이용 약관 내용을 추가할 수 있습니다. 이미 다른 곳에 문서가 호스팅되어 있다면 전체 URL을 여기에 제공하세요." + privacy_policy: + label: 개인정보 보호 정책 + text: "여기에 개인정보 보호 정책 내용을 추가할 수 있습니다. 이미 다른 곳에 문서가 호스팅되어 있다면 전체 URL을 여기에 제공하세요." + external_content_display: + label: 외부 콘텐츠 + text: "콘텐츠에는 외부 웹사이트에서 삽입된 이미지, 비디오 및 미디어가 포함됩니다." + always_display: 항상 외부 콘텐츠 표시 + ask_before_display: 외부 콘텐츠 표시 전 확인 + write: + page_title: 작성 + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: 답변 작성 + label: 각 사용자는 각 질문에 대해 단 하나의 답변만 작성할 수 있습니다. + text: "기존 답변을 개선하고 향상시키기 위해 편집 링크를 사용할 수 있습니다." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: 추천 태그 + text: "추천 태그가 기본적으로 드롭다운 목록에 표시됩니다." + msg: + contain_reserved: "추천 태그에는 예약된 태그가 포함될 수 없습니다" + required_tag: + title: 필수 태그 설정 + label: '"추천 태그" 를 필수 태그로 설정' + text: "모든 새로운 질문은 최소한 하나의 추천 태그가 있어야 합니다." + reserved_tags: + label: 예약된 태그 + text: "예약된 태그는 관리자만 사용할 수 있습니다." + image_size: + label: 최대 이미지 크기 (MB) + text: "최대 이미지 업로드 크기입니다." + attachment_size: + label: 최대 첨부 파일 크기 (MB) + text: "최대 첨부 파일 업로드 크기입니다." + image_megapixels: + label: 최대 이미지 메가픽셀 + text: "이미지에 허용되는 최대 메가픽셀 수입니다." + image_extensions: + label: 허용된 이미지 확장자 + text: "이미지 표시가 허용된 파일 확장자 목록입니다. 쉼표로 구분하세요." + attachment_extensions: + label: 인증된 첨부 파일 확장자 + text: "업로드가 허용된 파일 확장자 목록입니다. 쉼표로 구분하세요. 경고: 업로드를 허용하면 보안 문제가 발생할 수 있습니다." + seo: + page_title: 검색 엔진 최적화 + permalink: + label: 영구 링크 + text: 사용자 정의 URL 구조는 링크의 사용성과 미래 호환성을 향상시킬 수 있습니다. + robots: + label: robots.txt + text: 이 설정은 사이트 설정과 관련된 내용을 영구적으로 덮어씁니다. + themes: + page_title: 테마 + themes: + label: 테마 + text: 기존 테마를 선택하세요. + color_scheme: + label: 색상 스키마 + navbar_style: + label: 네비바 배경 스타일 + primary_color: + label: 주요 색상 + text: 테마에서 사용할 색상을 수정합니다. + css_and_html: + page_title: CSS 및 HTML + custom_css: + label: 사용자 정의 CSS + text: > + + head: + label: 헤드 + text: > + + header: + label: 헤더 + text: > + + footer: + label: 푸터 + text: 본문의 바로 앞에 삽입됩니다. + sidebar: + label: 사이드바 + text: 사이드바에 삽입됩니다. + login: + page_title: 로그인 + membership: + title: 멤버십 + label: 신규 등록 허용 + text: 계정을 생성할 수 있는 사람을 제한하려면 끄세요. + email_registration: + title: 이메일 등록 + label: 이메일 등록 허용 + text: 이메일을 통한 새 계정 생성을 막으려면 끄세요. + allowed_email_domains: + title: 허용된 이메일 도메인 + text: 사용자가 계정을 등록할 때 필수적으로 사용해야 하는 이메일 도메인입니다. 한 줄에 하나의 도메인을 입력하세요. 비어 있으면 무시됩니다. + private: + title: 비공개 + label: 로그인 필수 + text: 로그인한 사용자만이 이 커뮤니티에 접근할 수 있습니다. + password_login: + title: 비밀번호 로그인 + label: 이메일과 비밀번호 로그인 허용 + text: "경고: 끄면 다른 로그인 방법을 설정하지 않았다면 로그인할 수 없을 수 있습니다." + installed_plugins: + title: 설치된 플러그인 + plugin_link: 플러그인은 기능을 확장하고 확장합니다. <1> 플러그인 저장소에서 플러그인을 찾을 수 있습니다. + filter: + all: 전체 + active: 활성화됨 + inactive: 비활성화됨 + outdated: 오래된 상태 + plugins: + label: 플러그인 + text: 기존 플러그인을 선택하세요. + name: 이름 + version: 버전 + status: 상태 + action: 작업 + deactivate: 비활성화 + activate: 활성화 + settings: 설정 + settings_users: + title: 사용자 + avatar: + label: 기본 아바타 + text: 사용자가 자신의 사용자 정의 아바타를 가지지 않았을 때 표시됩니다. + gravatar_base_url: + label: Gravatar 기본 URL + text: Gravatar 공급자의 API 기본 URL입니다. 비어 있으면 무시됩니다. + profile_editable: + title: 프로필 편집 가능 + allow_update_display_name: + label: 사용자가 표시 이름을 변경할 수 있도록 허용 + allow_update_username: + label: 사용자가 사용자 이름을 변경할 수 있도록 허용 + allow_update_avatar: + label: 사용자가 프로필 이미지를 변경할 수 있도록 허용 + allow_update_bio: + label: 사용자가 자기 소개를 변경할 수 있도록 허용 + allow_update_website: + label: 사용자가 웹사이트를 변경할 수 있도록 허용 + allow_update_location: + label: 사용자가 위치 정보를 변경할 수 있도록 허용 + privilege: + title: 권한 + level: + label: 권한에 필요한 평판 레벨 + text: 권한에 필요한 평판 레벨을 선택하세요. + msg: + should_be_number: 입력값은 숫자여야 합니다. + number_larger_1: 숫자는 1 이상이어야 합니다. + badges: + action: 동작 + active: 활성 + activate: 활성화 + all: 모두 + awards: 수상 + deactivate: 비활성화 + filter: + placeholder: 이름, 배지:id 로 필터링 + group: 그룹 + inactive: 비활성 + name: 이름 + show_logs: 로그 표시 + status: 상태 + title: 뱃지 + form: + optional: (선택 사항) + empty: 비어 있을 수 없습니다 + invalid: 유효하지 않습니다 + btn_submit: 저장 + not_found_props: "필수 속성 {{ key }}을(를) 찾을 수 없습니다." + select: 선택 + page_review: + review: 리뷰 + proposed: 제안된 + question_edit: 질문 편집 + answer_edit: 답변 편집 + tag_edit: 태그 편집 + edit_summary: 편집 요약 + edit_question: 질문 편집 + edit_answer: 답변 편집 + edit_tag: 태그 편집 + empty: 남은 리뷰 작업이 없습니다. + approve_revision_tip: 이 리비전을 승인하시겠습니까? + approve_flag_tip: 이 신고를 승인하시겠습니까? + approve_post_tip: 이 게시물을 승인하시겠습니까? + approve_user_tip: 이 사용자를 승인하시겠습니까? + suggest_edits: 제안된 편집 + flag_post: 게시물 신고 + flag_user: 사용자 신고 + queued_post: 대기 중인 게시물 + queued_user: 대기 중인 사용자 + filter_label: 유형 + reputation: 평판 + flag_post_type: 이 게시물을 {{ type }}로 신고 처리했습니다. + flag_user_type: 이 사용자를 {{ type }}로 신고 처리했습니다. + edit_post: 게시물 편집 + list_post: 게시물 목록 + unlist_post: 게시물 비공개 + timeline: + undeleted: 복구됨 + deleted: 삭제됨 + downvote: 다운보트 + upvote: 업보트 + accept: 채택됨 + cancelled: 취소됨 + commented: 댓글 작성됨 + rollback: 롤백 + edited: 편집됨 + answered: 답변됨 + asked: 질문됨 + closed: 닫힘 + reopened: 다시 열림 + created: 생성됨 + pin: 고정됨 + unpin: 고정 해제됨 + show: 공개됨 + hide: 비공개됨 + title: "다음을 위한 히스토리" + tag_title: "태그에 대한 타임라인" + show_votes: "투표 보기" + n_or_a: 없음 + title_for_question: "질문에 대한 타임라인" + title_for_answer: "{{ author }}가 {{ title }}에 대한 답변에 대한 타임라인" + title_for_tag: "태그에 대한 타임라인" + datetime: 날짜 및 시간 + type: 유형 + by: 작성자 + comment: 코멘트 + no_data: "아무 데이터도 찾을 수 없습니다." + users: + title: 사용자 + users_with_the_most_reputation: 이번 주 평판이 가장 높은 사용자들 + users_with_the_most_vote: 이번 주 투표를 가장 많이 한 사용자들 + staffs: 우리 커뮤니티 스태프 + reputation: 평판 + votes: 투표 + prompt: + leave_page: 페이지를 떠나시겠습니까? + changes_not_save: 변경 사항이 저장되지 않을 수 있습니다. + draft: + discard_confirm: 초안을 삭제하시겠습니까? + messages: + post_deleted: 이 게시물은 삭제되었습니다. + post_cancel_deleted: 이 게시물이 삭제 취소되었습니다. + post_pin: 이 게시물이 고정되었습니다. + post_unpin: 이 게시물의 고정이 해제되었습니다. + post_hide_list: 이 게시물이 목록에서 숨겨졌습니다. + post_show_list: 이 게시물이 목록에 표시되었습니다. + post_reopen: 이 게시물이 다시 열렸습니다. + post_list: 이 게시물이 목록에 등록되었습니다. + post_unlist: 이 게시물이 목록에서 등록 해제되었습니다. + post_pending: 회원님의 게시물이 검토를 기다리고 있습니다. 미리보기입니다. 승인 후에 공개됩니다. + post_closed: 이 게시물이 닫혔습니다. + answer_deleted: 이 답변이 삭제되었습니다. + answer_cancel_deleted: 이 답변이 삭제 취소되었습니다. + change_user_role: 이 사용자의 역할이 변경되었습니다. + user_inactive: 이 사용자는 이미 비활성 상태입니다. + user_normal: 이 사용자는 이미 일반 사용자입니다. + user_suspended: 이 사용자가 정지되었습니다. + user_deleted: 이 사용자가 삭제되었습니다. + badge_activated: 이 배지가 활성화되었습니다. + badge_inactivated: 이 배지가 비활성화되었습니다. + users_deleted: 이 사용자들이 삭제되었습니다. + posts_deleted: 이 질문들이 삭제되었습니다. + answers_deleted: 이 답변들이 삭제되었습니다. + copy: 클립보드에 복사 + copied: 복사됨 + external_content_warning: 외부 이미지/미디어가 표시되지 않습니다. + + diff --git a/data/i18n/ml_IN.yaml b/data/i18n/ml_IN.yaml new file mode 100644 index 000000000..07c47bd8d --- /dev/null +++ b/data/i18n/ml_IN.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Success. + unknown: + other: Unknown error. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + forbidden_error: + other: Forbidden. + duplicate_request_error: + other: Duplicate submission. + action: + report: + other: Flag + edit: + other: Edit + delete: + other: Delete + close: + other: Close + reopen: + other: Reopen + forbidden_error: + other: Forbidden. + pin: + other: Pin + hide: + other: Unlist + unpin: + other: Unpin + show: + other: List + invite_someone_to_answer: + other: Edit + undelete: + other: Undelete + merge: + other: Merge + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + privilege: + level_1: + description: + other: Level 1 (less reputation required for private team, group) + level_2: + description: + other: Level 2 (low reputation required for startup community) + level_3: + description: + other: Level 3 (high reputation required for mature community) + level_custom: + description: + other: Custom Level + rank_question_add_label: + other: Ask question + rank_answer_add_label: + other: Write answer + rank_comment_add_label: + other: Write comment + rank_report_add_label: + other: Flag + rank_comment_vote_up_label: + other: Upvote comment + rank_link_url_limit_label: + other: Post more than 2 links at a time + rank_question_vote_up_label: + other: Upvote question + rank_answer_vote_up_label: + other: Upvote answer + rank_question_vote_down_label: + other: Downvote question + rank_answer_vote_down_label: + other: Downvote answer + rank_invite_someone_to_answer_label: + other: Invite someone to answer + rank_tag_add_label: + other: Create new tag + rank_tag_edit_label: + other: Edit tag description (need to review) + rank_question_edit_label: + other: Edit other's question (need to review) + rank_answer_edit_label: + other: Edit other's answer (need to review) + rank_question_edit_without_review_label: + other: Edit other's question without review + rank_answer_edit_without_review_label: + other: Edit other's answer without review + rank_question_audit_label: + other: Review question edits + rank_answer_audit_label: + other: Review answer edits + rank_tag_audit_label: + other: Review tag edits + rank_tag_edit_without_review_label: + other: Edit tag description without review + rank_tag_synonym_label: + other: Manage tag synonyms + email: + other: Email + e_mail: + other: Email + password: + other: Password + pass: + other: Password + old_pass: + other: Current password + original_text: + other: This post + email_or_password_wrong_error: + other: Email and password do not match. + error: + common: + invalid_url: + other: Invalid URL. + status_invalid: + other: Invalid status. + password: + space_invalid: + other: Password cannot contain spaces. + admin: + cannot_update_their_password: + other: You cannot modify your password. + cannot_edit_their_profile: + other: You cannot modify your profile. + cannot_modify_self_status: + other: You cannot modify your status. + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + question_closed_cannot_add: + other: Questions are closed and cannot be added. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + illegal_email_domain_error: + other: Email is not allowed from that email domain. Please use another one. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + already_deleted: + other: This post has been deleted. + meta: + object_not_found: + other: Meta object not found + question: + already_deleted: + other: This post has been deleted. + under_review: + other: Your post is awaiting review. It will be visible after it has been approved. + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Reputation rank fail to meet the condition. + vote_fail_to_meet_the_condition: + other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. + no_enough_rank_to_operate: + other: You need at least {{.Rank}} reputation to do this. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + already_exist: + other: Tag already exists. + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + is_used_cannot_delete: + other: You cannot delete a tag that is in use. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: The from name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to revise. + user: + external_login_missing_user_id: + other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. + external_login_unbinding_forbidden: + other: Please set a login password for your account before you remove this login. + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration. + not_allowed_login_via_password: + other: Currently the site is not allowed to login via password. + access_denied: + other: Access denied + page_access_denied: + other: You do not have access to this page. + add_bulk_users_format_error: + other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + site_info: + config_not_found: + other: Site config not found. + badge: + object_not_found: + other: Badge object not found + reason: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude_or_abusive: + name: + other: rude or abusive + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + a_duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + placeholder: + other: Enter the existing question link + not_a_answer: + name: + other: not an answer + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." + no_longer_needed: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + something: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + placeholder: + other: Let us know specifically what you are concerned about + community_specific: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + not_clarity: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + looks_ok: + name: + other: looks OK + desc: + other: This post is good as-is and not low quality. + needs_edit: + name: + other: needs edit, and I did it + desc: + other: Improve and correct problems with this post yourself. + needs_close: + name: + other: needs close + desc: + other: A closed question can't answer, but still can edit, vote and comment. + needs_delete: + name: + other: needs delete + desc: + other: This post will be deleted. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + deleted_title: + other: Deleted question + questions_title: + other: Questions + tag: + tags_title: + other: Tags + no_description: + other: The tag has no description. + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted + up_voted_question: + other: upvoted question + down_voted_question: + other: downvoted question + up_voted_answer: + other: upvoted answer + down_voted_answer: + other: downvoted answer + up_voted_comment: + other: upvoted comment + invited_you_to_answer: + other: invited you to answer + earned_badge: + other: You've earned the "{{.BadgeName}}" badge + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Confirm your new email address" + body: + other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} answered your question" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n

        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_question: + title: + other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Password reset" + body: + other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + register: + title: + other: "[{{.SiteName}}] Confirm your new account" + body: + other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + test: + title: + other: "[{{.SiteName}}] Test Email" + body: + other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + action_activity_type: + upvote: + other: upvote + upvoted: + other: upvoted + downvote: + other: downvote + downvoted: + other: downvoted + accept: + other: accept + accepted: + other: accepted + edit: + other: edit + review: + queued_post: + other: Queued post + flagged_post: + other: Flagged post + suggested_post_edit: + other: Suggested edits + reaction: + tooltip: + other: "{{ .Names }} and {{ .Count }} more..." + badge: + default_badges: + autobiographer: + name: + other: Autobiographer + desc: + other: Filled out profile information. + certified: + name: + other: Certified + desc: + other: Completed our new user tutorial. + editor: + name: + other: Editor + desc: + other: First post edit. + first_flag: + name: + other: First Flag + desc: + other: First flagged a post. + first_upvote: + name: + other: First Upvote + desc: + other: First up voted a post. + first_link: + name: + other: First Link + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: First Share + desc: + other: First shared a post. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Leave 5 comments. + new_user_of_the_month: + name: + other: New User of the Month + desc: + other: Outstanding contributions in their first month. + read_guidelines: + name: + other: Read Guidelines + desc: + other: Read the [community guidelines]. + reader: + name: + other: Reader + desc: + other: Read every answers in a topic with more than 10 answers. + welcome: + name: + other: Welcome + desc: + other: Received a up vote. + nice_share: + name: + other: Nice Share + desc: + other: Shared a post with 25 unique visitors. + good_share: + name: + other: Good Share + desc: + other: Shared a post with 300 unique visitors. + great_share: + name: + other: Great Share + desc: + other: Shared a post with 1000 unique visitors. + out_of_love: + name: + other: Out of Love + desc: + other: Used 50 up votes in a day. + higher_love: + name: + other: Higher Love + desc: + other: Used 50 up votes in a day 5 times. + crazy_in_love: + name: + other: Crazy in Love + desc: + other: Used 50 up votes in a day 20 times. + promoter: + name: + other: Promoter + desc: + other: Invited a user. + campaigner: + name: + other: Campaigner + desc: + other: Invited 3 basic users. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: Thank You + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Active member for a year, posted at least once. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + create_tag: Create Tag + edit_tag: Edit Tag + ask_a_question: Create Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + oauth_callback: Processing + http_404: HTTP Error 404 + http_50X: HTTP Error 500 + http_403: HTTP Error 403 + logout: Log Out + posts: Posts + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + new_alerts: New alerts + all_read: Mark all as read + show_more: Show more + someone: Someone + inbox_type: + all: All + posts: Posts + invites: Invites + votes: Votes + answer: Answer + question: Question + badge_award: Badge + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + contact_us: Contact us + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image file + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed {{size}} MB. + desc: + label: Description + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered list + unordered_list: + text: Bulleted list + table: + text: Table + heading: Heading + cell: Cell + file: + text: Attach files + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + not_a_url: URL format is incorrect. + url_not_match: URL origin does not match the current website. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description + revision: + label: Revision + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_cancel: Cancel + btn_submit: Submit + btn_post: Post new tag + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + tip_with_posts: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + tip_with_synonyms: >- +

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        + tip: Are you sure you wish to delete? + close: Close + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + default_first_reason: Add tag + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + hours: hours + days: days + month: month + months: months + year: year + reaction: + heart: heart + smile: smile + frown: frown + btn_label: add or remove reactions + undo_emoji: undo {{ emoji }} reaction + react_emoji: react with {{ emoji }} + unreact_emoji: unreact with {{ emoji }} + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: "{{count}} more comments" + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + tip_vote: It adds something useful to the post + edit_answer: + title: Edit Answer + default_reason: Edit answer + default_first_reason: Add answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: Newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + wiki: Wiki + ask: + title: Create Question + edit_title: Edit Question + default_reason: Edit question + default_first_reason: Create question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: What's your topic? Be specific. + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + badges: Badges + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + bookmark: Bookmarks + moderation: Moderation + search: + placeholder: Search + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + resend_email: + url_label: Are you sure you want to resend the activation email? + url_text: You can also give the activation link above to the user. + login: + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New email + msg: + empty: Email cannot be empty. + oauth: + connect: Connect with {{ auth_name }} + remove: Remove {{ auth_name }} + oauth_bind_email: + subtitle: Add a recovery email to your account. + btn_update: Update email address + email: + label: Email + msg: + empty: Email cannot be empty. + modal_title: Email already existes. + modal_content: This email address already registered. Are you sure you want to connect to the existing account? + modal_cancel: Change email + modal_confirm: Connect to the existing account + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm new password + settings: + page_title: Settings + goto_modify: Go to modify + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile image + gravatar: Gravatar + gravatar_text: You can change image on + custom: Custom + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About me + website: + label: Website + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location + placeholder: "City, Country" + notification: + heading: Email Notifications + turn_on: Turn on + inbox: + label: Inbox notifications + description: Answers to your questions, comments, invites, and more. + all_new_question: + label: All new questions + description: Get notified of all new questions. Up to 50 questions per week. + all_new_question_for_following_tags: + label: All new questions for following tags + description: Get notified of new questions for following tags. + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + pass: + label: Current password + msg: Password cannot be empty. + password_title: Password + current_pass: + label: Current password + msg: + empty: Current password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New password + pass_confirm: + label: Confirm new password + interface: + heading: Interface + lang: + label: Interface language + text: User interface language. It will change when you refresh the page. + my_logins: + title: My logins + label: Log in or sign up on this site using these accounts. + modal_title: Remove login + modal_content: Are you sure you want to remove this login from your account? + modal_confirm_btn: Remove + remove_success: Removed successfully + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + sent_success: Sent successfully + related_question: + title: Related + answers: answers + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Invite People + desc: Invite people you think can answer. + invite: Invite to answer + add: Add people + search: Search people + question_detail: + action: Action + created: Created + Asked: Asked + asked: asked + update: Modified + Edited: Edited + edit: edited + commented: commented + Views: Viewed + Follow: Follow + Following: Following + follow_tip: Follow this question to receive notifications + answered: answered + closed_in: Closed in + show_exist: Show existing question. + useful: Useful + question_useful: It is useful and clear + question_un_useful: It is unclear or not useful + question_bookmark: Bookmark this question + answer_useful: It is useful + answer_un_useful: It is not useful + answers: + title: Answers + score: Score + newest: Newest + oldest: Oldest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + edit_answer: Edit my existing answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + tips: + header_1: Thanks for your answer + li1_1: Please be sure to answer the question. Provide details and share your research. + li1_2: Back up any statements you make with references or personal experience. + header_2: But avoid ... + li2_1: Asking for help, seeking clarification, or responding to other answers. + reopen: + confirm_btn: Reopen + title: Reopen this post + content: Are you sure you want to reopen? + list: + confirm_btn: List + title: List this post + content: Are you sure you want to list? + unlist: + confirm_btn: Unlist + title: Unlist this post + content: Are you sure you want to unlist? + pin: + title: Pin this post + content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. + confirm_btn: Pin + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_answer_deleted: This answer has been deleted + undelete_title: Undelete this post + undelete_desc: Are you sure you wish to undelete? + btns: + confirm: Confirm + cancel: Cancel + edit: Edit + save: Save + delete: Delete + undelete: Undelete + list: List + unlist: Unlist + unlisted: Unlisted + login: Log in + signup: Sign up + logout: Log out + verify: Verify + create: Create + approve: Approve + reject: Reject + skip: Skip + discard_draft: Discard draft + pinned: Pinned + all: All + question: Question + answer: Answer + comment: Comment + refresh: Refresh + resend: Resend + deactivate: Deactivate + active: Active + suspend: Suspend + unsuspend: Unsuspend + close: Close + reopen: Reopen + ok: OK + light: Light + dark: Dark + system_setting: System setting + default: Default + reset: Reset + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignore + submit: Submit + normal: Normal + closed: Closed + deleted: Deleted + deleted_permanently: Deleted permanently + pending: Pending + more: More + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + counts_loading: "... Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post. + modal_confirm: + title: Error... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + x_posts: "{{ count }} Posts" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + frequent: Frequent + recommend: Recommend + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + badges: Badges + newest: Newest + score: Score + edit_profile: Edit profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + comma: "," + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + content_empty: No posts found. + accepted: Accepted + answered: answered + asked: asked + downvoted: downvoted + mod_short: MOD + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + recent_badges: Recent Badges + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please choose a language + db_type: + label: Database engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database host + placeholder: "db:3306" + msg: Database host cannot be empty. + db_name: + label: Database name + placeholder: answer + msg: Database name cannot be empty. + db_file: + label: Database file + placeholder: /data/answer.db + msg: Database file cannot be empty. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site name + msg: Site name cannot be empty. + msg_max_length: Site name must be at maximum 30 characters in length. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + max_length: Site URL must be at maximum 512 characters in length. + contact_email: + label: Contact email + text: Email address of key contact responsible for this site. + msg: + empty: Contact email cannot be empty. + incorrect: Contact email incorrect format. + login_required: + label: Private + switch: Login required + text: Only logged in users can access this community. + admin_name: + label: Name + msg: Name cannot be empty. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + msg_min_length: Password must be at least 8 characters in length. + msg_max_length: Password must be at maximum 32 characters in length. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_error: + http_error: HTTP Error {{ code }} + desc_403: You don't have permission to access this page. + desc_404: Unfortunately, this page doesn't exist. + desc_50X: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + badges: Badges + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + terms: Terms + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + login: Login + privileges: Privileges + plugins: Plugins + installed_plugins: Installed Plugins + apperance: Appearance + website_welcome: Welcome to {{site_name}} + user_center: + login: Login + qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. + login_failed_email_tip: Login failed, please allow this app to access your email information before try again. + badges: + modal: + title: Congratulations + content: You've earned a new badge. + close: Close + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site statistics + questions: "Questions:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + users: "Users:" + flags: "Flags:" + reviews: "Reviews:" + site_health: Site health + version: "Version:" + https: "HTTPS:" + upload_folder: "Upload folder:" + run_mode: "Running mode:" + private: Private + public: Public + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System info + go_version: "Go version:" + database: "Database:" + database_size: "Database size:" + storage_used: "Storage used:" + uptime: "Uptime:" + links: Links + plugins: Plugins + github: GitHub + blog: Blog + contact: Contact + forum: Forum + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + writable: Writable + not_writable: Not writable + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + flagged_type: Flagged {{ type }} + created: Created + action: Action + review: Review + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + edit_profile_modal: + title: Edit profile + form: + fields: + display_name: + label: Display name + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Invalid Email Address. + edit_success: Edited successfully + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + users: + label: Bulk add user + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separate “name, email, password” with commas. One user per line. + msg: "Please enter the user's email, one per line." + display_name: + label: Display name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + more: More + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + edit_profile: Edit profile + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + deactivate_user: + title: Deactivate user + content: An inactive user must re-validate their email. + delete_user: + title: Delete this user + content: Are you sure you want to delete this user? This is permanent! + remove: Remove their content + label: Remove all questions, answers, comments, etc. + text: Don’t check this if you wish to only delete the user’s account. + suspend_user: + title: Suspend this user + content: A suspended user can't log in. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Questions + unlisted: Unlisted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + pending: Pending + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short site description + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site description + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + check_update: + label: Software updates + text: Automatically check for updates + interface: + page_title: Interface + language: + label: Interface language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: From email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + tls: TLS + none: None + smtp_port: + label: SMTP port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test email recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile logo + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square icon + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Write + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Each user can only write one answer for the same question + text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Recommend tags + text: "Recommend tags will show in the dropdown list by default." + msg: + contain_reserved: "recommended tags cannot contain reserved tags" + required_tag: + title: Set required tags + label: Set “Recommend tags” as required tags + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved tags + text: "Reserved tags can only be used by moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + color_scheme: + label: Color scheme + navbar_style: + label: Navbar background style + primary_color: + label: Primary color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: > + + head: + label: Head + text: > + + header: + label: Header + text: > + + footer: + label: Footer + text: This will insert before </body>. + sidebar: + label: Sidebar + text: This will insert in sidebar. + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + email_registration: + title: Email registration + label: Allow email registration + text: Turn off to prevent anyone creating new account through email. + allowed_email_domains: + title: Allowed email domains + text: Email domains that users must register accounts with. One domain per line. Ignored when empty. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + password_login: + title: Password login + label: Allow email and password login + text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." + installed_plugins: + title: Installed Plugins + plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + filter: + all: All + active: Active + inactive: Inactive + outdated: Outdated + plugins: + label: Plugins + text: Select an existing plugin. + name: Name + version: Version + status: Status + action: Action + deactivate: Deactivate + activate: Activate + settings: Settings + settings_users: + title: Users + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + profile_editable: + title: Profile editable + allow_update_display_name: + label: Allow users to change their display name + allow_update_username: + label: Allow users to change their username + allow_update_avatar: + label: Allow users to change their profile image + allow_update_bio: + label: Allow users to change their about me + allow_update_website: + label: Allow users to change their website + allow_update_location: + label: Allow users to change their location + privilege: + title: Privileges + level: + label: Reputation required level + text: Choose the reputation required for the privileges + msg: + should_be_number: the input should be number + number_larger_1: number should be equal or larger than 1 + badges: + action: Action + active: Active + activate: Activate + all: All + awards: Awards + deactivate: Deactivate + filter: + placeholder: Filter by name, badge:id + group: Group + inactive: Inactive + name: Name + show_logs: Show logs + status: Status + title: Badges + form: + optional: (optional) + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + select: Select + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + approve_revision_tip: Do you approve this revision? + approve_flag_tip: Do you approve this flag? + approve_post_tip: Do you approve this post? + approve_user_tip: Do you approve this user? + suggest_edits: Suggested edits + flag_post: Flag post + flag_user: Flag user + queued_post: Queued post + queued_user: Queued user + filter_label: Type + reputation: reputation + flag_post_type: Flagged this post as {{ type }}. + flag_user_type: Flagged this user as {{ type }}. + edit_post: Edit post + list_post: List post + unlist_post: Unlist post + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + pin: pinned + unpin: unpinned + show: listed + hide: unlisted + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores this week + users_with_the_most_vote: Users who voted the most this week + staffs: Our community staff + reputation: reputation + votes: votes + prompt: + leave_page: Are you sure you want to leave the page? + changes_not_save: Your changes may not be saved. + draft: + discard_confirm: Are you sure you want to discard your draft? + messages: + post_deleted: This post has been deleted. + post_cancel_deleted: This post has been undeleted. + post_pin: This post has been pinned. + post_unpin: This post has been unpinned. + post_hide_list: This post has been hidden from list. + post_show_list: This post has been shown to list. + post_reopen: This post has been reopened. + post_list: This post has been listed. + post_unlist: This post has been unlisted. + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/nl_NL.yaml b/data/i18n/nl_NL.yaml new file mode 100644 index 000000000..25c086f11 --- /dev/null +++ b/data/i18n/nl_NL.yaml @@ -0,0 +1,1384 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: Success. + unknown: + other: Unknown error. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + email: + other: Email + password: + other: Password + email_or_password_wrong_error: + other: Email and password do not match. + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + question: + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + rank: + fail_to_meet_the_condition: + other: Rank fail to meet the condition. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend Tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + smtp: + config_from_name_cannot_be_email: + other: The From Name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to Revision. + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + report: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude: + name: + other: rude or abusive + desc: + other: A reasonable person would find this content inappropriate for respectful discourse. + duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + not_answer: + name: + other: not an answer + desc: + other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. + not_need: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + other: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comments + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to {{site_name}} + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to {{site_name}} + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/no_NO.yaml b/data/i18n/no_NO.yaml new file mode 100644 index 000000000..abe12baf4 --- /dev/null +++ b/data/i18n/no_NO.yaml @@ -0,0 +1,1385 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: Success. + unknown: + other: Unknown error. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + email: + other: Email + password: + other: Password + email_or_password_wrong_error: + other: Email and password do not match. + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + question: + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + rank: + fail_to_meet_the_condition: + other: Rank fail to meet the condition. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend Tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + smtp: + config_from_name_cannot_be_email: + other: The From Name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to Revision. + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + report: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude: + name: + other: rude or abusive + desc: + other: A reasonable person would find this content inappropriate for respectful discourse. + duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + not_answer: + name: + other: not an answer + desc: + other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. + not_need: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + other: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comments + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to {{site_name}} + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to {{site_name}} + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + recommend: Recommend + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/pl_PL.yaml b/data/i18n/pl_PL.yaml new file mode 100644 index 000000000..7cf88431b --- /dev/null +++ b/data/i18n/pl_PL.yaml @@ -0,0 +1,2414 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Sukces. + unknown: + other: Nieznany błąd. + request_format_error: + other: Format żądania jest nieprawidłowy. + unauthorized_error: + other: Niezautoryzowany. + database_error: + other: Błąd serwera danych. + forbidden_error: + other: Zakazane. + duplicate_request_error: + other: Duplikat zgłoszenia. + action: + report: + other: Zgłoś + edit: + other: Edytuj + delete: + other: Usuń + close: + other: Zamknij + reopen: + other: Otwórz ponownie + forbidden_error: + other: Zakazane. + pin: + other: Przypnij + hide: + other: Usuń z listy + unpin: + other: Odepnij + show: + other: Lista + invite_someone_to_answer: + other: Edytuj + undelete: + other: Przywróć + merge: + other: Merge + role: + name: + user: + other: Użytkownik + admin: + other: Administrator + moderator: + other: Moderator + description: + user: + other: Domyślnie bez specjalnego dostępu. + admin: + other: Posiadać pełne uprawnienia dostępu do strony. + moderator: + other: Ma dostęp do wszystkich postów z wyjątkiem ustawień administratora. + privilege: + level_1: + description: + other: Poziom 1 (mniejsza reputacja wymagana dla prywatnego zespołu, grupy) + level_2: + description: + other: Poziom 2 (niska reputacja wymagana dla społeczności startującej) + level_3: + description: + other: Poziom 3 (wysoka reputacja wymagana dla dojrzałej społeczności) + level_custom: + description: + other: Poziom niestandardowy + rank_question_add_label: + other: Zadaj pytanie + rank_answer_add_label: + other: Napisz odpowiedź + rank_comment_add_label: + other: Napisz komentarz + rank_report_add_label: + other: Zgłoś + rank_comment_vote_up_label: + other: Wyróżnij komentarz + rank_link_url_limit_label: + other: Opublikuj więcej niż 2 linki na raz + rank_question_vote_up_label: + other: Wyróżnij pytanie + rank_answer_vote_up_label: + other: Wyróżnij odpowiedź + rank_question_vote_down_label: + other: Oceń pytanie negatywnie + rank_answer_vote_down_label: + other: Oceń odpowiedź negatywnie + rank_invite_someone_to_answer_label: + other: Zaproś kogoś do odpowiedzi + rank_tag_add_label: + other: Utwórz nowy tag + rank_tag_edit_label: + other: Edytuj opis tagu (wymaga akceptacji) + rank_question_edit_label: + other: Edytuj pytanie innych (wymaga akceptacji) + rank_answer_edit_label: + other: Edytuj odpowiedź innych (wymaga akceptacji) + rank_question_edit_without_review_label: + other: Edytuj pytanie innych bez akceptacji + rank_answer_edit_without_review_label: + other: Edytuj odpowiedź innych bez akceptacji + rank_question_audit_label: + other: Przejrzyj edycje pytania + rank_answer_audit_label: + other: Przejrzyj edycje odpowiedzi + rank_tag_audit_label: + other: Przejrzyj edycje tagu + rank_tag_edit_without_review_label: + other: Edytuj opis tagu bez akceptacji + rank_tag_synonym_label: + other: Zarządzaj synonimami tagów + email: + other: E-mail + e_mail: + other: Email + password: + other: Hasło + pass: + other: Hasło + old_pass: + other: Current password + original_text: + other: Ten wpis + email_or_password_wrong_error: + other: Email lub hasło nie są poprawne. + error: + common: + invalid_url: + other: Nieprawidłowy URL. + status_invalid: + other: Nieprawidłowy status. + password: + space_invalid: + other: Hasło nie może zawierać spacji. + admin: + cannot_update_their_password: + other: Nie możesz zmieniać swojego hasła. + cannot_edit_their_profile: + other: Nie możesz modyfikować swojego profilu. + cannot_modify_self_status: + other: Nie możesz modyfikować swojego statusu. + email_or_password_wrong: + other: Emil lub hasło nie są zgodne. + answer: + not_found: + other: Odpowiedź nie została odnaleziona. + cannot_deleted: + other: Brak uprawnień do usunięcia. + cannot_update: + other: Brak uprawnień do aktualizacji. + question_closed_cannot_add: + other: Pytania są zamknięte i nie można ich dodawać. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Komentarz nie może edytować. + not_found: + other: Komentarz nie został odnaleziony. + cannot_edit_after_deadline: + other: Czas komentowania był zbyt długi, aby go zmodyfikować. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: E-mail już istnieje. + need_to_be_verified: + other: E-mail powinien zostać zweryfikowany. + verify_url_expired: + other: Adres URL zweryfikowanej wiadomości e-mail wygasł, prosimy o ponowne wysłanie wiadomości e-mail. + illegal_email_domain_error: + other: Wysyłanie wiadomości e-mail z tej domeny jest niedozwolone. Użyj innej domeny. + lang: + not_found: + other: Nie znaleziono pliku językowego. + object: + captcha_verification_failed: + other: Nieprawidłowa captcha. + disallow_follow: + other: Nie wolno ci podążać za nimi. + disallow_vote: + other: Nie masz uprawnień do głosowania. + disallow_vote_your_self: + other: Nie możesz głosować na własne posty. + not_found: + other: Obiekt nie został odnaleziony. + verification_failed: + other: Weryfikacja nie powiodła się. + email_or_password_incorrect: + other: Email lub hasło są nieprawidłowe. + old_password_verification_failed: + other: Stara weryfikacja hasła nie powiodła się + new_password_same_as_previous_setting: + other: Nowe hasło jest takie samo jak poprzednie. + already_deleted: + other: Ten wpis został usunięty. + meta: + object_not_found: + other: Meta obiekt nie został odnaleziony + question: + already_deleted: + other: Ten post został usunięty. + under_review: + other: Twój post oczekuje na recenzje. Będzie widoczny po jej akceptacji. + not_found: + other: Pytanie nie zostało odnalezione. + cannot_deleted: + other: Brak uprawnień do usunięcia. + cannot_close: + other: Brak uprawnień do zamknięcia. + cannot_update: + other: Brak uprawnień do edycji. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Ranga nie spełnia warunku. + vote_fail_to_meet_the_condition: + other: Dziękujemy za opinię. Potrzebujesz co najmniej {{.Rank}} reputacji, aby oddać głos. + no_enough_rank_to_operate: + other: Potrzebujesz co najmniej {{.Rank}} reputacji, aby to zrobić. + report: + handle_failed: + other: Nie udało się obsłużyć raportu. + not_found: + other: Raport nie został znaleziony. + tag: + already_exist: + other: Tag już istnieje. + not_found: + other: Tag nie został znaleziony. + recommend_tag_not_found: + other: Zalecany tag nie istnieje. + recommend_tag_enter: + other: Proszę wprowadzić przynajmniej jeden wymagany tag. + not_contain_synonym_tags: + other: Nie powinno zawierać tagów synonimów. + cannot_update: + other: Brak uprawnień do aktualizacji. + is_used_cannot_delete: + other: Nie możesz usunąć tagu, który jest w użyciu. + cannot_set_synonym_as_itself: + other: Nie można ustawić synonimu aktualnego tagu jako takiego. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: Nazwą nadawcy nie może być adresem e-mail. + theme: + not_found: + other: Nie znaleziono motywu. + revision: + review_underway: + other: Nie można teraz edytować, istnieje wersja w kolejce sprawdzeń. + no_permission: + other: Brak uprawnień do wersji. + user: + external_login_missing_user_id: + other: Platforma zewnętrzna nie dostarcza unikalnego identyfikatora użytkownika (UserID), dlatego nie możesz się zalogować. Skontaktuj się z administratorem witryny. + external_login_unbinding_forbidden: + other: Proszę ustawić hasło logowania dla swojego konta przed usunięciem tego logowania. + email_or_password_wrong: + other: + other: Adres email i hasło nie są zgodne. + not_found: + other: Użytkownik nie został znaleziony. + suspended: + other: Użytkownik został zawieszony. + username_invalid: + other: Nazwa użytkownika jest nieprawidłowa. + username_duplicate: + other: Nazwa użytkownika jest już zajęta. + set_avatar: + other: Nie udało się ustawić awatara. + cannot_update_your_role: + other: Nie możesz zmienić swojej roli. + not_allowed_registration: + other: Obecnie strona nie zezwala na rejestracje. + not_allowed_login_via_password: + other: Obecnie strona nie zezwala na logowanie się za pomocą hasła. + access_denied: + other: Odmowa dostępu. + page_access_denied: + other: Nie masz dostępu do tej strony. + add_bulk_users_format_error: + other: "Błąd {{.Field}} w pobliżu '{{.Content}}' w linii {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "Liczba użytkowników, których dodasz na raz, powinna mieścić się w przedziale 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Nie udało się odczytać pliku konfiguracyjnego. + database: + connection_failed: + other: Nie udało się połączyć z bazą danych. + create_table_failed: + other: Nie udało się utworzyć tabeli. + install: + create_config_failed: + other: Nie można utworzyć pliku config.yaml. + upload: + unsupported_file_format: + other: Nieobsługiwany format pliku. + site_info: + config_not_found: + other: Nie znaleziono konfiguracji strony. + badge: + object_not_found: + other: Nie znaleziono obiektu odznaki + reason: + spam: + name: + other: spam + desc: + other: Ten post jest reklamą lub wandalizmem. Nie jest przydatny ani istotny dla bieżącego tematu. + rude_or_abusive: + name: + other: niegrzeczny lub obraźliwy + desc: + other: "Rozsądna osoba uznałaby tę treść za nieodpowiednią do dyskusji opartej na szacunku." + a_duplicate: + name: + other: duplikat + desc: + other: To pytanie zostało już wcześniej zadane i ma już odpowiedź. + placeholder: + other: Wprowadź link do istniejącego pytania + not_a_answer: + name: + other: nie jest odpowiedzią + desc: + other: "Ta wiadomość została zamieszczona jako odpowiedź, ale nie próbuje odpowiedzieć na pytanie. Powinna być prawdopodobnie edycją, komentarzem, kolejnym pytaniem lub całkowicie usunięta." + no_longer_needed: + name: + other: nie jest już potrzebne + desc: + other: Ten komentarz jest przestarzały, prowadzi do rozmowy lub nie jest związany z tą wiadomością. + something: + name: + other: coś innego + desc: + other: Ta wiadomość wymaga uwagi personelu z innego powodu, który nie jest wymieniony powyżej. + placeholder: + other: Poinformuj nas dokładnie, o co Ci chodzi + community_specific: + name: + other: powód specyficzny dla społeczności + desc: + other: To pytanie nie spełnia wytycznych społeczności. + not_clarity: + name: + other: wymaga szczegółów lub wyjaśnienia + desc: + other: To pytanie obecnie zawiera wiele pytań w jednym. Powinno skupić się tylko na jednym problemie. + looks_ok: + name: + other: Wygląda poprawnie + desc: + other: Ta wiadomość jest dobra w obecnej formie i nie jest niskiej jakości. + needs_edit: + name: + other: wymaga edycji, a ja to zrobiłem/am + desc: + other: Popraw i skoryguj problemy w tej wiadomości samodzielnie. + needs_close: + name: + other: wymaga zamknięcia + desc: + other: Na zamknięte pytanie nie można odpowiadać, ale wciąż można edytować, głosować i komentować. + needs_delete: + name: + other: wymaga usunięcia + desc: + other: Ta wiadomość zostanie usunięta. + question: + close: + duplicate: + name: + other: spam + desc: + other: To pytanie zostało już wcześniej zadane i ma już odpowiedź. + guideline: + name: + other: powód specyficzny dla społeczności + desc: + other: To pytanie nie spełnia wytycznych społeczności. + multiple: + name: + other: wymaga szczegółów lub wyjaśnienia + desc: + other: To pytanie obecnie zawiera wiele pytań w jednym. Powinno się skupić tylko na jednym problemie. + other: + name: + other: coś innego + desc: + other: Ten post wymaga jeszcze jednego powodu, który nie został wymieniony powyżej. + operation_type: + asked: + other: zapytano + answered: + other: odpowiedziano + modified: + other: zmodyfikowane + deleted_title: + other: Usunięte pytanie + questions_title: + other: Pytania + tag: + tags_title: + other: Tagi + no_description: + other: Tag nie posiada opisu. + notification: + action: + update_question: + other: zaktualizował/a pytanie + answer_the_question: + other: odpowiedz na pytanie + update_answer: + other: aktualizuj odpowiedź + accept_answer: + other: zaakceptował/a odpowiedź + comment_question: + other: skomentował/a pytanie + comment_answer: + other: skomentował/a odpowiedź + reply_to_you: + other: odpowiedział/a tobie + mention_you: + other: wspomniał/a o tobie + your_question_is_closed: + other: Twoje pytanie zostało zamknięte + your_question_was_deleted: + other: Twoje pytanie zostało usunięte + your_answer_was_deleted: + other: Twoja odpowiedź została usunięta + your_comment_was_deleted: + other: Twój komentarz został usunięty + up_voted_question: + other: pytanie przegłosowane + down_voted_question: + other: pytanie odrzucone + up_voted_answer: + other: odpowiedź przegłosowana + down_voted_answer: + other: odrzucona odpowiedź + up_voted_comment: + other: komentarz upvote + invited_you_to_answer: + other: zaproszono Cię do odpowiedzi + earned_badge: + other: Zdobyłeś odznakę "{{.BadgeName}}" + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Potwierdź swój nowy adres e-mail" + body: + other: "Potwierdź swój nowy adres e-mail dla {{.SiteName}}, klikając poniższy link:
        \n{{.ChangeEmailUrl}}

        \n\nJeśli nie prosiłeś(-aś) o zmianę adresu e-mail, zignoruj tę wiadomość.

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} odpowiedział(-a) na pytanie" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}} napisał(-a):
        \n
        {{.AnswerSummary}}

        \nZobacz na {{.SiteName}}

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana.

        \n\nZrezygnuj z subskrypcji" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} zaprosił(-a) Cię do odpowiedzi" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}} napisał(-a):
        \n
        Myślę, że możesz znać odpowiedź.

        \nZobacz na {{.SiteName}}

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana.

        \n\nZrezygnuj z subskrypcji" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} skomentował(-a) Twój wpis" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}} napisał(-a):
        \n
        {{.CommentSummary}}

        \nZobacz na {{.SiteName}}

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana.

        \n\nZrezygnuj z subskrypcji" + new_question: + title: + other: "[{{.SiteName}}] Nowe pytanie: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana.

        \n\nZrezygnuj z subskrypcji" + pass_reset: + title: + other: "[{{.SiteName}}] Reset hasła" + body: + other: "Otrzymaliśmy prośbę o zresetowanie Twojego hasła w serwisie {{.SiteName}}.

        \n\nJeśli to nie Ty wysłałeś(-aś) tę prośbę, możesz bezpiecznie zignorować tę wiadomość.

        \n\nKliknij poniższy link, aby ustawić nowe hasło:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana." + register: + title: + other: "[{{.SiteName}}] Potwierdź swoje nowe konto" + body: + other: "Witamy w {{.SiteName}}!

        \n\nKliknij poniższy link, aby potwierdzić i aktywować swoje nowe konto:
        \n{{.RegisterUrl}}

        \n\nJeśli powyższy link nie jest klikalny, spróbuj skopiować go i wkleić do paska adresu przeglądarki.\n

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana." + test: + title: + other: "[{{.SiteName}}] Wiadomość testowa" + body: + other: "To jest testowa wiadomość e-mail.\n

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana." + upvote: + other: oceń pozytywnie + upvoted: + other: polubione + downvote: + other: oceń negatywnie + downvoted: + other: oceniono negatywnie + accept: + other: akceptuj + accepted: + other: zaakceptowane + edit: + other: edytuj + review: + queued_post: + other: Post w kolejce + flagged_post: + other: Post oznaczony + suggested_post_edit: + other: Sugerowane zmiany + reaction: + tooltip: + other: "{{ .Names }} już {{ .Count }} razy ..." + badge: + default_badges: + autobiographer: + name: + other: Autobiografista + desc: + other: Wypełniono informacje profil. + certified: + name: + other: Certyfikowany + desc: + other: Ukończono nasz nowy samouczek. + editor: + name: + other: Edytor + desc: + other: Pierwsza edycja posta. + first_flag: + name: + other: Pierwsza flaga + desc: + other: Po raz pierwszy oznaczono post. + first_upvote: + name: + other: Pierwszy pozytywny głos + desc: + other: Po raz pierwszy oddano pozytywny głos na post. + first_link: + name: + other: Pierwszy odnośnik + desc: + other: Po raz pierwszy dodano link do innego wpisu. + + first_reaction: + name: + other: Pierwsza reakcja + desc: + other: Po raz pierwszy zareagowano na wpis. + + first_share: + name: + other: Pierwsze udostępnienie + desc: + other: Po raz pierwszy udostępniono wpis. + + scholar: + name: + other: Scholar + desc: + other: Zadano pytanie i zaakceptowano odpowiedź. + + commentator: + name: + other: Komentator + desc: + other: Pozostawiono 5 komentarzy. + + new_user_of_the_month: + name: + other: Nowy użytkownik miesiąca + desc: + other: Wyjątkowy wkład w pierwszym miesiącu aktywności. + + read_guidelines: + name: + other: Przeczytano zasady + desc: + other: Przeczytano [zasady społeczności]. + + reader: + name: + other: Czytelnik + desc: + other: Przeczytano wszystkie odpowiedzi w wątku mającym ponad 10 odpowiedzi. + + welcome: + name: + other: Witamy + desc: + other: Otrzymano pozytywny głos. + + nice_share: + name: + other: Udane udostępnienie + desc: + other: Udostępniono wpis, który odwiedziło 25 unikalnych użytkowników. + + good_share: + name: + other: Dobre udostępnienie + desc: + other: Udostępniono wpis, który odwiedziło 300 unikalnych użytkowników. + + great_share: + name: + other: Świetne udostępnienie + desc: + other: Udostępniono wpis, który odwiedziło 1000 unikalnych użytkowników. + + out_of_love: + name: + other: Z miłości + desc: + other: Wykorzystano 50 pozytywnych głosów w ciągu dnia. + + higher_love: + name: + other: Więcej miłości + desc: + other: Wykorzystano 50 pozytywnych głosów w ciągu dnia - 5 razy. + + crazy_in_love: + name: + other: Szaleństwo miłości + desc: + other: Wykorzystano 50 pozytywnych głosów w ciągu dnia - 20 razy. + + promoter: + name: + other: Promotor + desc: + other: Zaproszono użytkownika. + + campaigner: + name: + other: Kampanier + desc: + other: Zaproszono 3 podstawowych użytkowników. + + champion: + name: + other: Mistrz + desc: + other: Zaproszono 5 użytkowników. + + thank_you: + name: + other: Dziękuję + desc: + other: Otrzymano 20 pozytywnych głosów i oddano 10. + + gives_back: + name: + other: Oddający dalej + desc: + other: Otrzymano 100 pozytywnych głosów i oddano 100. + + empathetic: + name: + other: Empatyczny + desc: + other: Otrzymano 500 pozytywnych głosów i oddano 1000. + + enthusiast: + name: + other: Entuzjasta + desc: + other: Odwiedzono serwis 10 dni z rzędu. + + aficionado: + name: + other: Koneser + desc: + other: Odwiedzono serwis 100 dni z rzędu. + + devotee: + name: + other: Wytrwały + desc: + other: Odwiedzono serwis 365 dni z rzędu. + + anniversary: + name: + other: Rocznica + desc: + other: Aktywny użytkownik od roku, co najmniej jeden wpis. + + appreciated: + name: + other: Doceniony + desc: + other: Otrzymano 1 pozytywny głos na 20 wpisach. + + respected: + name: + other: Szanujący + desc: + other: Otrzymano 2 pozytywne głosy na 100 wpisach. + + admired: + name: + other: Podziwiany + desc: + other: Otrzymano 5 pozytywnych głosów na 300 wpisach. + + solved: + name: + other: Rozwiązane + desc: + other: Udzielono odpowiedzi, która została zaakceptowana. + + guidance_counsellor: + name: + other: Doradca + desc: + other: 10 udzielonych odpowiedzi zostało zaakceptowanych. + + know_it_all: + name: + other: Wszystkowiedzący + desc: + other: 50 udzielonych odpowiedzi zostało zaakceptowanych. + + solution_institution: + name: + other: Instytucja rozwiązań + desc: + other: 150 udzielonych odpowiedzi zostało zaakceptowanych. + + nice_answer: + name: + other: Dobra odpowiedź + desc: + other: Odpowiedź z wynikiem co najmniej 10. + + good_answer: + name: + other: Bardzo dobra odpowiedź + desc: + other: Odpowiedź z wynikiem co najmniej 25. + + great_answer: + name: + other: Świetna odpowiedź + desc: + other: Odpowiedź z wynikiem co najmniej 50. + + nice_question: + name: + other: Dobre pytanie + desc: + other: Pytanie z wynikiem co najmniej 10. + + good_question: + name: + other: Bardzo dobre pytanie + desc: + other: Pytanie z wynikiem co najmniej 25. + + great_question: + name: + other: Świetne pytanie + desc: + other: Pytanie z wynikiem co najmniej 50. + + popular_question: + name: + other: Popularne pytanie + desc: + other: Pytanie z 500 wyświetleniami. + + notable_question: + name: + other: Zauważalne pytanie + desc: + other: Pytanie z 1000 wyświetleniami. + + famous_question: + name: + other: Słynne pytanie + desc: + other: Pytanie z 5000 wyświetleniami. + + popular_link: + name: + other: Popularny link + desc: + other: Opublikowano zewnętrzny link z 50 kliknięciami. + + hot_link: + name: + other: Gorący link + desc: + other: Opublikowano zewnętrzny link z 300 kliknięciami. + + famous_link: + name: + other: Słynny link + desc: + other: Opublikowano zewnętrzny link z 1000 kliknięciami. + default_badge_groups: + getting_started: + name: + other: Pierwsze kroki + community: + name: + other: Społeczność + posting: + name: + other: Publikowanie +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Jak formatować + desc: >- +
          +
        • wspomnij wpis: #post_id

        • +
        • tworzenie linków

          +
          <https://url.com>

          [Tytuł](https://url.com)
          +
        • +
        • oddziel akapity pustą linią

        • +
        • _kursywa_ lub **pogrubienie**

        • +
        • zagnieźdź kod, dodając 4 spacje na początku wiersza

        • +
        • cytuj, dodając > na początku wiersza

        • +
        • użyj odwrotnego apostrofu (backtick) do zagnieżdżonego kodu `tak _to_ działa`

        • +
        • twórz bloki kodu przy pomocy potrójnych odwrotnych apostrofów `

          +
          ```
          kod tutaj
          ```
          +
        • +
        + prev: Poprzedni + next: Następny + page_title: + question: Pytanie + questions: Pytania + tag: Tag + tags: Tagi + tag_wiki: wiki tagu + create_tag: Utwórz tag + edit_tag: Edytuj tag + ask_a_question: Create Question + edit_question: Edytuj pytanie + edit_answer: Edytuj odpowiedź + search: Szukaj + posts_containing: Posty zawierające + settings: Ustawienia + notifications: Powiadomienia + login: Zaloguj się + sign_up: Zarejestruj się + account_recovery: Odzyskiwanie konta + account_activation: Aktywacja konta + confirm_email: Potwierdź adres e-mail + account_suspended: Konto zawieszone + admin: Administrator + change_email: Zmień e-mail + install: Instalacja Answer + upgrade: Aktualizacja Answer + maintenance: Przerwa techniczna + users: Użytkownicy + oauth_callback: Przetwarzanie + http_404: Błąd HTTP 404 + http_50X: Błąd HTTP 500 + http_403: Błąd HTTP 403 + logout: Wyloguj się + posts: Posts + notifications: + title: Powiadomienia + inbox: Skrzynka odbiorcza + achievement: Osiągnięcia + new_alerts: Nowe powiadomienia + all_read: Oznacz wszystkie jako przeczytane + show_more: Pokaż więcej + someone: Ktoś + inbox_type: + all: Wszystko + posts: Posty + invites: Zaproszenia + votes: Głosy + answer: Answer + question: Question + badge_award: Badge + suspended: + title: Twoje konto zostało zawieszone + until_time: "Twoje konto zostało zawieszone do {{ time }}." + forever: Ten użytkownik został na zawsze zawieszony. + end: Nie spełniasz wytycznych społeczności. + contact_us: Skontaktuj się z nami + editor: + blockquote: + text: Cytat + bold: + text: Pogrubienie + chart: + text: Wykres + flow_chart: Wykres przepływu + sequence_diagram: Diagram sekwencji + class_diagram: Diagram klas + state_diagram: Diagram stanów + entity_relationship_diagram: Diagram związków encji + user_defined_diagram: Diagram zdefiniowany przez użytkownika + gantt_chart: Wykres Gantta + pie_chart: Wykres kołowy + code: + text: Przykład kodu + add_code: Dodaj przykład kodu + form: + fields: + code: + label: Kod + msg: + empty: Kod nie może być pusty. + language: + label: Język + placeholder: Wykrywanie automatyczne + btn_cancel: Anuluj + btn_confirm: Dodaj + formula: + text: Formuła + options: + inline: Formuła w linii + block: Formuła blokowa + heading: + text: Nagłówek + options: + h1: Nagłówek 1 + h2: Nagłówek 2 + h3: Nagłówek 3 + h4: Nagłówek 4 + h5: Nagłówek 5 + h6: Nagłówek 6 + help: + text: Pomoc + hr: + text: Linia pozioma + image: + text: Obrazek + add_image: Dodaj obrazek + tab_image: Prześlij obrazek + form_image: + fields: + file: + label: Plik graficzny + btn: Wybierz obrazek + msg: + empty: Plik nie może być pusty. + only_image: Dozwolone są tylko pliki obrazków. + max_size: File size cannot exceed {{size}} MB. + desc: + label: Opis + tab_url: Adres URL obrazka + form_url: + fields: + url: + label: Adres URL obrazka + msg: + empty: Adres URL obrazka nie może być pusty. + name: + label: Opis + btn_cancel: Anuluj + btn_confirm: Dodaj + uploading: Przesyłanie + indent: + text: Wcięcie + outdent: + text: Wcięcie zewnętrzne + italic: + text: Podkreślenie + link: + text: Hiperłącze + add_link: Dodaj hiperłącze + form: + fields: + url: + label: Adres URL + msg: + empty: Adres URL nie może być pusty. + name: + label: Opis + btn_cancel: Anuluj + btn_confirm: Dodaj + ordered_list: + text: Lista numerowana + unordered_list: + text: Lista wypunktowana + table: + text: Tabela + heading: Nagłówek + cell: Komórka + file: + text: Dołącz pliki + not_supported: "Ten typ pliku nie jest obsługiwany. Spróbuj ponownie z {{file_type}}." + max_size: "Rozmiar dołączanych plików nie może przekraczać {{size}} MB." + close_modal: + title: Zamykam ten post jako... + btn_cancel: Anuluj + btn_submit: Prześlij + remark: + empty: Nie może być puste. + msg: + empty: Proszę wybrać powód. + report_modal: + flag_title: Oznaczam ten post jako... + close_title: Zamykam ten post jako... + review_question_title: Przegląd pytania + review_answer_title: Przegląd odpowiedzi + review_comment_title: Przegląd komentarza + btn_cancel: Anuluj + btn_submit: Prześlij + remark: + empty: Nie może być puste. + msg: + empty: Proszę wybrać powód. + not_a_url: Format adresu URL jest nieprawidłowy. + url_not_match: Wskazany URL nie pasuje do bieżącej witryny. + tag_modal: + title: Utwórz nowy tag + form: + fields: + display_name: + label: Nazwa wyświetlana + msg: + empty: Nazwa wyświetlana nie może być pusta. + range: Nazwa wyświetlana może zawierać maksymalnie 35 znaków. + slug_name: + label: Adres URL slug + desc: Odnośnik URL może zawierać maksymalnie 35 znaków. + msg: + empty: Odnośnik URL nie może być pusty. + range: Odnośnik URL może zawierać maksymalnie 35 znaków. + character: Slug adresu URL zawiera niedozwolony zestaw znaków. + desc: + label: Opis + revision: + label: Wersja + edit_summary: + label: Podsumowanie edycji + placeholder: >- + Krótkie wyjaśnienie zmian (poprawa pisowni, naprawa gramatyki, poprawa formatowania) + btn_cancel: Anuluj + btn_submit: Prześlij + btn_post: Opublikuj nowy tag + tag_info: + created_at: Utworzony + edited_at: Edytowany + history: Historia + synonyms: + title: Synonimy + text: Następujące tagi zostaną przekierowane na + empty: Nie znaleziono synonimów. + btn_add: Dodaj synonim + btn_edit: Edytuj + btn_save: Zapisz + synonyms_text: Następujące tagi zostaną przekierowane na + delete: + title: Usuń ten tag + tip_with_posts: >- +

        Nie można usunąć tagu, który jest używany w postach.

        +

        Najpierw usuń ten tag z powiązanych postów.

        + tip_with_synonyms: >- +

        Nie można usunąć tagu, który ma synonimy.

        +

        Najpierw usuń synonimy przypisane do tego tagu.

        + tip: Czy na pewno chcesz usunąć? + close: Zamknij + merge: + title: Scal tag + source_tag_title: Źródłowy tag + source_tag_description: Źródłowy tag i wszystkie powiązane dane zostaną przemapowane na tag docelowy. + target_tag_title: Docelowy tag + target_tag_description: Po scaleniu zostanie utworzony synonim między tymi dwoma tagami. + no_results: Brak pasujących tagów + btn_submit: Zatwierdź + btn_close: Zamknij + edit_tag: + title: Edytuj tag + default_reason: Edytuj tag + default_first_reason: Dodaj tag + btn_save_edits: Zapisz edycje + btn_cancel: Anuluj + dates: + long_date: D MMM + long_date_with_year: "YYYY MMM D" + long_date_with_time: "YYYY MMM D [o] HH:mm" + now: teraz + x_seconds_ago: "{{count}} sek. temu" + x_minutes_ago: "{{count}} min. temu" + x_hours_ago: "{{count}} godz. temu" + hour: godzina + day: dzień + hours: godziny + days: dni + month: month + months: months + year: rok + reaction: + heart: serce + smile: uśmiech + frown: niezadowolenie + btn_label: dodaj lub usuń reakcje + undo_emoji: cofnij reakcje {{ emoji }} + react_emoji: zareaguj {{ emoji }} + unreact_emoji: usuń reakcje {{ emoji }} + comment: + btn_add_comment: Dodaj komentarz + reply_to: Odpowiedź na + btn_reply: Odpowiedz + btn_edit: Edytuj + btn_delete: Usuń + btn_flag: Zgłoś + btn_save_edits: Zapisz edycje + btn_cancel: Anuluj + show_more: "Jest {{count}} komentarzy, pokaż więcej" + tip_question: >- + Użyj komentarzy, aby poprosić o dodatkowe informacje lub sugerować poprawki. Unikaj udzielania odpowiedzi na pytania w komentarzach. + tip_answer: >- + Użyj komentarzy, aby odpowiedzieć innym użytkownikom lub powiadomić ich o zmianach. Jeśli dodajesz nowe informacje, edytuj swój post zamiast komentować. + tip_vote: Dodaje coś wartościowego do posta + edit_answer: + title: Edytuj odpowiedź + default_reason: Edytuj odpowiedź + default_first_reason: Dodaj odpowiedź + form: + fields: + revision: + label: Rewizja + answer: + label: Odpowiedź + feedback: + characters: Treść musi mieć co najmniej 6 znaków. + edit_summary: + label: Podsumowanie edycji + placeholder: >- + Pokrótce opisz swoje zmiany (poprawa pisowni, naprawa gramatyki, poprawa formatowania) + btn_save_edits: Zapisz edycje + btn_cancel: Anuluj + tags: + title: Tagi + sort_buttons: + popular: Popularne + name: Nazwa + newest: Najnowsze + button_follow: Obserwuj + button_following: Obserwowane + tag_label: pytania + search_placeholder: Filtruj według nazwy tagu + no_desc: Tag nie posiada opisu. + more: Więcej + wiki: Wiki + ask: + title: Utwórz pytanie + edit_title: Edytuj pytanie + default_reason: Edytuj pytanie + default_first_reason: Create question + similar_questions: Podobne pytania + form: + fields: + revision: + label: Rewizja + title: + label: Tytuł + placeholder: Jaki jest temat? Bądź konkretny. + msg: + empty: Tytuł nie może być pusty. + range: Tytuł do 150 znaków + body: + label: Treść + msg: + empty: Treść nie może być pusta. + hint: + optional_body: Opisz, czego dotyczy pytanie. + minimum_characters: "Opisz, czego dotyczy pytanie — wymagane jest co najmniej {{min_content_length}} znaków." + tags: + label: Tagi + msg: + empty: Tagi nie mogą być puste. + answer: + label: Odpowiedź + msg: + empty: Odpowiedź nie może być pusta. + edit_summary: + label: Podsumowanie edycji + placeholder: >- + Pokrótce opisz swoje zmiany (poprawa pisowni, naprawa gramatyki, poprawa formatowania) + btn_post_question: Opublikuj swoje pytanie + btn_save_edits: Zapisz edycje + answer_question: Odpowiedz na swoje pytanie + post_question&answer: Opublikuj swoje pytanie i odpowiedź + tag_selector: + add_btn: Dodaj tag + create_btn: Utwórz nowy tag + search_tag: Wyszukaj tag + hint: Opisz, czego dotyczy Twoja treść — wymagany jest co najmniej jeden tag. + hint_zero_tags: Opisz, czego dotyczy Twoja treść. + hint_more_than_one_tag: "Opisz, czego dotyczy Twoja treść — wymagane są co najmniej {{min_tags_number}} tagi." + no_result: Nie znaleziono pasujących tagów + tag_required_text: Wymagany tag (co najmniej jeden) + header: + nav: + question: Pytania + tag: Tagi + user: Użytkownicy + badges: Odznaki + profile: Profil + setting: Ustawienia + logout: Wyloguj + admin: Administrator + review: Recenzja + bookmark: Zakładki + moderation: Moderacja + search: + placeholder: Szukaj + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Zmień + loading: Wczytywanie... + pic_auth_code: + title: Captcha + placeholder: Wpisz tekst z obrazka powyżej + msg: + empty: Captcha nie może być pusty. + inactive: + first: >- + Czas na ostatni krok! Wysłaliśmy wiadomość aktywacyjną na adres {{mail}}. Prosimy postępować zgodnie z instrukcjami zawartymi w wiadomości w celu aktywacji Twojego konta. + info: "Jeśli nie dotarła, sprawdź folder ze spamem." + another: >- + Wysłaliśmy kolejną wiadomość aktywacyjną na adres {{mail}}. Może to potrwać kilka minut, zanim dotrze; upewnij się, że sprawdzasz folder ze spamem. + btn_name: Ponownie wyślij wiadomość aktywacyjną + change_btn_name: Zmień adres e-mail + msg: + empty: Nie może być puste. + resend_email: + url_label: Czy na pewno chcesz ponownie wysłać e-mail aktywacyjny? + url_text: Możesz również podać powyższy link aktywacyjny użytkownikowi. + login: + login_to_continue: Zaloguj się, aby kontynuować + info_sign: Nie masz jeszcze konta? <1>Zarejestruj się + info_login: Masz już konto? <1>Zaloguj się + agreements: Rejestrując się, wyrażasz zgodę na <1>politykę prywatności i <3>warunki korzystania z usługi. + forgot_pass: Zapomniałeś hasła? + name: + label: Imię + msg: + empty: Imię nie może być puste. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: Adres e-mail + msg: + empty: Adres e-mail nie może być pusty. + password: + label: Hasło + msg: + empty: Hasło nie może być puste. + different: Wprowadzone hasła są niezgodne + account_forgot: + page_title: Zapomniałeś hasła + btn_name: Wyślij mi e-mail odzyskiwania + send_success: >- + Jeśli istnieje konto powiązane z adresem {{mail}}, wkrótce otrzymasz wiadomość e-mail z instrukcjami dotyczącymi resetowania hasła. + email: + label: Adres e-mail + msg: + empty: Adres e-mail nie może być pusty. + change_email: + btn_cancel: Anuluj + btn_update: Zaktualizuj adres e-mail + send_success: >- + Jeśli istnieje konto powiązane z adresem {{mail}}, wkrótce otrzymasz wiadomość e-mail z instrukcjami dotyczącymi zmiany adresu e-mail. + email: + label: Nowy email + msg: + empty: Adres e-mail nie może być pusty. + oauth: + connect: Połącz z {{ auth_name }} + remove: Usuń {{ auth_name }} + oauth_bind_email: + subtitle: Dodaj e-mail odzyskiwania do swojego konta. + btn_update: Zaktualizuj adres e-mail + email: + label: Adres e-mail + msg: + empty: Adres e-mail nie może być pusty. + modal_title: Adres e-mail już istnieje. + modal_content: Ten adres e-mail jest już zarejestrowany. Czy na pewno chcesz połączyć się z istniejącym kontem? + modal_cancel: Zmień adres e-mail + modal_confirm: Połącz z istniejącym kontem + password_reset: + page_title: Resetowanie hasła + btn_name: Zresetuj moje hasło + reset_success: >- + Pomyślnie zmieniono hasło; zostaniesz przekierowany na stronę logowania. + link_invalid: >- + Przepraszamy, ten link do resetowania hasła jest już nieaktualny. Być może Twoje hasło jest już zresetowane? + to_login: Przejdź do strony logowania + password: + label: Hasło + msg: + empty: Hasło nie może być puste. + length: Długość musi wynosić od 8 do 32 znaków. + different: Wprowadzone hasła są niezgodne. + password_confirm: + label: Potwierdź nowe hasło + settings: + page_title: Ustawienia + goto_modify: Przejdź do modyfikacji + nav: + profile: Profil + notification: Powiadomienia + account: Konto + interface: Interfejs + profile: + heading: Profil + btn_name: Zapisz + display_name: + label: Nazwa wyświetlana + msg: Wyświetlana nazwa nie może być pusta. + msg_range: Wyświetlana nazwa musi mieć od 2 do 30 znaków długości. + username: + label: Nazwa użytkownika + caption: Ludzie mogą oznaczać Cię jako "@nazwa_użytkownika". + msg: Nazwa użytkownika nie może być pusta. + msg_range: Nazwa użytkownika musi mieć od 2 do 30 znaków długości. + character: 'Muszą być znaki ze zbioru "a-z", "0-9", "- . _"' + avatar: + label: Zdjęcie profilowe + gravatar: Gravatar + gravatar_text: Możesz zmienić obraz na stronie + custom: Własne + custom_text: Możesz przesłać własne zdjęcie. + default: Systemowe + msg: Prosimy o przesłanie awatara + bio: + label: O mnie + website: + label: Strona internetowa + placeholder: "https://przyklad.com" + msg: Nieprawidłowy format strony internetowej + location: + label: Lokalizacja + placeholder: "Miasto, Kraj" + notification: + heading: Powiadomienia email + turn_on: Włącz + inbox: + label: Powiadomienia skrzynki odbiorczej + description: Odpowiedzi na Twoje pytania, komentarze, zaproszenia i inne. + all_new_question: + label: Wszystkie nowe pytania + description: Otrzymuj powiadomienia o wszystkich nowych pytaniach. Do 50 pytań tygodniowo. + all_new_question_for_following_tags: + label: Wszystkie nowe pytania dla obserwowanych tagów + description: Otrzymuj powiadomienia o nowych pytaniach do obserwowanych tagów. + account: + heading: Konto + change_email_btn: Zmień adres e-mail + change_pass_btn: Zmień hasło + change_email_info: >- + Wysłaliśmy e-mail na ten adres. Prosimy postępować zgodnie z instrukcjami potwierdzającymi. + email: + label: Email + new_email: + label: Nowy Email + msg: Nowy Email nie może być pusty. + pass: + label: Aktualne hasło + msg: Hasło nie może być puste. + password_title: Hasło + current_pass: + label: Aktualne hasło + msg: + empty: Obecne hasło nie może być puste. + length: Długość musi wynosić od 8 do 32 znaków. + different: Dwa wprowadzone hasła nie są zgodne. + new_pass: + label: Nowe hasło + pass_confirm: + label: Potwierdź nowe hasło + interface: + heading: Interfejs + lang: + label: Język Interfejsu + text: Język interfejsu użytkownika. Zmieni się po odświeżeniu strony. + my_logins: + title: Moje logowania + label: Zaloguj się lub zarejestruj na tej stronie za pomocą tych kont. + modal_title: Usuń logowanie + modal_content: Czy na pewno chcesz usunąć to logowanie z Twojego konta? + modal_confirm_btn: Usuń + remove_success: Pomyślnie usunięto + toast: + update: pomyślnie zaktualizowane + update_password: Hasło zostało pomyślnie zmienione. + flag_success: Dzięki za zgłoszenie. + forbidden_operate_self: Zakazane działanie na sobie + review: Twoja poprawka zostanie wyświetlona po zatwierdzeniu. + sent_success: Wysyłanie zakończone powodzeniem + related_question: + title: Related + answers: odpowiedzi + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Ludzie pytali + desc: Wybierz osoby, które mogą znać odpowiedź. + invite: Zaproś do odpowiedzi + add: Dodaj osoby + search: Wyszukaj osoby + question_detail: + action: Akcja + created: Utworzono + Asked: Zadane + asked: zadał(a) + update: Zmodyfikowane + Edited: Wyedytowane + edit: edytowany + commented: skomentowano + Views: Wyświetlone + Follow: Obserwuj + Following: Obserwuje + follow_tip: Obserwuj to pytanie, aby otrzymywać powiadomienia + answered: odpowiedziano + closed_in: Zamknięte za + show_exist: Pokaż istniejące pytanie. + useful: Przydatne + question_useful: Jest przydatne i jasne + question_un_useful: Jest niejasne lub nieprzydatne + question_bookmark: Dodaj do zakładek to pytanie + answer_useful: Jest przydatna + answer_un_useful: To nie jest użyteczne + answers: + title: Odpowiedzi + score: Ocena + newest: Najnowsze + oldest: Najstarsze + btn_accept: Akceptuj + btn_accepted: Zaakceptowane + write_answer: + title: Twoja odpowiedź + edit_answer: Edytuj moją obecną odpowiedź + btn_name: Wyślij swoją odpowiedź + add_another_answer: Dodaj kolejną odpowiedź + confirm_title: Kontynuuj odpowiedź + continue: Kontynuuj + confirm_info: >- +

        Czy na pewno chcesz dodać kolejną odpowiedź?

        Możesz zamiast tego użyć linku edycji, aby udoskonalić i poprawić istniejącą odpowiedź.

        + empty: Odpowiedź nie może być pusta. + characters: Treść musi mieć co najmniej 6 znaków. + tips: + header_1: Dziękujemy za Twoją odpowiedź + li1_1: Prosimy, upewnij się, że odpowiadasz na pytanie. Podaj szczegóły i podziel się swoimi badaniami. + li1_2: Popieraj swoje stwierdzenia referencjami lub osobistym doświadczeniem. + header_2: Ale unikaj ... + li2_1: Prośby o pomoc, pytania o wyjaśnienie lub odpowiadanie na inne odpowiedzi. + reopen: + confirm_btn: Ponowne otwarcie + title: Otwórz ponownie ten post + content: Czy na pewno chcesz go ponownie otworzyć? + list: + confirm_btn: Lista + title: Pokaż ten post + content: Czy na pewno chcesz wyświetlić tę listę? + unlist: + confirm_btn: Usuń z listy + title: Usuń ten post z listy + content: Czy na pewno chcesz usunąć z listy? + pin: + title: Przypnij ten post + content: Czy na pewno chcesz przypiąć go globalnie? Ten post będzie wyświetlany na górze wszystkich list postów. + confirm_btn: Przypnij + delete: + title: Usuń ten post + question: >- + Nie zalecamy usuwanie pytań wraz z udzielonymi, ponieważ pozbawia to przyszłych czytelników tej wiedzy.

        Powtarzające się usuwanie pytań z odpowiedziami może skutkować zablokowaniem Twojego konta w zakresie zadawania pytań. Czy na pewno chcesz usunąć? + answer_accepted: >- +

        Nie zalecamy usuwania zaakceptowanych już odpowiedzi, ponieważ pozbawia to przyszłych czytelników tej wiedzy.

        Powtarzające się usuwanie zaakceptowanych odpowiedzi może skutkować zablokowaniem Twojego konta w zakresie udzielania odpowiedzi. Czy na pewno chcesz usunąć? + other: Czy na pewno chcesz usunąć? + tip_answer_deleted: Ta odpowiedź została usunięta + undelete_title: Cofnij usunięcie tego posta + undelete_desc: Czy na pewno chcesz cofnąć usunięcie? + btns: + confirm: Potwierdź + cancel: Anuluj + edit: Edytuj + save: Zapisz + delete: Usuń + undelete: Przywróć + list: Lista + unlist: Usuń z listy + unlisted: Usunięte z listy + login: Zaloguj się + signup: Zarejestruj się + logout: Wyloguj się + verify: Zweryfikuj + create: Create + approve: Zatwierdź + reject: Odrzuć + skip: Pominięcie + discard_draft: Odrzuć szkic + pinned: Przypięte + all: Wszystkie + question: Pytanie + answer: Odpowiedź + comment: Komentarz + refresh: Odśwież + resend: Wyślij ponownie + deactivate: Deaktywuj + active: Aktywne + suspend: Zawieś + unsuspend: Cofnij zawieszenie + close: Zamknij + reopen: Otwórz ponownie + ok: Ok + light: Jasny + dark: Ciemny + system_setting: Ustawienia systemowe + default: Domyślne + reset: Reset + tag: Tag + post_lowercase: wpis + filter: Filtry + ignore: Ignoruj + submit: Prześlij + normal: Normalny + closed: Zamknięty + deleted: Usunięty + deleted_permanently: Usunięto trwale + pending: Oczekujący + more: Więcej + view: Podgląd + card: Karta + compact: Kompakt + display_below: Wyświetl poniżej + always_display: Wyświetlaj zawsze + or: lub + back_sites: Powrót do stron + search: + title: Wyniki wyszukiwania + keywords: Słowa kluczowe + options: Opcje + follow: Obserwuj + following: Obserwuje + counts: "Liczba wyników: {{count}}" + counts_loading: "... Wyniki" + more: Więcej + sort_btns: + relevance: Relewantność + newest: Najnowsze + active: Aktywne + score: Ocena + more: Więcej + tips: + title: Porady dotyczące wyszukiwania zaawansowanego + tag: "<1>[tag] search with a tag" + user: "<1>user:username wyszukiwanie według autora" + answer: "<1> answers:0 pytania bez odpowiedzi" + score: "<1>score:3 posty z oceną 3+" + question: "<1>is:question wyszukiwanie pytań" + is_answer: "<1>is:answer wyszukiwanie odpowiedzi" + empty: Nie mogliśmy niczego znaleźć.
        Wypróbuj inne lub mniej konkretne słowa kluczowe. + share: + name: Udostępnij + copy: Skopiuj link + via: Udostępnij post za pośrednictwem... + copied: Skopiowano + facebook: Udostępnij na Facebooku + twitter: Udostępnij na X + cannot_vote_for_self: Nie możesz głosować na własne posty. + modal_confirm: + title: Błąd... + delete_permanently: + title: Usuń trwale + content: Czy na pewno chcesz usunąć to trwale? + account_result: + success: Twoje nowe konto zostało potwierdzone; zostaniesz przekierowany na stronę główną. + link: Kontynuuj do strony głównej + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: Twój adres e-mail został zaktualizowany. + confirm_new_email_invalid: >- + Przepraszamy, ten link potwierdzający jest już nieaktualny. Być może twój adres e-mail został już zmieniony? + unsubscribe: + page_title: Wypisz się + success_title: Pomyślne anulowanie subskrypcji + success_desc: Zostałeś pomyślnie usunięty z listy subskrybentów i nie będziesz otrzymywać dalszych wiadomości e-mail od nas. + link: Zmień ustawienia + question: + following_tags: Obserwowane tagi + edit: Edytuj + save: Zapisz + follow_tag_tip: Obserwuj tagi, aby dostosować listę pytań. + hot_questions: Gorące pytania + all_questions: Wszystkie pytania + x_questions: "{{ count }} pytań" + x_answers: "{{ count }} odpowiedzi" + x_posts: "{{ count }} Posts" + questions: Pytania + answers: Odpowiedzi + newest: Najnowsze + active: Aktywne + hot: Gorące + frequent: Częste + recommend: Polecane + score: Ocena + unanswered: Bez odpowiedzi + modified: zmodyfikowane + answered: udzielone odpowiedzi + asked: zadane + closed: zamknięte + follow_a_tag: Podążaj za tagiem + more: Więcej + personal: + overview: Przegląd + answers: Odpowiedzi + answer: odpowiedź + questions: Pytania + question: pytanie + bookmarks: Zakładki + reputation: Reputacja + comments: Komentarze + votes: Głosy + badges: Odznaczenia + newest: Najnowsze + score: Ocena + edit_profile: Edytuj Profil + visited_x_days: "Odwiedzone przez {{ count }} dni" + viewed: Wyświetlone + joined: Dołączył + comma: "," + last_login: Widziano + about_me: O mnie + about_me_empty: "// Hello, World !" + top_answers: Najlepsze odpowiedzi + top_questions: Najlepsze pytania + stats: Statystyki + list_empty: Nie znaleziono wpisów.
        Być może chcesz wybrać inną kartę? + content_empty: No posts found. + accepted: Zaakceptowane + answered: Udzielone odpowiedzi + asked: zapytano + downvoted: oceniono negatywnie + mod_short: MOD + mod_long: Moderatorzy + x_reputation: reputacja + x_votes: otrzymane głosy + x_answers: odpowiedzi + x_questions: pytania + recent_badges: Ostatnie odznaki + install: + title: Instalacja + next: Dalej + done: Zakończono + config_yaml_error: Nie można utworzyć pliku config.yaml. + lang: + label: Wybierz język + db_type: + label: Silnik bazy danych + db_username: + label: Nazwa użytkownika + placeholder: root + msg: Nazwa użytkownika nie może być pusta. + db_password: + label: Hasło + placeholder: turbo-tajne-hasło + msg: Hasło nie może być puste. + db_host: + label: Host bazy danych (ewentualnie dodatkowo port) + placeholder: "db.domena:3306" + msg: Host bazy danych nie może być pusty. + db_name: + label: Nazwa bazy danych + placeholder: odpowiedź + msg: Nazwa bazy danych nie może być pusta. + db_file: + label: Plik bazy danych + placeholder: /data/answer.db + msg: Plik bazy danych nie może być pusty. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: Ścieżka do pliku sslrootcert + msg: Ścieżka do pliku sslrootcert nie może być pusta + ssl_cert: + placeholder: Ścieżka do pliku sslcert + msg: Ścieżka do pliku sslcert nie może być pusta + ssl_key: + placeholder: Ścieżka do pliku sslkey + msg: Ścieżka do pliku sslkey nie może być pusta + config_yaml: + title: Utwórz plik config.yaml + label: Plik config.yaml utworzony. + desc: >- + Możesz ręcznie utworzyć plik <1>config.yaml w katalogu <1>/var/wwww/xxx/ i wkleić do niego poniższy tekst. + info: Gdy już to zrobisz, kliknij przycisk "Dalej". + site_information: Informacje o witrynie + admin_account: Konto administratora + site_name: + label: Nazwa witryny + msg: Nazwa witryny nie może być pusta. + msg_max_length: Nazwa witryny musi mieć maksymalnie 30 znaków. + site_url: + label: Adres URL + text: Adres twojej strony. + msg: + empty: Adres URL nie może być pusty. + incorrect: Niepoprawny format adresu URL. + max_length: Adres URL witryny musi mieć maksymalnie 512 znaków. + contact_email: + label: Email kontaktowy + text: Email do osób odpowiedzialnych za tą witrynę. + msg: + empty: Email kontaktowy nie może być pusty. + incorrect: Email do kontaktu ma niepoprawny format. + login_required: + label: Prywatne + switch: Wymagane logowanie + text: Dostęp do tej społeczności mają tylko zalogowani użytkownicy. + admin_name: + label: Imię + msg: Imię nie może być puste. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Hasło + text: >- + Będziesz potrzebować tego hasła do logowania. Przechowuj je w bezpiecznym miejscu. + msg: Hasło nie może być puste. + msg_min_length: Hasło musi mieć co najmniej 8 znaków. + msg_max_length: Hasło musi mieć maksymalnie 32 znaki. + admin_confirm_password: + label: "Potwierdź hasło" + text: "Wprowadź ponownie swoje hasło, aby potwierdzić." + msg: "Potwierdzenie hasła nie jest zgodne." + admin_email: + label: Email + text: Będziesz potrzebować tego adresu e-mail do logowania. + msg: + empty: Adres e-mail nie może być pusty. + incorrect: Niepoprawny format adresu e-mail. + ready_title: Twoja strona jest gotowa + ready_desc: >- + Jeśli kiedykolwiek zechcesz zmienić więcej ustawień, odwiedź <1>sekcję administratora; znajdziesz ją w menu strony. + good_luck: "Baw się dobrze i powodzenia!" + warn_title: Ostrzeżenie + warn_desc: >- + Plik <1>config.yaml już istnieje. Jeśli chcesz zresetować którekolwiek z elementów konfiguracji w tym pliku, proszę go najpierw usunąć. + install_now: Możesz teraz <1>rozpocząć instalację. + installed: Już zainstalowane + installed_desc: >- + Wygląda na to, że masz już zainstalowaną instancję Answer. Aby zainstalować ponownie, proszę najpierw wyczyścić tabele bazy danych. + db_failed: Połączenie z bazą danych nie powiodło się + db_failed_desc: >- + Oznacza to, że informacje o bazie danych w pliku <1>config.yaml są nieprawidłowe lub że nie można nawiązać połączenia z serwerem bazy danych. Może to oznaczać, że serwer bazy danych wskazanego hosta nie działa. + counts: + views: widoki + votes: głosów + answers: odpowiedzi + accepted: Zaakceptowane + page_error: + http_error: Błąd HTTP {{ code }} + desc_403: Nie masz uprawnień do dostępu do tej strony. + desc_404: Niestety, ta strona nie istnieje. + desc_50X: Serwer napotkał błąd i nie mógł zrealizować twojego żądania. + back_home: Powrót do strony głównej + page_maintenance: + desc: "Trwa konserwacja, wrócimy wkrótce." + nav_menus: + dashboard: Panel kontrolny + contents: Zawartość + questions: Pytania + answers: Odpowiedzi + users: Użytkownicy + badges: Badges + flags: Flagi + settings: Ustawienia + general: Ogólne + interface: Interfejs + smtp: SMTP + branding: Marka + legal: Prawne + write: Pisanie + terms: Terms + tos: Warunki korzystania z usługi + privacy: Prywatność + seo: SEO + customize: Dostosowywanie + themes: Motywy + login: Logowanie + privileges: Uprawnienia + plugins: Wtyczki + installed_plugins: Zainstalowane wtyczki + apperance: Wygląd + website_welcome: Witamy w serwisie {{site_name}} + user_center: + login: Zaloguj się + qrcode_login_tip: Zeskanuj kod QR za pomocą {{ agentName }} i zaloguj się. + login_failed_email_tip: Logowanie nie powiodło się, przed ponowną próbą zezwól na dostęp tej aplikacji do informacji o Twojej skrzynce pocztowej. + badges: + modal: + title: Gratulacje + content: Zdobyłeś nową odznakę. + close: Zamknij + confirm: Zobacz odznaki + title: Odznaki + awarded: Przyznano + earned_×: Zdobyto ×{{ number }} + ×_awarded: „{{ number }} przyznano” + can_earn_multiple: Możesz zdobyć tę odznakę wielokrotnie. + earned: Zdobyto + admin: + admin_header: + title: Administrator + dashboard: + title: Panel + welcome: Witaj Administratorze! + site_statistics: Statystyki witryny + questions: "Pytania:" + resolved: "Rozwiązane:" + unanswered: "Bez odpowiedzi:" + answers: "Odpowiedzi:" + comments: "Komentarze:" + votes: "Głosy:" + users: "Użytkownicy:" + flags: "Zgłoszenia:" + reviews: "Przeglądy:" + site_health: "Stan serwisu" + version: "Wersja:" + https: "HTTPS:" + upload_folder: "Prześlij folder:" + run_mode: "Tryb pracy:" + private: Prywatne + public: Publiczne + smtp: "SMTP:" + timezone: "Strefa czasowa:" + system_info: Informacje o systemie + go_version: "Wersja Go:" + database: "Baza danych:" + database_size: "Wielkość bazy danych:" + storage_used: "Wykorzystane miejsce:" + uptime: "Czas pracy:" + links: Linki + plugins: Wtyczki + github: GitHub + blog: Blog + contact: Kontakt + forum: Forum + documents: Dokumenty + feedback: Opinie + support: Wsparcie + review: Przegląd + config: Konfiguracja + update_to: Zaktualizuj do + latest: Najnowszej + check_failed: Sprawdzanie nie powiodło się + "yes": "Tak" + "no": "Nie" + not_allowed: Nie dozwolone + allowed: Dozwolone + enabled: Włączone + disabled: Wyłączone + writable: Zapis i odczyt + not_writable: Nie można zapisać + flags: + title: Flagi + pending: Oczekujące + completed: Zakończone + flagged: Oznaczone + flagged_type: Oznaczone {{ type }} + created: Utworzone + action: Akcja + review: Przegląd + user_role_modal: + title: Zmień rolę użytkownika na... + btn_cancel: Anuluj + btn_submit: Wyślij + new_password_modal: + title: Ustaw nowe hasło + form: + fields: + password: + label: Hasło + text: Użytkownik zostanie wylogowany i musi zalogować się ponownie. + msg: Hasło musi mieć od 8 do 32 znaków. + btn_cancel: Anuluj + btn_submit: Prześlij + edit_profile_modal: + title: Edytuj profil + form: + fields: + display_name: + label: Wyświetlana nazwa + msg_range: Wyświetlana nazwa musi mieć od 2 do 30 znaków. + username: + label: Nazwa użytkownika + msg_range: Nazwa użytkownika musi mieć od 2 do 30 znaków. + email: + label: Email + msg_invalid: Błędny adres e-mail. + edit_success: Edycja zakończona pomyślnie + btn_cancel: Anuluj + btn_submit: Prześlij + user_modal: + title: Dodaj nowego użytkownika + form: + fields: + users: + label: Masowo dodaj użytkownika + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Oddziel "nazwa, e-mail, hasło" przecinkami. Jeden użytkownik na linię. + msg: "Podaj adresy e-mail użytkowników, jeden w każdej linii." + display_name: + label: Nazwa wyświetlana + msg: Wyświetlana nazwa musi mieć od 2 do 30 znaków. + email: + label: E-mail + msg: Email nie jest prawidłowy. + password: + label: Hasło + msg: Hasło musi mieć od 8 do 32 znaków. + btn_cancel: Anuluj + btn_submit: Prześlij + users: + title: Użytkownicy + name: Imię + email: E-mail + reputation: Reputacja + created_at: Czas utworzenia + delete_at: Czas usunięcia + suspend_at: Czas zawieszenia + suspend_until: Zawieszone do + status: Status + role: Rola + action: Akcja + change: Zmień + all: Wszyscy + staff: Personel + more: Więcej + inactive: Nieaktywni + suspended: Zawieszeni + deleted: Usunięci + normal: Normalni + Moderator: Moderator + Admin: Administrator + User: Użytkownik + filter: + placeholder: "Filtruj według imienia, użytkownik:id" + set_new_password: Ustaw nowe hasło + edit_profile: Edytuj profil + change_status: Zmień status + change_role: Zmień rolę + show_logs: Pokaż logi + add_user: Dodaj użytkownika + deactivate_user: + title: Dezaktywuj użytkownika + content: Nieaktywny użytkownik musi ponownie potwierdzić swój adres email. + delete_user: + title: Usuń tego użytkownika + content: Czy na pewno chcesz usunąć tego użytkownika? Ta operacja jest nieodwracalna! + remove: Usuń zawartość + label: Usuń wszystkie pytania, odpowiedzi, komentarze itp. + text: Nie zaznaczaj tego, jeśli chcesz usunąć tylko konto użytkownika. + suspend_user: + title: Zawieś tego użytkownika + content: Zawieszony użytkownik nie może się logować. + label: Na jak długo użytkownik zostanie zawieszony? + forever: Na zawsze + questions: + page_title: Pytania + unlisted: Unlisted + post: Wpis + votes: Głosy + answers: Odpowiedzi + created: Utworzone + status: Status + action: Akcja + change: Zmień + pending: Oczekuje + filter: + placeholder: "Filtruj według tytułu, pytanie:id" + answers: + page_title: Odpowiedzi + post: Wpis + votes: Głosy + created: Utworzone + status: Status + action: Akcja + change: Zmień + filter: + placeholder: "Filtruj według tytułu, odpowiedź:id" + general: + page_title: Ogólne + name: + label: Nazwa witryny + msg: Nazwa strony nie może być pusta. + text: "Nazwa tej strony, używana w tagu tytułu." + site_url: + label: URL strony + msg: Adres Url witryny nie może być pusty. + validate: Podaj poprawny adres URL. + text: Adres Twojej strony. + short_desc: + label: Krótki opis witryny + msg: Krótki opis strony nie może być pusty. + text: "Krótki opis, używany w tagu tytułu na stronie głównej." + desc: + label: Opis witryny + msg: Opis strony nie może być pusty. + text: "Opisz tę witrynę w jednym zdaniu, użytym w znaczniku meta description." + contact_email: + label: Email kontaktowy + msg: Email kontaktowy nie może być pusty. + validate: Email kontaktowy nie jest poprawny. + text: Adres email głównego kontaktu odpowiedzialnego za tę stronę. + check_update: + label: Aktualizacjia oprogramowania + text: Automatycznie sprawdzaj dostępność aktualizacji + interface: + page_title: Interfejs + language: + label: Język Interfejsu + msg: Język interfejsu nie może być pusty. + text: Język interfejsu użytkownika. Zmieni się po odświeżeniu strony. + time_zone: + label: Strefa czasowa + msg: Strefa czasowa nie może być pusta. + text: Wybierz miasto w tej samej strefie czasowej, co Ty. + avatar: + label: Domyślny awatar + text: Dla użytkowników, którzy nie ustawili własnego awatara. + gravatar_base_url: + label: Bazowy URL Gravatara + text: Adres bazowy API dostawcy Gravatara. Ignorowane, jeśli puste. + smtp: + page_title: SMTP + from_email: + label: Email nadawcy + msg: Email nadawcy nie może być pusty. + text: Adres email, z którego są wysyłane wiadomości. + from_name: + label: Nazwa w polu Od + msg: Nazwa nadawcy nie może być pusta. + text: Nazwa, z której są wysyłane wiadomości. + smtp_host: + label: Serwer SMTP + msg: Host SMTP nie może być pusty. + text: Twój serwer poczty. + encryption: + label: Szyfrowanie + msg: Szyfrowanie nie może być puste. + text: Dla większości serwerów zalecana jest opcja SSL. + ssl: SSL + tls: TLS + none: Brak + smtp_port: + label: Port SMTP + msg: Port SMTP musi być liczbą od 1 do 65535. + text: Port Twojego serwera poczty. + smtp_username: + label: Nazwa użytkownika SMTP + msg: Nazwa użytkownika SMTP nie może być pusta. + smtp_password: + label: Hasło SMTP + msg: Hasło SMTP nie może być puste. + test_email_recipient: + label: Odbiorcy testowych wiadomości email + text: Podaj adres email, który otrzyma testowe wiadomości. + msg: Odbiorcy testowych wiadomości email są nieprawidłowi + smtp_authentication: + label: Wymagaj uwierzytelniania + title: Uwierzytelnianie SMTP + msg: Uwierzytelnianie SMTP nie może być puste. + "yes": "Tak" + "no": "Nie" + branding: + page_title: Marka + logo: + label: Logo + msg: Logo nie może być puste. + text: Obrazek logo znajdujący się na górze lewej strony Twojej strony. Użyj szerokiego prostokątnego obrazka o wysokości 56 pikseli i proporcjach większych niż 3:1. Jeśli zostanie puste, wyświetlony zostanie tekst tytułu strony. + mobile_logo: + label: Logo mobilne + text: Logo używane w wersji mobilnej Twojej strony. Użyj szerokiego prostokątnego obrazka o wysokości 56 pikseli. Jeśli zostanie puste, użyty zostanie obrazek z ustawienia "logo". + square_icon: + label: Kwadratowa ikona + msg: Kwadratowa ikona nie może być pusta. + text: Obrazek używany jako podstawa dla ikon metadanych. Powinien mieć idealnie większe wymiary niż 512x512 pikseli. + favicon: + label: Ikona (favicon) + text: Ulubiona ikona witryny. Aby działać poprawnie przez CDN, musi to być png. Rozmiar zostanie zmieniony na 32x32. Jeśli pozostanie puste, zostanie użyta "kwadratowa ikona". + legal: + page_title: Prawne + terms_of_service: + label: Warunki korzystania z usługi + text: "Możesz tutaj dodać treść regulaminu. Jeśli masz dokument hostowany gdzie indziej, podaj tutaj pełny URL." + privacy_policy: + label: Polityka prywatności + text: "Możesz tutaj dodać treść polityki prywatności. Jeśli masz dokument hostowany gdzie indziej, podaj tutaj pełny URL." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Pisanie + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Każdy użytkownik może napisać tylko jedną odpowiedź na każde pytanie + text: "Wyłącz, aby pozwolić użytkownikom pisać wiele odpowiedzi na to samo pytanie, co może powodować, że odpowiedzi będą mniej skupione." + min_tags: + label: "Minimalna liczba tagów na pytanie" + text: "Minimalna liczba tagów wymagana w pytaniu." + recommend_tags: + label: Rekomendowane tagi + text: "Rekomendowane tagi będą domyślnie wyświetlane na liście wyboru." + msg: + contain_reserved: "Rekomendowane tagi nie mogą zawierać tagów zarezerwowanych." + required_tag: + title: Ustaw wymagane tagi + label: Ustaw „Rekomendowane tagi” jako wymagane + text: "Każde nowe pytanie musi mieć przynajmniej jeden rekomendowany tag." + reserved_tags: + label: Zarezerwowane tagi + text: "Zarezerwowane tagi mogą być używane tylko przez moderatorów." + image_size: + label: Maksymalny rozmiar obrazu (MB) + text: "Maksymalny dopuszczalny rozmiar przesyłanego obrazu." + attachment_size: + label: Maksymalny rozmiar załącznika (MB) + text: "Maksymalny dopuszczalny rozmiar przesyłanych plików." + image_megapixels: + label: Maksymalna liczba megapikseli + text: "Maksymalna liczba megapikseli dopuszczona dla obrazu." + image_extensions: + label: Dozwolone rozszerzenia obrazów + text: "Lista rozszerzeń plików dozwolonych dla obrazów; oddziel po przecinkach." + attachment_extensions: + label: Dozwolone rozszerzenia załączników + text: "Lista rozszerzeń plików dozwolonych do przesyłania; oddziel po przecinkach. UWAGA: Zezwolenie na przesyłanie plików może powodować ryzyko bezpieczeństwa." + seo: + page_title: SEO + permalink: + label: Link bezpośredni + text: Dostosowane struktury URL mogą poprawić użyteczność i kompatybilność w przyszłości Twoich linków. + robots: + label: robots.txt + text: To trwale zastąpi wszelkie związane z witryną ustawienia. + themes: + page_title: Motywy + themes: + label: Motywy + text: Wybierz istniejący motyw. + color_scheme: + label: Schemat kolorów + navbar_style: + label: Navbar background style + primary_color: + label: Kolor podstawowy + text: Zmodyfikuj kolory używane przez Twoje motywy. + css_and_html: + page_title: CSS i HTML + custom_css: + label: Własny CSS + text: > + + head: + label: Głowa + text: > + + header: + label: Nagłówek + text: > + + footer: + label: Stopka + text: Zostanie wstawione przed </body>. + sidebar: + label: Pasek boczny + text: Będzie wstawiony w pasku bocznym. + login: + page_title: Logowanie + membership: + title: Członkostwo + label: Zezwalaj na nowe rejestracje + text: Wyłącz, aby uniemożliwić komukolwiek tworzenie nowego konta. + email_registration: + title: Rejestracja przez email + label: Zezwalaj na rejestrację przez email + text: Wyłącz, aby uniemożliwić tworzenie nowego konta poprzez email. + allowed_email_domains: + title: Dozwolone domeny email + text: Domeny email, z których użytkownicy muszą rejestrować konta. Jeden domena na linię. Ignorowane, gdy puste. + private: + title: Prywatne + label: Wymagane logowanie + text: Dostęp do tej społeczności mają tylko zalogowani użytkownicy. + password_login: + title: Hasło logowania + label: Zezwalaj na logowanie email i hasłem + text: "OSTRZEŻENIE: Jeśli wyłączone, już się nie zalogujesz, jeśli wcześniej nie skonfigurowałeś innej metody logowania." + installed_plugins: + title: Zainstalowane wtyczki + plugin_link: Wtyczki rozszerzają i rozbudowują funkcjonalność. Wtyczki znajdziesz w <1>Repozytorium Wtyczek. + filter: + all: Wszystkie + active: Aktywne + inactive: Nieaktywne + outdated: Przestarzałe + plugins: + label: Wtyczki + text: Wybierz istniejącą wtyczkę. + name: Nazwa + version: Wersja + status: Status + action: Akcja + deactivate: Deaktywuj + activate: Aktywuj + settings: Ustawienia + settings_users: + title: Użytkownicy + avatar: + label: Domyślny Awatar + text: Dla użytkowników bez własnego awatara. + gravatar_base_url: + label: Adres URL bazy Gravatar + text: Adres URL bazy API dostawcy Gravatar. Ignorowane, gdy puste. + profile_editable: + title: Edycja profilu + allow_update_display_name: + label: Zezwalaj użytkownikom na zmianę wyświetlanej nazwy + allow_update_username: + label: Zezwalaj użytkownikom na zmianę nazwy użytkownika + allow_update_avatar: + label: Zezwalaj użytkownikom na zmianę obrazka profilowego + allow_update_bio: + label: Zezwalaj użytkownikom na zmianę opisu + allow_update_website: + label: Zezwalaj użytkownikom na zmianę witryny + allow_update_location: + label: Zezwalaj użytkownikom na zmianę lokalizacji + privilege: + title: Uprawnienia + level: + label: Wymagany poziom reputacji + text: Wybierz reputację wymaganą dla tego uprawnienia + msg: + should_be_number: Wartość musi być liczbą + number_larger_1: Liczba musi być równa 1 lub większa + badges: + action: Akcja + active: Aktywne + activate: Aktywuj + all: Wszystkie + awards: Przyznane + deactivate: Dezaktywuj + filter: + placeholder: Filtruj po nazwie, badge:id + group: Grupa + inactive: Nieaktywne + name: Nazwa + show_logs: Wyświetl dzienniki + status: Status + title: Odznaki + form: + optional: (opcjonalne) + empty: nie może być puste + invalid: jest nieprawidłowe + btn_submit: Zapisz + not_found_props: "Nie znaleziono wymaganej właściwości {{ key }}." + select: Wybierz + page_review: + review: Przegląd + proposed: zaproponowany + question_edit: Edycja pytania + answer_edit: Edycja odpowiedzi + tag_edit: Edycja tagu + edit_summary: Podsumowanie edycji + edit_question: Edytuj pytanie + edit_answer: Edytuj odpowiedź + edit_tag: Edytuj tag + empty: Nie ma więcej zadań do przeglądu. + approve_revision_tip: Czy akceptujesz tę wersję? + approve_flag_tip: Czy akceptujesz tę flagę? + approve_post_tip: Czy zatwierdzasz ten post? + approve_user_tip: Czy zatwierdzasz tego użytkownika? + suggest_edits: Sugerowane edycje + flag_post: Oznacz wpis + flag_user: Oznacz użytkownika + queued_post: Oczekujący post + queued_user: Oczekujący użytkownik + filter_label: Typ + reputation: reputacja + flag_post_type: Oznaczono ten wpis jako {{ type }}. + flag_user_type: Oznaczono tego użytkownika jako {{ type }}. + edit_post: Edytuj wpis + list_post: List post + unlist_post: Unlist post + timeline: + undeleted: nieusunięte + deleted: usunięty + downvote: odrzucenie + upvote: głos za + accept: akceptacja + cancelled: anulowane + commented: skomentowano + rollback: wycofaj + edited: edytowany + answered: odpowiedziano + asked: zapytano + closed: zamknięty + reopened: ponownie otwarty + created: utworzony + pin: przypięty + unpin: odpięty + show: wymieniony + hide: niewidoczne + title: "Historia dla" + tag_title: "Historia dla" + show_votes: "Pokaż głosy" + n_or_a: Nie dotyczy + title_for_question: "Historia dla" + title_for_answer: "Oś czasu dla odpowiedzi na {{ tytuł }} autorstwa {{ autor }}" + title_for_tag: "Oś czasu dla tagu" + datetime: Data i czas + type: Typ + by: Przez + comment: Komentarz + no_data: "Nie mogliśmy nic znaleźć." + users: + title: Użytkownicy + users_with_the_most_reputation: Użytkownicy o najwyższej reputacji w tym tygodniu + users_with_the_most_vote: Użytkownicy, którzy oddali najwięcej głosów w tym tygodniu + staffs: Nasz personel społeczności + reputation: reputacja + votes: głosy + prompt: + leave_page: Czy na pewno chcesz opuścić stronę? + changes_not_save: Twoje zmiany mogą nie zostać zapisane. + draft: + discard_confirm: Czy na pewno chcesz odrzucić swoją wersję roboczą? + messages: + post_deleted: Ten post został usunięty. + post_cancel_deleted: Usunięcie tego posta zostało anulowane. + post_pin: Ten post został przypięty. + post_unpin: Ten post został odpięty. + post_hide_list: Ten post został ukryty na liście. + post_show_list: Ten post został wyświetlony na liście. + post_reopen: Ten post został ponownie otwarty. + post_list: Ten wpis został umieszczony na liście. + post_unlist: Ten wpis został usunięty z listy. + post_pending: Twój wpis oczekuje na recenzje. Będzie widoczny po jej akceptacji. + post_closed: Ten post został zamknięty. + answer_deleted: Ta odpowiedź została usunięta. + answer_cancel_deleted: Ta odpowiedź została przywrócona. + change_user_role: Rola tego użytkownika została zmieniona. + user_inactive: Ten użytkownik jest już nieaktywny. + user_normal: Ten użytkownik jest już aktywny. + user_suspended: Ten użytkownik został zawieszony. + user_deleted: Ten użytkownik został usunięty. + badge_activated: Ta odznaka została aktywowana. + badge_inactivated: Ta odznaka została dezaktywowana. + users_deleted: Ci użytkownicy zostali usunięci. + posts_deleted: Te pytania zostały usunięte. + answers_deleted: Te odpowiedzi zostały usunięte. + copy: Skopiuj do schowka + copied: Skopiowano + external_content_warning: Zewnętrzne obrazy/media nie są wyświetlane. + diff --git a/data/i18n/pt_BR.yaml b/data/i18n/pt_BR.yaml new file mode 100644 index 000000000..45e00873c --- /dev/null +++ b/data/i18n/pt_BR.yaml @@ -0,0 +1,1381 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: Sucesso. + unknown: + other: Erro desconhecido. + request_format_error: + other: O formato da Requisição não é válido. + unauthorized_error: + other: Não autorizado. + database_error: + other: Erro no servidor de dados. + role: + name: + user: + other: Usuário + admin: + other: Administrador + moderator: + other: Moderador + description: + user: + other: Padrão sem acesso especial. + admin: + other: Possui controle total para acessar o site. + moderator: + other: Não possui controle a todas as postagens exceto configurações de administrador. + email: + other: E-mail + password: + other: Senha + email_or_password_wrong_error: + other: E-mail e Senha inválidos. + error: + admin: + email_or_password_wrong: + other: E-mail e Senha inválidos. + answer: + not_found: + other: Resposta não encontrada. + cannot_deleted: + other: Permissão insuficiente para deletar. + cannot_update: + other: Permissão insuficiente para atualizar. + comment: + edit_without_permission: + other: Não é permitido atualizar comentários. + not_found: + other: Comentário não encontrado. + cannot_edit_after_deadline: + other: O tempo para comentários expirou. + email: + duplicate: + other: E-mail já existe na base de dados. + need_to_be_verified: + other: E-mail precisa ser verificado. + verify_url_expired: + other: A URL de validação do e-mail expirou, por favor, re-envie o e-mail. + lang: + not_found: + other: Arquivo de idioma não encontrado. + object: + captcha_verification_failed: + other: Captcha inválido. + disallow_follow: + other: Você não possui permissão para seguir. + disallow_vote: + other: Você não possui permissão para votar. + disallow_vote_your_self: + other: Você não pode votar na sua própria postagem. + not_found: + other: Objeto não encontrado. + verification_failed: + other: Falha na verificação. + email_or_password_incorrect: + other: E-mail e Senha não conferem. + old_password_verification_failed: + other: Verficação de senhas antigas falhou. + new_password_same_as_previous_setting: + other: A nova senha é idêntica à senha anterior. + question: + not_found: + other: Pergunta não encontrada. + cannot_deleted: + other: Não possui permissão para deletar. + cannot_close: + other: Não possui permissão para fechar. + cannot_update: + other: Não possui permissão para atualizar.. + rank: + fail_to_meet_the_condition: + other: A classificação não atende à condição. + report: + handle_failed: + other: Falha no processamento do relatório. + not_found: + other: Relatório não encontrado. + tag: + not_found: + other: Marcador não encontada. + recommend_tag_not_found: + other: Marcador recomendado não existe. + recommend_tag_enter: + other: Por favor, insira ao menos um marcador obrigatório. + not_contain_synonym_tags: + other: Não pode contar marcadores de sinônimos. + cannot_update: + other: Não possui permissão para atualizar. + cannot_set_synonym_as_itself: + other: Você não pode definir o sinônimo do marcador atual como ela mesma. + smtp: + config_from_name_cannot_be_email: + other: O De Nome não pode ser um endereço de e-mail. + Tema: + not_found: + other: Tema não encontrado. + revision: + review_underway: + other: Não é possível editar no momento, há uma versão na fila de revisão. + no_permission: + other: Sem pemissão para revisar. + user: + email_or_password_wrong: + other: + other: E-mail e senha não correspondem. + not_found: + other: Usuário não encontrado. + suspended: + other: Usuário foi suspenso. + username_invalid: + other: Nome de usuário inválido. + username_duplicate: + other: Nome de usuário já está em uso. + set_avatar: + other: Falha ao configurar Avatar. + cannot_update_your_role: + other: Você não pode modificar a sua função. + not_allowed_registration: + other: Atualmente o site não está aberto para cadastro + config: + read_config_failed: + other: A leitura da configuração falhou + database: + connection_failed: + other: Falha na conexão com o banco de dados + create_table_failed: + other: Falha na criação de tabela + install: + create_config_failed: + other: Não foi possível criar o arquivo config.yaml. + upload: + unsupported_file_format: + other: Formato de arquivo não suportado. + report: + spam: + name: + other: spam + desc: + other: Este post é um anúncio, ou vandalismo. Não é útil ou relevante para o tópico atual. + rude: + name: + other: rude ou abusivo + desc: + other: Uma pessoa razoável acharia este conteúdo impróprio para um discurso respeitoso. + duplicate: + name: + other: uma duplicidade + desc: + other: Esta pergunta já foi feita antes e já tem uma resposta. + not_answer: + name: + other: não é uma resposta + desc: + other: Isso foi postado como uma resposta, mas não tenta responder à pergunta. Possivelmente deve ser uma edição, um comentário, outra pergunta ou excluído completamente. + not_need: + name: + other: não é mais necessário + desc: + other: Este comentário está desatualizado, coloquial ou não é relevante para esta postagem. + other: + name: + other: algo mais + desc: + other: Esta postagem requer atenção da equipe por outro motivo não listado acima. + question: + close: + duplicate: + name: + other: spam + desc: + other: Esta pergunta já foi feita antes e já tem uma resposta. + guideline: + name: + other: um motivo específico da comunidade + desc: + other: Esta pergunta não atende a uma diretriz da comunidade. + multiple: + name: + other: precisa de detalhes ou clareza + desc: + other: Esta pergunta atualmente inclui várias perguntas em uma. Deve se concentrar em apenas um problema. + other: + name: + other: algo mais + desc: + other: Este post requer outro motivo não listado acima. + operation_type: + asked: + other: perguntado + answered: + other: respondido + modified: + other: modificado + notification: + action: + update_question: + other: pergunta atualizada + answer_the_question: + other: pergunta respondida + update_answer: + other: resposta atualizada + accept_answer: + other: resposta aceita + comment_question: + other: pergunta comentada + comment_answer: + other: resposta comentada + reply_to_you: + other: respondeu a você + mention_you: + other: mencionou você + your_question_is_closed: + other: A sua pergunta foi fechada + your_question_was_deleted: + other: A sua pergunta foi deletada + your_answer_was_deleted: + other: A sua resposta foi deletada + your_comment_was_deleted: + other: O seu comentário foi deletado +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Como formatar + desc: >- +
        • para mais links

          <https://url.com>

          [Título](https://url.com)
        • colocar retornos entre parágrafos

        • _italic_ ou **bold**

        • identar código por 4 espaços

        • cotação colocando > no início da linha

        • aspas invertidas `tipo_isso`

        • criar cercas de código com aspas invertidas `

          ```
          código aqui
          ```
        + pagination: + prev: Anterior + next: Próximo + page_title: + question: Pergunta + questions: Perguntas + tag: Marcador + tags: Marcadores + tag_wiki: marcador wiki + edit_tag: Editar Marcador + ask_a_question: Adicionar Pergunta + edit_question: Editar Pergunta + edit_answer: Editar Resposta + search: Busca + posts_containing: Postagens contendo + settings: Configurações + notifications: Notificações + login: Entrar + sign_up: Criar conta + account_recovery: Recuperação de conta + account_activation: Ativação de conta + confirm_email: Confirmação de e-mail + account_suspended: Conta suspensa + admin: Administrador + change_email: Modificar e-mail + install: Instalação do Resposta + upgrade: Atualização do Resposta + maintenance: Manutenção do Website + users: Usuários + notifications: + title: Notificações + inbox: Caixa de entrada + achievement: Conquistas + all_read: Marcar todas como lidas + show_more: Mostrar mais + suspended: + title: A sua conta foi suspensa + until_time: "A sua conta foi suspensa até {{ time }}." + forever: Este usuário foi suspenso por tempo indeterminado. + end: Você não atende a uma diretriz da comunidade. + editor: + blockquote: + text: Bloco de citação + bold: + text: Forte + chart: + text: Gráfico + flow_chart: Fluxograma + sequence_diagram: Diagrama de sequência + class_diagram: Diagrama de classe + state_diagram: Diagrama de estado + entity_relationship_diagram: Diagrama de relacionamento de entidade + user_defined_diagram: Diagrama definido pelo usuário + gantt_chart: Diagrama de Gantt + pie_chart: Gráfico de pizza + code: + text: Código de exemplo + add_code: Adicione código de exemplo + form: + fields: + code: + label: Código + msg: + empty: Código não pode ser vazio. + language: + label: Idioma (opcional) + placeholder: Detecção automática + btn_cancel: Cancelar + btn_confirm: Adicionar + formula: + text: Fórmula + options: + inline: Fórmula em linha + block: Fórmula em bloco + Cabeçalho: + text: Cabeçalho + options: + h1: Cabeçalho 1 + h2: Cabeçalho 2 + h3: Cabeçalho 3 + h4: Cabeçalho 4 + h5: Cabeçalho 5 + h6: Cabeçalho 6 + help: + text: Ajuda + hr: + text: Régua horizontal + image: + text: Imagem + add_image: Adicionar imagem + tab_image: Enviar imagem + form_image: + fields: + file: + label: Arquivo de imagem + btn: Selecione imagem + msg: + empty: Arquivo não pode ser vazio. + only_image: Somente um arquivo de imagem é permitido. + max_size: O tamanho do arquivo não pode exceder 4 MB. + desc: + label: Descrição (opcional) + tab_url: URL da imagem + form_url: + fields: + url: + label: URL da imagem + msg: + empty: URL da imagem não pode ser vazia. + name: + label: Descrição (opcional) + btn_cancel: Cancelar + btn_confirm: Adicionar + uploading: Enviando + indent: + text: Identação + outdent: + text: Não identado + italic: + text: Ênfase + link: + text: Superlink (Hyperlink) + add_link: Adicionar superlink (hyperlink) + form: + fields: + url: + label: URL + msg: + empty: URL não pode ser vazia. + name: + label: Descrição (opcional) + btn_cancel: Cancelar + btn_confirm: Adicionar + ordered_list: + text: Lista numerada + unordered_list: + text: Lista com marcadores + table: + text: Tabela + Cabeçalho: Cabeçalho + cell: Célula + close_modal: + title: Estou fechando este post como... + btn_cancel: Cancelar + btn_submit: Enviar + remark: + empty: Não pode ser vazio. + msg: + empty: Por favor selecione um motivo. + report_modal: + flag_title: I am flagging to report this post as... + close_title: Estou fechando este post como... + review_question_title: Revisar pergunta + review_answer_title: Revisar resposta + review_comment_title: Revisar comentário + btn_cancel: Cancelar + btn_submit: Enviar + remark: + empty: Não pode ser vazio. + msg: + empty: Por favor selecione um motivo. + tag_modal: + title: Criar novo marcador + form: + fields: + display_name: + label: Nome de exibição + msg: + empty: Nome de exibição não pode ser vazio. + range: Nome de exibição tem que ter até 35 caracteres. + slug_name: + label: Slug de URL + desc: 'Deve usar o conjunto de caracteres "a-z", "0-9", "+ # - ."' + msg: + empty: URL slug não pode ser vazio. + range: URL slug até 35 caracteres. + character: URL slug contém conjunto de caracteres não permitido. + desc: + label: Descrição (opcional) + btn_cancel: Cancelar + btn_submit: Enviar + tag_info: + created_at: Criado + edited_at: Editado + history: Histórico + synonyms: + title: Sinônimos + text: Os marcadores a seguir serão re-mapeados para + empty: Sinônimos não encotrados. + btn_add: Adicionar um sinônimo + btn_edit: Editar + btn_save: Salvar + synonyms_text: Os marcadores a seguir serão re-mapeados para + delete: + title: Deletar este marcador + content: >- +

        Não permitimos a exclusão de marcadores com postagens.

        Por favor, remova este marcador das postagens primeiro.

        + content2: Você tem certeza que deseja deletar? + close: Fechar + edit_tag: + title: Editar marcador + default_reason: Editar marcador + form: + fields: + revision: + label: Revisão + display_name: + label: Nome de exibição + slug_name: + label: Slug de URL + info: 'Deve usar o conjunto de caracteres "a-z", "0-9", "+ # - ."' + desc: + label: Descrição + edit_summary: + label: Resumo da edição + placeholder: >- + Explique resumidamente suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada) + btn_save_edits: Salvar edições + btn_cancel: Cancelar + dates: + long_date: D MMM + long_date_with_year: "D MMM, YYYY" + long_date_with_time: "D MMM, YYYY [at] HH:mm" + now: agora + x_seconds_ago: "{{count}}s atrás" + x_minutes_ago: "{{count}}m atrás" + x_hours_ago: "{{count}}h atrás" + hour: hora + day: dia + comment: + btn_add_comment: Adicionar comentário + reply_to: Responder a + btn_reply: Responder + btn_edit: Editar + btn_delete: Deletar + btn_flag: Marcador + btn_save_edits: Salvar edições + btn_cancel: Cancelar + show_more: Mostrar mais comentários + tip_question: >- + Use os comentários para pedir mais informações ou sugerir melhorias. Evite responder perguntas nos comentários. + tip_answer: >- + Use comentários para responder a outros usuários ou notificá-los sobre alterações. Se você estiver adicionando novas informações, edite sua postagem em vez de comentar. + edit_answer: + title: Editar Resposta + default_reason: Editar Resposta + form: + fields: + revision: + label: Revisão + answer: + label: Resposta + feedback: + caracteres: conteúdo deve ser pelo menos 6 caracteres em comprimento. + edit_summary: + label: Resumo da edição + placeholder: >- + Explique resumidamente suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada) + btn_save_edits: Salvar edições + btn_cancel: Cancelar + tags: + title: Marcadores + sort_buttons: + popular: Popular + name: Nome + newest: mais recente + button_follow: Seguir + button_following: Seguindo + tag_label: perguntas + search_placeholder: Filtrar por nome de marcador + no_desc: O marcador não possui descrição. + more: Mais + ask: + title: Adicionar Pergunta + edit_title: Editar Pergunta + default_reason: Editar pergunta + similar_questions: Perguntas similares + form: + fields: + revision: + label: Revisão + title: + label: Título + placeholder: Seja específico e tenha em mente que está fazendo uma pergunta a outra pessoa + msg: + empty: Título não pode ser vazio. + range: Título até 150 caracteres + body: + label: Corpo + msg: + empty: Corpo da mensagem não pode ser vazio. + tags: + label: Marcadores + msg: + empty: Marcadores não podes ser vazios. + answer: + label: Resposta + msg: + empty: Resposta não pode ser vazia. + edit_summary: + label: Resumo da edição + placeholder: >- + Explique resumidamente suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada) + btn_post_question: Publicar a sua pergunta + btn_save_edits: Salvar edições + answer_question: Responda a sua própria pergunta + post_question&answer: Publicar a sua pergunta e resposta + tag_selector: + add_btn: Adicionar marcador + create_btn: Criar novo marcador + search_tag: Procurar marcador + hint: "Descreva do quê se trata a sua pergunta, ao menos um marcador é requirido." + no_result: Nenhum marcador correspondente + tag_required_text: Marcador obrigatório (ao menos um) + header: + nav: + question: Perguntas + tag: Marcadores + user: Usuários + profile: Perfil + setting: Configurações + logout: Sair + admin: Administrador + review: Revisar + search: + placeholder: Procurar + footer: + build_on: >- + Desenvolvido com base no <1> Answer — o software de código aberto que alimenta comunidades de perguntas e respostas.
        Feito com amor © {{cc}}. + upload_img: + name: Mudar + loading: carregando... + pic_auth_code: + title: Captcha + placeholder: Escreva o texto acima + msg: + empty: Captcha não pode ser vazio. + inactive: + first: >- + Você está quase pronto! Enviamos um e-mail de ativação para {{mail}}. Por favor, siga as instruções no e-mail para ativar uma conta sua. + info: "Se não chegar, verifique sua pasta de spam." + another: >- + Enviamos outro e-mail de ativação para você em {{mail}}. Pode levar alguns minutos para chegar; certifique-se de verificar sua pasta de spam. + btn_name: Reenviar e-mail de ativação + change_btn_name: Mudar email + msg: + empty: Não pode ser vazio. + login: + page_title: Bem vindo ao {{site_name}} + login_to_continue: Entre para continuar + info_sign: Não possui uma conta? <1>Cadastrar-se + info_login: Já possui uma conta? <1>Entre + agreements: Ao se registrar, você concorda com as <1>políticas de privacidades e os <3>termos de serviços. + forgot_pass: Esqueceu a sua senha? + name: + label: Nome + msg: + empty: Nome não pode ser vazio. + range: Nome até 30 caracteres. + email: + label: E-mail + msg: + empty: E-mail não pode ser vazio. + password: + label: Senha + msg: + empty: Senha não pode ser vazia. + different: As senhas inseridas em ambos os campos são inconsistentes + account_forgot: + page_title: Esqueceu a sua senha + btn_name: Enviar e-mail de recuperação de senha + send_success: >- + Se uma conta corresponder {{mail}}, você deve receber um e-mail com instruções sobre como redefinir sua senha em breve. + email: + label: E-mail + msg: + empty: E-mail não pode ser vazio. + change_email: + page_title: Bem vindo ao {{site_name}} + btn_cancel: Cancelar + btn_update: Atualiza email address + send_success: >- + Se uma conta corresponder {{mail}}, você deve receber um e-mail com instruções sobre como redefinir sua senha em breve. + email: + label: Novo E-mail + msg: + empty: E-mail não pode ser vazio. + password_reset: + page_title: Redefinir senha + btn_name: Redefinir minha senha + reset_success: >- + Você alterou com sucesso uma senha sua; você será redirecionado para a página de login. + link_invalid: >- + Desculpe, este link de redefinição de senha não é mais válido. Talvez uma senha sua já tenha sido redefinida? + to_login: Continuar para a tela de login + password: + label: Senha + msg: + empty: Senha não pode ser vazio. + length: O comprimento deve estar entre 8 e 32 + different: As senhas inseridas em ambos os campos são inconsistentes + password_confirm: + label: Confirmar Nova senha + settings: + page_title: Configurações + nav: + profile: Perfil + notification: Notificações + account: Conta + interface: Interface + profile: + Cabeçalho: Perfil + btn_name: Salvar + display_name: + label: Nome de exibição + msg: Nome de exibição não pode ser vazio. + msg_range: Nome de exibição tem que ter até 30 caracteres. + username: + label: Nome de usuário + caption: As pessoas poderão mensionar você com "@usuário". + msg: Nome de usuário não pode ser vazio. + msg_range: Nome de usuário até 30 caracteres. + character: 'Deve usar o conjunto de caracteres "a-z", "0-9", "- . _"' + avatar: + label: Perfil Imagem + gravatar: Gravatar + gravatar_text: Você pode mudar a imagem em <1>gravatar.com + custom: Customizado + btn_refresh: Atualizar + custom_text: Você pode enviar a sua image. + default: System + msg: Por favor envie um avatar + bio: + label: Sobre mim (opcional) + website: + label: Website (opcional) + placeholder: "https://exemplo.com.br" + msg: Formato incorreto de endereço de Website + location: + label: Localização (opcional) + placeholder: "Cidade, País" + notification: + Cabeçalho: Notificações + email: + label: E-mail Notificações + radio: "Responda as suas perguntas, comentários, e mais" + account: + Cabeçalho: Conta + change_email_btn: Mudar e-mail + change_pass_btn: Mudar senha + change_email_info: >- + Enviamos um e-mail para esse endereço. Siga as instruções de confirmação. + email: + label: E-mail + msg: E-mail não pode ser vazio. + password_title: Senha + current_pass: + label: Senha atual + msg: + empty: A Senha não pode ser vazia. + length: O comprimento deve estar entre 8 and 32. + different: As duas senhas inseridas não correspondem. + new_pass: + label: Nova Senha + pass_confirm: + label: Confirmar nova Senha + interface: + Cabeçalho: Interface + lang: + label: Idioma da Interface + text: Idioma da interface do usuário. A interface mudará quando você atualizar a página. + toast: + update: atualização realizada com sucesso + update_password: Senha alterada com sucesso. + flag_success: Obrigado por marcar. + forbidden_operate_self: Proibido para operar por você mesmo + review: A sua resposta irá aparecer após a revisão. + related_question: + title: Perguntas relacionadas + btn: Adicionar pegunta + answers: respostas + question_detail: + Perguntado: Perguntado + asked: perguntado + update: Modificado + edit: modificado + Views: Visualizado + Seguir: Seguir + Seguindo: Seguindo + answered: respondido + closed_in: Fechado em + show_exist: Mostrar pergunta existente. + answers: + title: Respostas + score: Pontuação + newest: Mais recente + btn_accept: Aceito + btn_accepted: Aceito + write_answer: + title: A sua Resposta + btn_name: Publicação a sua resposta + add_another_answer: Adicionar outra resposta + confirm_title: Continuar a responder + continue: Continuar + confirm_info: >- +

        Tem certeza de que deseja adicionar outra resposta?

        Você pode usar o link de edição para refinar e melhorar uma resposta existente.

        + empty: Resposta não pode ser vazio. + caracteres: conteúdo deve ser pelo menos 6 caracteres em comprimento. + reopen: + title: Reabrir esta postagem + content: Tem certeza que deseja reabrir? + success: Esta postagem foi reaberta + delete: + title: Excluir esta postagem + question: >- + Nós não recomendamos excluir perguntas com respostas porque isso priva os futuros leitores desse conhecimento.

        A exclusão repetida de perguntas respondidas pode resultar no bloqueio de perguntas de sua conta. Você tem certeza que deseja excluir? + answer_accepted: >- +

        Não recomendamos excluir resposta aceita porque isso priva os futuros leitores desse conhecimento.

        A exclusão repetida de respostas aceitas pode resultar no bloqueio de respostas de uma conta sua. Você tem certeza que deseja excluir? + other: Você tem certeza que deseja deletar? + tip_question_deleted: Esta postagem foi deletada + tip_answer_deleted: Esta resposta foi deletada + btns: + confirm: Confirmar + cancel: Cancelar + save: Salvar + delete: Deletar + login: Entrar + signup: Cadastrar-se + logout: Sair + verify: Verificar + add_question: Adicionar pergunta + approve: Aprovar + reject: Rejetar + skip: Pular + search: + title: Procurar Resultados + keywords: Palavras-chave + options: Opções + follow: Seguir + following: Seguindo + counts: "{{count}} Resultados" + more: Mais + sort_btns: + relevance: Relevância + newest: Mais recente + active: Ativar + score: Pontuação + more: Mais + tips: + title: Dicas de Pesquisa Avançada + tag: "<1>[tag] pesquisar dentro de um marcador" + user: "<1>user:username buscar por autor" + answer: "<1>answers:0 perguntas não respondidas" + score: "<1>score:3 postagens com mais de 3+ placares" + question: "<1>is:question buscar perguntas" + is_answer: "<1>is:answer buscar respostas" + empty: Não conseguimos encontrar nada.
        Tente palavras-chave diferentes ou menos específicas. + share: + name: Compartilhar + copy: Copiar link + via: Compartilhar postagem via... + copied: Copiado + facebook: Compartilhar no Facebook + twitter: Compartilhar no X + cannot_vote_for_self: Você não pode votar na sua própria postagem + modal_confirm: + title: Erro... + account_result: + page_title: Bem vindo ao {{site_name}} + success: A sua nova conta está confirmada; você será redirecionado para a página inicial. + link: Continuar para a página inicial. + invalid: >- + Desculpe, este link de confirmação não é mais válido. Talvez a sua já está ativa. + confirm_new_email: Seu e-mail foi atualizado. + confirm_new_email_invalid: >- + Desculpe, este link de confirmação não é mais válido. Talvez o seu e-mail já tenha sido alterado. + unsubscribe: + page_title: Cancelar subscrição + success_title: Cancelamento de inscrição bem-sucedido + success_desc: Você foi removido com sucesso desta lista de assinantes e não receberá mais nenhum e-mail nosso. + link: Mudar configurações + question: + following_tags: Seguindo Marcadores + edit: Editar + save: Salvar + follow_tag_tip: Siga as tags para selecionar sua lista de perguntas. + hot_questions: Perguntas quentes + all_questions: Todas Perguntas + x_questions: "{{ count }} perguntas" + x_answers: "{{ count }} respostas" + questions: Perguntas + answers: Respostas + newest: Mais recente + active: Ativo + hot: Hot + score: Pontuação + unanswered: Não Respondido + modified: modificado + answered: respondido + asked: perguntado + closed: fechado + follow_a_tag: Seguir o marcador + more: Mais + personal: + overview: Visão geral + answers: Respostas + answer: resposta + questions: Perguntas + question: pergunta + bookmarks: Favoritas + reputation: Reputação + comments: Comentários + Votos: Votos + newest: Mais recente + score: Pontuação + edit_profile: Editar Perfil + visited_x_days: "Visitado {{ count }} dias" + viewed: Visualizado + joined: Ingressou + last_login: Visto + about_me: Sobre mim + about_me_empty: "// Olá, Mundo !" + top_answers: Melhores Respostas + top_questions: Melhores Perguntas + stats: Estatísticas + list_empty: Postagens não encontradas.
        Talvez você queira selecionar uma guia diferente? + accepted: Aceito + answered: respondido + asked: perguntado + upvote: voto positivo + downvote: voto negativo + mod_short: Moderador + mod_long: Moderadores + x_reputation: reputação + x_Votos: votos recebidos + x_answers: respostas + x_questions: perguntas + install: + title: Instalação + next: Próximo + done: Completo + config_yaml_error: Não é possível criar o arquivo config.yaml. + lang: + label: Por favor Escolha um Idioma + db_type: + label: Mecanismo de banco de dados + db_username: + label: Nome de usuário + placeholder: root + msg: Nome de usuário não pode ser vazio. + db_password: + label: Senha + placeholder: root + msg: Senha não pode ser vazio. + db_host: + label: Host do banco de dados + placeholder: "db:3306" + msg: Host de banco de dados não pode ficar vazio. + db_name: + label: Nome do banco de dados + placeholder: answer + msg: O nome do banco de dados não pode ficar vazio. + db_file: + label: Arquivo de banco de dados + placeholder: /data/answer.db + msg: O arquivo de banco de dados não pode ficar vazio. + config_yaml: + title: Criar config.yaml + label: O arquivo config.yaml foi criado. + desc: >- + Você pode criar o arquivo <1>config.yaml manualmente no diretório <1>/var/www/xxx/ e colar o seguinte texto nele. + info: Depois de fazer isso, clique no botão "Avançar". + site_information: Informações do site + admin_account: Administrador Conta + site_name: + label: Site Nome + msg: Site Nome não pode ser vazio. + site_url: + label: Site URL + text: O endereço do seu site. + msg: + empty: Site URL não pode ser vazio. + incorrect: Formato incorreto da URL do site. + contact_email: + label: E-mail para contato + text: Endereço de e-mail do contato principal responsável por este site. + msg: + empty: E-mail para contato não pode ser vazio. + incorrect: E-mail para contato em formato incorreto. + admin_name: + label: Nome + msg: Nome não pode ser vazio. + admin_password: + label: Senha + text: >- + Você precisará dessa senha para efetuar login. Por favor, guarde-a em um local seguro. + msg: Senha não pode ser vazia. + admin_email: + label: Email + text: Você precisará deste e-mail para fazer login. + msg: + empty: Email não pode ser vazio. + incorrect: Formato de e-mail incorreto. + ready_title: Sua resposta está pronta! + ready_desc: >- + Se você quiser alterar mais configurações, visite a <1>seção de administração; encontre-a no menu do site. + good_luck: "Divirta-se e boa sorte!" + warn_title: Aviso + warn_desc: >- + O arquivo <1>config.yaml já existe. Se precisar redefinir algum item de configuração neste arquivo, exclua-o primeiro. + install_now: Você pode tentar <1>instalar agora. + installed: Já instalado + installed_desc: >- + Parece que você já instalou. Para reinstalar, limpe primeiro as tabelas antigas do seu banco de dados. + db_failed: Falha na conexão do banco de dados + db_failed_desc: >- + Isso significa que as informações do banco de dados em um arquivo <1>config.yaml do SUA estão incorretas ou que o contato com o servidor do banco de dados não pôde ser estabelecido. Isso pode significar que o servidor de banco de dados de um host SUA está inativo. + counts: + views: visualizações + Votos: votos + answers: respostas + accepted: Aceito + page_404: + desc: "Infelizmente, esta postagem não existe mais." + back_home: Voltar para a página inicial + page_50X: + desc: O servidor encontrou um erro e não pôde concluir sua solicitação. + back_home: Voltar para a página inicial + page_maintenance: + desc: "Estamos em manutenção, voltaremos em breve." + nav_menus: + dashboard: Painel + contents: Conteúdos + questions: Perguntas + answers: Respostas + users: Usuários + flags: Marcadores + settings: Configurações + general: Geral + interface: Interface + smtp: SMTP + branding: Marca + legal: Legal + write: Escrever + tos: Termos de Serviços + privacy: Privacidade + seo: SEO + customize: Personalização + Temas: Temas + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Administrador + dashboard: + title: Painel + welcome: Bem vindo ao Administrador! + site_statistics: Estatísticas do Site + questions: "Perguntas:" + answers: "Respostas:" + comments: "Comentários:" + Votos: "Votos:" + active_users: "Usuários ativos:" + flags: "Marcadores:" + site_health_status: Estatísticas da saúde do site + version: "Versão:" + https: "HTTPS:" + uploading_files: "Enviando arquivos:" + smtp: "SMTP:" + timezone: "Fuso horário:" + system_info: Informações do Sistema + storage_used: "Armazenamento usado:" + uptime: "Tempo de atividade:" + answer_links: Links das Respostas + documents: Documentos + feedback: Opinião + support: Suporte + review: Revisar + config: Configurações + update_to: Atualizar ao + latest: Ultimo + check_failed: Falha na verificação + "yes": "Sim" + "no": "Não" + not_allowed: Não permitido + allowed: Permitido + enabled: Ativo + disabled: Disponível + flags: + title: Marcadores + pending: Pendente + completed: Completo + flagged: Marcado + created: Criado + action: Ação + review: Revisar + change_modal: + title: Mudar user status to... + btn_cancel: Cancelar + btn_submit: Enviar + normal_name: normal + normal_desc: Um usuário normal pode fazer e responder perguntas. + suspended_name: suspenso + suspended_desc: Um usuário suspenso não pode fazer login. + deleted_name: removido + deleted_desc: "Deletar perfil, associações de autenticação." + inactive_name: inativo + inactive_desc: Um usuário inativo deve revalidar seu e-mail. + confirm_title: Remover este usuário + confirm_content: Tem certeza de que deseja excluir este usuário? Isso é permanente! + confirm_btn: Deletar + msg: + empty: Por favor selecione um motivo. + status_modal: + title: "Mudar {{ type }} status para..." + normal_name: normal + normal_desc: Um post normal disponível para todos. + closed_name: fechado + closed_desc: "Uma pergunta fechada não pode responder, mas ainda pode editar, votar e comentar." + deleted_name: removido + deleted_desc: Toda reputação ganha e perdida será restaurada. + btn_cancel: Cancelar + btn_submit: Enviar + btn_next: Próximo + user_role_modal: + title: Altere a função do usuário para... + btn_cancel: Cancelar + btn_submit: Enviar + users: + title: Usuários + name: Nome + email: Email + reputation: Reputação + created_at: Hora de criação + delete_at: Hora da remoção + suspend_at: Hora da suspensão + status: Status + role: Função + action: Ação + change: Mudar + all: Todos + staff: Funcionários + inactive: Inativo + suspended: Suspenso + deleted: Removido + normal: Normal + Moderador: Moderador + Administrador: Administrador + Usuário: Usuário + filter: + placeholder: "Filtrar por nome, user:id" + set_new_password: Configurar nova senha + change_status: Mudar status + change_role: Mudar função + show_logs: Mostrar registros + add_user: Adicionar usuário + new_password_modal: + title: Configurar nova senha + form: + fields: + password: + label: Senha + text: O usuário será desconectado e precisará fazer login novamente. + msg: Senha de ver entre 8-32 caracteres em comprimento. + btn_cancel: Cancelar + btn_submit: Enviar + user_modal: + title: Adicionar novo usuário + form: + fields: + display_name: + label: Nome de exibição + msg: Nome de exibição deve ser 2-30 caracteres em comprimento. + email: + label: Email + msg: Email não é válido. + password: + label: Senha + msg: Senha deve ser 8-32 caracteres em comprimento. + btn_cancel: Cancelar + btn_submit: Enviar + questions: + page_title: Perguntas + normal: Normal + closed: Fechado + deleted: Removido + post: Publicação + Votos: Votos + answers: Respostas + created: Criado + status: Status + action: Ação + change: Mudar + filter: + placeholder: "Filtrar por título, question:id" + answers: + page_title: Respostas + normal: Normal + deleted: Removido + post: Publicação + Votos: Votos + created: Criado + status: Status + action: Ação + change: Mudar + filter: + placeholder: "Filtrar por título, answer:id" + general: + page_title: General + name: + label: Site Nome + msg: Site name não pode ser vazio. + text: "O nome deste site, conforme usado na tag de título." + site_url: + label: URL do Site + msg: Site url não pode ser vazio. + validate: Por favor digite uma URL válida. + text: O endereço do seu site. + short_desc: + label: Breve Descrição do site (opcional) + msg: Breve Descrição do site não pode ser vazio. + text: "Breve descrição, conforme usado na tag de título na página inicial." + desc: + label: Site Descrição (opcional) + msg: Descrição do site não pode ser vazio. + text: "Descreva este site em uma única sentença, conforme usado na meta tag de descrição." + contact_email: + label: E-mail para contato + msg: E-mail par contato não pode ser vazio. + validate: E-mail par contato não é válido. + text: Endereço de e-mail do principal contato responsável por este site. + interface: + page_title: Interface + logo: + label: Logo (opcional) + msg: Site logo não pode ser vazio. + text: Você pode enviar a sua image ou <1>reiniciar ao texto do título do site. + Tema: + label: Tema + msg: Tema não pode ser vazio. + text: Selecione um tema existente. + language: + label: Idioma da interface + msg: Idioma da Interface não pode ser vazio. + text: Idioma da interface do Usuário. Ele mudará quando você atualizar a página. + time_zone: + label: Fuso horário + msg: Fuso horário não pode ser vazio. + text: Escolha a cidade no mesmo fuso horário que você. + smtp: + page_title: SMTP + from_email: + label: E-mail de origem + msg: E-mail de origem não pode ser vazio. + text: O endereço de e-mail de onde os e-mails são enviados. + from_name: + label: Nome de origem + msg: Nome de origem não pode ser vazio. + text: O nome de onde os e-mails são enviados. + smtp_host: + label: SMTP Host + msg: SMTP host não pode ser vazio. + text: O seu servidor de e-mails. + encryption: + label: Criptografia + msg: Criptografia não pode ser vazio. + text: Para a maioria dos servidores SSL é a opção recomendada. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: A porta para seu servidor de e-mail. + smtp_username: + label: SMTP Nome de usuário + msg: SMTP username não pode ser vazio. + smtp_password: + label: SMTP Senha + msg: SMTP password não pode ser vazio. + test_email_recipient: + label: Destinatários de e-mail de teste + text: Forneça o endereço de e-mail que receberá os envios de testes. + msg: Os destinatários do e-mail de teste são inválidos + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication não pode ser vazio. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (opcional) + msg: Logo não pode ser vazio. + text: A imagem do logotipo no canto superior esquerdo do seu site. Use uma imagem retangular larga com altura de 56 e proporção maior que 3:1. Se deixada em branco, o texto do título do site será exibido. + mobile_logo: + label: Mobile Logo (opcional) + text: O logotipo usado na versão mobile do seu site. Use uma imagem retangular larga com altura de 56. Se deixado em branco, a imagem da configuração "logotipo" será usada. + square_icon: + label: Square Icon (opcional) + msg: Square icon não pode ser vazio. + text: Imagem usada como base para ícones de metadados. Idealmente, deve ser maior que 512x512. + favicon: + label: Favicon (opcional) + text: Um favicon para o seu site. Para funcionar corretamente em uma CDN, ele deve ser um png. Será redimensionado para 32x32. Se deixado em branco, o "ícone quadrado" será usado. + legal: + page_title: Legal + terms_of_service: + label: Termos de Serviço + text: "Você pode adicionar conteúdo dos termos de serviço aqui. Se você já possui um documento hospedado em outro lugar, informe o URL completo aqui." + privacy_policy: + label: Política de Privacidade + text: "Você pode adicionar o conteúdo da política de privacidade aqui. Se você já possui um documento hospedado em outro lugar, informe o URL completo aqui." + write: + page_title: Escrever + recommend_tags: + label: Recomendar Marcadores + text: "Por favor, insira o slug da tag acima, uma tag por linha." + required_tag: + title: Tag necessária + label: Definir tag recomendada como necessária + text: "Cada nova pergunta deve ter pelo menos uma tag de recomendação." + reserved_tags: + label: Marcadores Reservados + text: "Tags reservadas só podem ser adicionadas a uma postagem pelo moderador." + seo: + page_title: SEO + permalink: + label: Permalink + text: Estruturas de URL personalizadas podem melhorar a usabilidade e a compatibilidade futura de seus links. + robots: + label: robots.txt + text: Isso substituirá permanentemente todas as configurações relacionadas do site. + Temas: + page_title: Temas + Temas: + label: Temas + text: Selecione um tema existente. + navbar_style: + label: Estilo da barra de navegação + text: Selecione um tema existente. + primary_color: + label: Cor primária + text: Modifique as cores usadas por seus Temas + css_and_html: + page_title: CSS e HTML + custom_css: + label: Custom CSS + text: Isto será inserido como + head: + label: Head + text: Isto será inserido antes de + header: + label: Header + text: Isto será inserido após + footer: + label: Footer + text: Isso será inserido antes de . + login: + page_title: Login + membership: + title: Associação + label: Permitir novos registros + text: Desative para impedir que alguém crie uma nova conta. + private: + title: Privado + label: Login requirido + text: Somente usuários logados podem acessar esta comunidade. + form: + empty: não pode ser vazio + invalid: é inválido + btn_submit: Salvar + not_found_props: "Propriedade necessária {{ key }} não encontrada." + page_review: + review: Revisar + proposed: proposta + question_edit: Editar Pergunta + answer_edit: Editar Resposta + tag_edit: Editar Tag + edit_summary: Editar resumo + edit_question: Editar pergunta + edit_answer: Editar resposta + edit_tag: Editar tag + empty: Não há mais tarefas de revisão. + timeline: + undeleted: não excluído + deleted: apagado + downvote: voto negativo + upvote: voto positivo + accept: aceitar + cancelled: cancelado + commented: comentado + rollback: rollback + edited: editado + answered: respondido + asked: perguntado + closed: fechado + reopened: reaberto + created: criado + title: "Histórico para" + tag_title: "Linha do tempo para" + show_Votos: "Mostrar votos" + n_or_a: N/A + title_for_question: "Linha do tempo para" + title_for_answer: "Linha do tempo para resposta a {{ title }} por {{ author }}" + title_for_tag: "Linha do tempo para tag" + datetime: Datetime + type: Tipo + by: Por + comment: Comentário + no_data: "Não conseguimos encontrar nada." + users: + title: Usuários + users_with_the_most_reputation: Usuários com as maiores pontuações de reputação + users_with_the_most_vote: Usuários que mais votaram + staffs: Nossa equipe comunitária + reputation: reputação + Votos: Votos diff --git a/data/i18n/pt_PT.yaml b/data/i18n/pt_PT.yaml new file mode 100644 index 000000000..eba40d2f6 --- /dev/null +++ b/data/i18n/pt_PT.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Sucesso. + unknown: + other: Erro desconhecido. + request_format_error: + other: Formato de solicitação inválido. + unauthorized_error: + other: Não autorizado. + database_error: + other: Erro no servidor de dados. + forbidden_error: + other: Proibido. + duplicate_request_error: + other: Solicitação duplicada. + action: + report: + other: Bandeira + edit: + other: Editar + delete: + other: Excluir + close: + other: Fechar + reopen: + other: Reabrir + forbidden_error: + other: Proibido. + pin: + other: Fixar + hide: + other: Não listar + unpin: + other: Desafixar + show: + other: Lista + invite_someone_to_answer: + other: Editar + undelete: + other: Desfazer + merge: + other: Merge + role: + name: + user: + other: Usuário + admin: + other: Administrador + moderator: + other: Moderador + description: + user: + other: Padrão sem acesso especial. + admin: + other: Possui acesso total. + moderator: + other: Acesso a todas as postagens, exceto configurações administrativas. + privilege: + level_1: + description: + other: Nível 1 (Menos reputação necessária para a equipe privado, grupo) + level_2: + description: + other: Nível 2 (pouca reputação necessária para a comunidade de inicialização) + level_3: + description: + other: Nível 3 (Alta reputação necessária para a comunidade adulta) + level_custom: + description: + other: Nível customizado + rank_question_add_label: + other: Perguntar + rank_answer_add_label: + other: Escrever resposta + rank_comment_add_label: + other: Comentar + rank_report_add_label: + other: Bandeira + rank_comment_vote_up_label: + other: Aprovar um comentário + rank_link_url_limit_label: + other: Poste mais de 2 links por vez + rank_question_vote_up_label: + other: Avaliar perguntar + rank_answer_vote_up_label: + other: Votar na resposta + rank_question_vote_down_label: + other: Desaprovar pergunta + rank_answer_vote_down_label: + other: Desaprovar resposta + rank_invite_someone_to_answer_label: + other: Convide alguém para responder + rank_tag_add_label: + other: Criar marcador + rank_tag_edit_label: + other: Editar descrição de um marcador (revisão necessária) + rank_question_edit_label: + other: Editar pergunta do outro (revisão necessária) + rank_answer_edit_label: + other: Editar a resposta do outro (revisão necessária) + rank_question_edit_without_review_label: + other: Editar a pergunta do outro sem revisar + rank_answer_edit_without_review_label: + other: Editar a resposta do outro sem revisar + rank_question_audit_label: + other: Rever edições de perguntas + rank_answer_audit_label: + other: Revisar edições de respostas + rank_tag_audit_label: + other: Revisar edições de marcadores + rank_tag_edit_without_review_label: + other: Editar descrições de marcadores sem revisar + rank_tag_synonym_label: + other: Gerenciar sinônimos de marcação + email: + other: E-mail + e_mail: + other: Email + password: + other: Senha + pass: + other: Senha + old_pass: + other: Current password + original_text: + other: Esta publicação + email_or_password_wrong_error: + other: O e-mail e a palavra-passe não coincidem. + error: + common: + invalid_url: + other: URL inválida. + status_invalid: + other: Estado inválido. + password: + space_invalid: + other: A senha não pode conter espaços. + admin: + cannot_update_their_password: + other: Você não pode modificar sua senha. + cannot_edit_their_profile: + other: Você não pode alterar o seu perfil. + cannot_modify_self_status: + other: Você não pode modificar seu status + email_or_password_wrong: + other: O e-mail e a palavra-passe não coincidem. + answer: + not_found: + other: Resposta não encontrada. + cannot_deleted: + other: Sem permissão para remover. + cannot_update: + other: Sem permissão para atualizar. + question_closed_cannot_add: + other: Perguntas são fechadas e não podem ser adicionadas. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Não é possível alterar comentários. + not_found: + other: Comentário não encontrado. + cannot_edit_after_deadline: + other: O tempo do comentário foi muito longo para ser modificado. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: O e-mail já existe. + need_to_be_verified: + other: O e-mail deve ser verificado. + verify_url_expired: + other: O e-mail verificado URL expirou, por favor, reenvie o e-mail. + illegal_email_domain_error: + other: O email não é permitido a partir desse email de domínio. Por favor, use outro. + lang: + not_found: + other: Arquivo de idioma não encontrado. + object: + captcha_verification_failed: + other: O Captcha está incorreto. + disallow_follow: + other: Você não tem permissão para seguir. + disallow_vote: + other: Você não possui permissão para votar. + disallow_vote_your_self: + other: Você não pode votar na sua própria postagem. + not_found: + other: Objeto não encontrado. + verification_failed: + other: A verificação falhou. + email_or_password_incorrect: + other: O e-mail e a senha não correspondem. + old_password_verification_failed: + other: Falha na verificação de senha antiga + new_password_same_as_previous_setting: + other: A nova senha é a mesma que a anterior. + already_deleted: + other: Esta publicação foi removida. + meta: + object_not_found: + other: Objeto meta não encontrado + question: + already_deleted: + other: Essa publicação foi deletado. + under_review: + other: Sua postagem está aguardando revisão. Ela ficará visível depois que for aprovada. + not_found: + other: Pergunta não encontrada. + cannot_deleted: + other: Sem permissão para remover. + cannot_close: + other: Sem permissão para fechar. + cannot_update: + other: Sem permissão para atualizar. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: A classificação não atende à condição. + vote_fail_to_meet_the_condition: + other: Obrigado pela sugestão. Você precisa ser {{.Rank}} para poder votar. + no_enough_rank_to_operate: + other: Você precisa ser pelo menos {{.Rank}} para fazer isso. + report: + handle_failed: + other: Falha ao manusear relatório. + not_found: + other: Relatório não encontrado. + tag: + already_exist: + other: Marcação já existe. + not_found: + other: Marca não encontrada. + recommend_tag_not_found: + other: Marcador recomendado não existe. + recommend_tag_enter: + other: Por favor, insira pelo menos um marcador obrigatório. + not_contain_synonym_tags: + other: Não deve conter marcadores sinónimos. + cannot_update: + other: Sem permissão para atualizar. + is_used_cannot_delete: + other: Não é possível excluir um marcador em uso. + cannot_set_synonym_as_itself: + other: Você não pode definir o sinônimo do marcador atual como a si mesmo. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: O De Nome não pode ser um endereço de e-mail. + theme: + not_found: + other: Tema não encontrado. + revision: + review_underway: + other: Não é possível editar atualmente, há uma versão na fila de análise. + no_permission: + other: Sem pemissão para revisar. + user: + external_login_missing_user_id: + other: A plataforma de terceiros não fornece um ID único de usuário, então você não pode fazer login, entre em contato com o administrador do site. + external_login_unbinding_forbidden: + other: Por favor, defina uma senha de login para sua conta antes de remover esta conta. + email_or_password_wrong: + other: + other: O e-mail e a senha não conferem. + not_found: + other: Usuário não encontrado. + suspended: + other: O utilizador foi suspenso. + username_invalid: + other: Nome de usuário inválido. + username_duplicate: + other: O nome de usuário já em uso. + set_avatar: + other: Configuração de avatar falhou. + cannot_update_your_role: + other: Você não pode modificar a sua função. + not_allowed_registration: + other: Atualmente o site não está aberto para cadastro + not_allowed_login_via_password: + other: Atualmente o site não tem permissão para acessar utilizando senha. + access_denied: + other: Acesso negado + page_access_denied: + other: Você não tem permissão de acesso para esta página. + add_bulk_users_format_error: + other: "Erro no formato {{.Field}} próximo '{{.Content}}' na linha {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "O número de usuários que você adicionou de uma vez deve estar no intervalo de 1 -{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Falha ao ler configuração + database: + connection_failed: + other: Falha ao conectar-se ao banco de dados + create_table_failed: + other: Falha ao criar tabela + install: + create_config_failed: + other: Não foi possível criar o arquivo de configuração. + upload: + unsupported_file_format: + other: Formato de arquivo não suportado. + site_info: + config_not_found: + other: Configuração do site não encontrada. + badge: + object_not_found: + other: Objeto emblema não encontrado + reason: + spam: + name: + other: spam + desc: + other: Essa postagem é um anúncio, ou vandalismo. Não é útil ou relevante para o tópico atual. + rude_or_abusive: + name: + other: rude ou abusivo + desc: + other: "Uma pessoa razoável consideraria esse conteúdo inapropriado para um discurso respeitoso." + a_duplicate: + name: + other: uma duplicação + desc: + other: Esta pergunta já foi feita antes e já possui uma resposta. + placeholder: + other: Insira o link existente para a pergunta + not_a_answer: + name: + other: não é uma resposta + desc: + other: "Foi apresentada como uma resposta, mas não tenta responder à pergunta. Talvez deva ser uma edição, um comentário, outra pergunta ou totalmente apagada." + no_longer_needed: + name: + other: não é mais necessário + desc: + other: Este comentário está desatualizado, conversacional ou não é relevante para esta publicação. + something: + name: + other: outro assunto + desc: + other: Esta postagem requer atenção da equipe por outra razão não listada acima. + placeholder: + other: Conte-nos especificamente com o que você está preocupado + community_specific: + name: + other: um motivo específico para a comunidade + desc: + other: Esta questão não atende a uma orientação da comunidade. + not_clarity: + name: + other: precisa de detalhes ou clareza + desc: + other: Atualmente esta pergunta inclui várias perguntas em um só. Deve se concentrar apenas em um problema. + looks_ok: + name: + other: parece estar OK + desc: + other: Este post é bom como está e não de baixa qualidade. + needs_edit: + name: + other: necessitava de edição, assim o fiz + desc: + other: Melhore e corrija problemas com este post você mesmo. + needs_close: + name: + other: precisa ser fechado + desc: + other: Uma pergunta fechada não pode responder, mas ainda pode editar, votar e comentar. + needs_delete: + name: + other: precisa ser excluído + desc: + other: Esta postagem será excluída. + question: + close: + duplicate: + name: + other: spam + desc: + other: Esta pergunta já foi feita antes e já tem uma resposta. + guideline: + name: + other: um motivo específico da comunidade + desc: + other: Esta pergunta não atende a uma diretriz da comunidade. + multiple: + name: + other: precisa de detalhes ou clareza + desc: + other: Esta pergunta atualmente inclui várias perguntas em uma só. Por isso, deve focar em apenas um problema. + other: + name: + other: algo mais + desc: + other: Este post requer outro motivo não listado acima. + operation_type: + asked: + other: perguntado + answered: + other: respondido + modified: + other: modificado + deleted_title: + other: Questão excluída + questions_title: + other: Questões + tag: + tags_title: + other: Marcadores + no_description: + other: O marcador não possui descrição. + notification: + action: + update_question: + other: pergunta atualizada + answer_the_question: + other: pergunta respondida + update_answer: + other: resposta atualizada + accept_answer: + other: resposta aceita + comment_question: + other: pergunta comentada + comment_answer: + other: resposta comentada + reply_to_you: + other: respondeu a você + mention_you: + other: mencionou você + your_question_is_closed: + other: A sua pergunta foi fechada + your_question_was_deleted: + other: A sua pergunta foi deletada + your_answer_was_deleted: + other: A sua resposta foi deletada + your_comment_was_deleted: + other: O seu comentário foi deletado + up_voted_question: + other: votos positivos da pergunta + down_voted_question: + other: votos negativos da pergunta + up_voted_answer: + other: votos positivos da resposta + down_voted_answer: + other: votos negativos da resposta + up_voted_comment: + other: votos positivos do comentário + invited_you_to_answer: + other: lhe convidou para responder + earned_badge: + other: Ganhou o emblema "{{.BadgeName}}" emblema + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Confirme seu novo endereço de e-mail" + body: + other: "Confirme seu novo endereço de e-mail para {{.SiteName}} clicando no seguinte link:
        \n{{.ChangeEmailUrl}}

        \n\nSe você não solicitou esta alteração, por favor, ignore este email.

        \n\n--
        \nNota: Este é um e-mail automático do sistema, por favor, não responda a esta mensagem, pois a sua resposta não será vista." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} respondeu à sua pergunta" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nVisualizar no {{.SiteName}}

        \n\n--
        \nNota: Este é um e-mail de sistema automático, por favor, não responda a esta mensagem, pois a sua resposta não será vista.

        \n\nCancelar inscrição" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} convidou-lhe para responder" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        acho que você pode saber a resposta.

        \nVisualizar na {{.SiteName}}

        \n\n--
        \nNota: Este é um e-mail de sistema automático, por favor, não responda a esta mensagem, pois a sua resposta não será vista.

        \n\nCancelar Inscrição" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} comentou em sua publicação" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nVisualizar no {{.SiteName}}

        \n\n--
        \nNota: Este é um e-mail de sistema automático, por favor, não responda a esta mensagem, pois a sua resposta não será vista.

        \n\nCancelar inscrição" + new_question: + title: + other: "[{{.SiteName}}] Nova pergunta: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Redefinição de senha" + body: + other: "Alguém pediu para redefinir a sua senha em {{.SiteName}}.

        \n\nSe não foi você, você pode ignorar este e-mail.

        \n\nClique no seguinte link para escolher uma nova senha:
        \n{{.PassResetUrl}}

        \n\n--
        \nNota: Este é um e-mail de sistema automático, por favor, não responda a esta mensagem, pois a sua resposta não será vista." + register: + title: + other: "[{{.SiteName}}] Confirme seu novo endereço de e-mail" + body: + other: "Bem-vindo a {{.SiteName}}!

        \n\nClique no seguinte link para confirmar e ativar sua nova conta:
        \n{{.RegisterUrl}}

        \n\nSe o link acima não for clicável, tente copiá-lo e colá-lo na barra de endereços do seu navegador web.\n

        \n\n--
        \nNota: Este é um e-mail de sistema automático. por favor, não responda a esta mensagem, pois a sua resposta não será vista." + test: + title: + other: "[{{.SiteName}}] E-mail de teste" + body: + other: "Este é um e-mail de teste.\n

        \n\n--
        \nNota: Este é um e-mail automático do sistema, por favor, não responda a esta mensagem, pois a sua resposta não será vista." + action_activity_type: + upvote: + other: voto positivo + upvoted: + other: votos positivos + downvote: + other: voto negativo + downvoted: + other: voto negativo + accept: + other: aceito + accepted: + other: aceito + edit: + other: editar + review: + queued_post: + other: Publicação na fila + flagged_post: + other: Postagem sinalizada + suggested_post_edit: + other: Edições sugeridas + reaction: + tooltip: + other: "{{ .Names }} e mais {{ .Count }}..." + badge: + default_badges: + autobiographer: + name: + other: Autobiógrafo + desc: + other: Preenchido com perfil . + certified: + name: + other: Certificado + desc: + other: Completou o nosso tutorial de novo usuário. + editor: + name: + other: Editor + desc: + other: Primeira edição em publicação. + first_flag: + name: + other: Primeira Sinalização + desc: + other: Primeiro sinalização numa publicação. + first_upvote: + name: + other: Primeiro voto + desc: + other: Primeiro post votado. + first_link: + name: + other: Primeiro link + desc: + other: First added a link to another post. + first_reaction: + name: + other: Primeira Reação + desc: + other: Primeira reação a um post. + first_share: + name: + other: Primeiro Compartilhamento + desc: + other: Primeiro a compartilhar um post. + scholar: + name: + other: Académico + desc: + other: Fez uma pergunta e aceitou uma resposta. + commentator: + name: + other: Comentador + desc: + other: Fez 5 comentários. + new_user_of_the_month: + name: + other: Novo usuário do mês + desc: + other: Contribuições pendentes no seu primeiro mês. + read_guidelines: + name: + other: Ler diretrizes + desc: + other: Leia as [diretrizes da comunidade]. + reader: + name: + other: Leitor + desc: + other: Leia todas as respostas num tópico com mais de 10 respostas. + welcome: + name: + other: Bem-vindo + desc: + other: Recebeu um voto positivo. + nice_share: + name: + other: Bom compartilhador + desc: + other: Compartilhou um post com 25 visitantes únicos. + good_share: + name: + other: Bom compartilhador + desc: + other: Compartilhou um post com 300 visitantes únicos. + great_share: + name: + other: Grande Compartilhador + desc: + other: Compartilhou um post com 1000 visitantes únicos. + out_of_love: + name: + other: Por amor + desc: + other: Cinquenta votos positivos em um dia. + higher_love: + name: + other: Amor Superior + desc: + other: Usou 50 votos positivos em um dia — 5 vezes. + crazy_in_love: + name: + other: Amor Louco + desc: + other: Usou 50 votos positivos em um dia — 20 vezes. + promoter: + name: + other: Promotor + desc: + other: Convidou um usuário. + campaigner: + name: + other: Ativista + desc: + other: Foram convidados 3 usuários básicos. + champion: + name: + other: Campeão + desc: + other: Cinco membros convidados. + thank_you: + name: + other: Obrigado + desc: + other: Recebeu 20 votos positivos e deu 10 votos. + gives_back: + name: + other: Dar de volta + desc: + other: Recebeu100 votos positivos e deu 100 votos a favor. + empathetic: + name: + other: Empático + desc: + other: Recebeu 500 votos e deu 1000 votos. + enthusiast: + name: + other: Entusiasta + desc: + other: . + aficionado: + name: + other: Aficionado + desc: + other: Visitou 100 dias consecutivos. + devotee: + name: + other: Devoto + desc: + other: Visitou 365 dias consecutivos. + anniversary: + name: + other: Aniversário + desc: + other: Membro ativo por um ano, postando pelo menos uma vez. + appreciated: + name: + other: Apreciado + desc: + other: Recebeu 1 voto positivo em 20 posts. + respected: + name: + other: Respeitado + desc: + other: Novos 2 votos em 100 posts. + admired: + name: + other: Admirado + desc: + other: Recebeu 5 votos positivos em 300 posts. + solved: + name: + other: Resolvido + desc: + other: Ter uma resposta aceita. + guidance_counsellor: + name: + other: Orientador Educacional + desc: + other: Tenham 10 respostas aceitas. + know_it_all: + name: + other: Sabichão + desc: + other: Tenha 50 respostas aceitas. + solution_institution: + name: + other: Instituição de Soluções + desc: + other: Tenham 150 respostas aceitas. + nice_answer: + name: + other: Resposta legal + desc: + other: Resposta com pontuação maior que 10. + good_answer: + name: + other: Boa resposta + desc: + other: Resposta com pontuação maior que 25. + great_answer: + name: + other: Ótima Resposta + desc: + other: Resposta com pontuação maior que 50. + nice_question: + name: + other: Questão legal + desc: + other: Pergunta com pontuação maior que 10. + good_question: + name: + other: Boa questão + desc: + other: Questão com pontuação maior que 25. + great_question: + name: + other: Otima questão + desc: + other: Questão com pontuação maior que 50. + popular_question: + name: + other: Pergunta Popular + desc: + other: Pergunta com 500 visualizações. + notable_question: + name: + other: Pergunta Notável + desc: + other: Pergunta com 1000 visualizações. + famous_question: + name: + other: Pergunta Famosa + desc: + other: Pergunta com 5000 visualizações. + popular_link: + name: + other: Link Popular + desc: + other: Postou um link externo com 50 cliques. + hot_link: + name: + other: Link Quente + desc: + other: Postou um link externo com 300 cliques. + famous_link: + name: + other: Link Famoso + desc: + other: Postou um link externo com 100 cliques. + default_badge_groups: + getting_started: + name: + other: Começando + community: + name: + other: Comunidade + posting: + name: + other: Postando +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Como formatar + desc: >- +
        • mencionar uma postagem: #post_id

        • para mais links

          <https://url.com>

          [Título](https://url.com)
        • colocar retornos entre parágrafos

        • _italic_ ou **bold**

        • identar código por 4 espaços

        • cotação colocando > no início da linha

        • aspas invertidas `tipo_isso`

        • criar cercas de código com aspas invertidas `

          ```
          código aqui
          ```
        + pagination: + prev: Anterior + next: Próximo + page_title: + question: Pergunta + questions: Perguntas + tag: Marcador + tags: Marcadores + tag_wiki: marcador wiki + create_tag: Criar Marcador + edit_tag: Editar Marcador + ask_a_question: Create Question + edit_question: Editar Pergunta + edit_answer: Editar Resposta + search: Busca + posts_containing: Postagens contendo + settings: Configurações + notifications: Notificações + login: Entrar + sign_up: Registar-se + account_recovery: Recuperação de conta + account_activation: Ativação de conta + confirm_email: Confirmar E-mail + account_suspended: Conta suspensa + admin: Administrador + change_email: Modificar e-mail + install: Instalação do Answer + upgrade: Atualização do Answer + maintenance: Manutenção do website + users: Usuários + oauth_callback: Processando + http_404: HTTP Erro 404 + http_50X: HTTP Erro 500 + http_403: HTTP Erro 403 + logout: Encerrar Sessão + posts: Posts + notifications: + title: Notificações + inbox: Caixa de entrada + achievement: Conquistas + new_alerts: Novos alertas + all_read: Marcar todos como lida + show_more: Mostrar mais + someone: Alguém + inbox_type: + all: Tudo + posts: Postagens + invites: Convites + votes: Votos + answer: Resposta + question: Questão + badge_award: Emblema + suspended: + title: A sua conta foi suspensa + until_time: "Sua conta está suspensa até {{ time }}." + forever: Este usuário foi suspenso permanentemente. + end: Você não atende a uma diretriz da comunidade. + contact_us: Entre em contato conosco + editor: + blockquote: + text: Bloco de citação + bold: + text: Negrito + chart: + text: Gráfico + flow_chart: Gráfico de fluxo + sequence_diagram: Diagrama de sequência + class_diagram: Diagrama de classe + state_diagram: Diagrama de estado + entity_relationship_diagram: Diagrama de relacionamento de entidade + user_defined_diagram: Diagrama definido pelo usuário + gantt_chart: Gráfico de Gantt + pie_chart: Gráfico de pizza + code: + text: Exemplo de código + add_code: Adicionar exemplo de código + form: + fields: + code: + label: Código + msg: + empty: Código não pode ser vazio. + language: + label: Idioma + placeholder: Deteção automática + btn_cancel: Cancelar + btn_confirm: Adicionar + formula: + text: Fórmula + options: + inline: Fórmula na linha + block: Bloco de fórmula + heading: + text: Cabeçalho + options: + h1: Cabeçalho 1 + h2: Cabeçalho 2 + h3: Cabeçalho 3 + h4: Cabeçalho 4 + h5: Cabeçalho 5 + h6: Cabeçalho 6 + help: + text: Ajuda + hr: + text: Régua horizontal + image: + text: Imagem + add_image: Adicionar imagem + tab_image: Enviar image, + form_image: + fields: + file: + label: Arquivo de imagem + btn: Selecione imagem + msg: + empty: Arquivo não pode ser vazio. + only_image: Somente um arquivo de imagem é permitido. + max_size: O tamanho do arquivo não pode exceder {{size}} MB. + desc: + label: Descrição (opcional) + tab_url: URL da imagem + form_url: + fields: + url: + label: URL da imagem + msg: + empty: URL da imagem não pode ser vazia. + name: + label: Descrição (opcional) + btn_cancel: Cancelar + btn_confirm: Adicionar + uploading: Enviando + indent: + text: Identação + outdent: + text: Não identado + italic: + text: Emphase + link: + text: Superlink (Hyperlink) + add_link: Adicionar superlink (hyperlink) + form: + fields: + url: + label: URL + msg: + empty: URL não pode ser vazia. + name: + label: Descrição (opcional) + btn_cancel: Cancelar + btn_confirm: Adicionar + ordered_list: + text: Lista numerada + unordered_list: + text: Lista com marcadores + table: + text: Tabela + heading: heading + cell: Célula + file: + text: Anexar arquivos + not_supported: "Não suporta esse tipo de arquivo. Tente novamente com {{file_type}}." + max_size: "Anexar arquivos não pode exceder {{size}} MB." + close_modal: + title: Estou fechando este post como... + btn_cancel: Cancelar + btn_submit: Enviar + remark: + empty: Não pode ser vazio. + msg: + empty: Por favor selecione um motivo. + report_modal: + flag_title: Estou marcando para denunciar este post como... + close_title: Estou fechando este post como... + review_question_title: Revisar pergunta + review_answer_title: Revisar resposta + review_comment_title: Revisar comentário + btn_cancel: Cancelar + btn_submit: Enviar + remark: + empty: Não pode ser vazio. + msg: + empty: Por favor selecione um motivo. + not_a_url: Formato da URL incorreto. + url_not_match: A origem da URL não corresponde ao site atual. + tag_modal: + title: Criar novo marcador + form: + fields: + display_name: + label: Nome de exibição + msg: + empty: Nome de exibição não pode ser vazio. + range: Nome de exibição tem que ter até 35 caracteres. + slug_name: + label: Slug de URL + desc: 'Deve usar o conjunto de caracteres "a-z", "0-9", "+ # - ."' + msg: + empty: URL slug não pode ser vazio. + range: URL slug até 35 caracteres. + character: URL slug contém conjunto de caracteres não permitido. + desc: + label: Descrição (opcional) + revision: + label: Revisão + edit_summary: + label: Editar descrição + placeholder: >- + Explique resumidamente as suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada) + btn_cancel: Cancelar + btn_submit: Enviar + btn_post: Postar novo marcador + tag_info: + created_at: Criado + edited_at: Editado + history: Histórico + synonyms: + title: Sinônimos + text: Os marcadores a seguir serão re-mapeados para + empty: Sinônimos não encotrados. + btn_add: Adicionar um sinônimo + btn_edit: Editar + btn_save: Salvar + synonyms_text: Os marcadores a seguir serão re-mapeados para + delete: + title: Remover este marcador + tip_with_posts: >- +

        Nós não permitimos remover marcadores com postagens.

        Por favor, remova este marcador a partir da postagem.

        + tip_with_synonyms: >- +

        Nós não permitimos remover marcadores com postagens.

        Por favor, remova este marcador a partir da postagem.

        + tip: Você tem certeza que deseja remover? + close: Fechar + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Editar marcador + default_reason: Editar marcador + default_first_reason: Adicionar marcador + btn_save_edits: Salvar edições + btn_cancel: Cancelar + dates: + long_date: D MMM + long_date_with_year: "D MMM, YYYY" + long_date_with_time: "D MMM, YYYY [at] HH:mm" + now: agora + x_seconds_ago: "{{count}}s atrás" + x_minutes_ago: "{{count}}m atrás" + x_hours_ago: "{{count}}h atrás" + hour: hora + day: dia + hours: horas + days: dias + month: month + months: months + year: year + reaction: + heart: coração + smile: sorrir + frown: cara feia + btn_label: adicionar ou remover reações + undo_emoji: desfazer reação {{ emoji }} + react_emoji: reagir com {{ emoji }} + unreact_emoji: remover reação {{ emoji }} + comment: + btn_add_comment: Adicionar comentário + reply_to: Responder a + btn_reply: Responder + btn_edit: Editar + btn_delete: Excluir + btn_flag: Marcador + btn_save_edits: Salvar edições + btn_cancel: Cancelar + show_more: "Mais {{count}} comentários" + tip_question: >- + Use os comentários para pedir mais informações ou sugerir melhorias. Evite responder perguntas nos comentários. + tip_answer: >- + Use comentários para responder a outros usuários ou notificá-los sobre alterações. Se você estiver adicionando novas informações, edite sua postagem em vez de comentar. + tip_vote: Isto adiciona alguma utilidade à postagem + edit_answer: + title: Editar Resposta + default_reason: Editar Resposta + default_first_reason: Adicionar resposta + form: + fields: + revision: + label: Revisão + answer: + label: Resposta + feedback: + characters: conteúdo deve ser pelo menos 6 characters em comprimento. + edit_summary: + label: Resumo da edição + placeholder: >- + Explique resumidamente suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada) + btn_save_edits: Salvar edições + btn_cancel: Cancelar + tags: + title: Marcadores + sort_buttons: + popular: Popular + name: Nome + newest: mais recente + button_follow: Seguir + button_following: Seguindo + tag_label: perguntas + search_placeholder: Filtrar por nome de marcador + no_desc: O marcador não possui descrição. + more: Mais + wiki: Wiki + ask: + title: Create Question + edit_title: Editar Pergunta + default_reason: Editar pergunta + default_first_reason: Create question + similar_questions: Similar perguntas + form: + fields: + revision: + label: Revisão + title: + label: Título + placeholder: What's your topic? Be specific. + msg: + empty: Título não pode ser vazio. + range: Título até 150 caracteres + body: + label: Corpo + msg: + empty: Corpo da mensagem não pode ser vazio. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Marcadores + msg: + empty: Marcadores não podes ser vazios. + answer: + label: Resposta + msg: + empty: Resposta não pode ser vazia. + edit_summary: + label: Resumo da edição + placeholder: >- + Explique resumidamente suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada) + btn_post_question: Publicação a sua pergunta + btn_save_edits: Salvar edições + answer_question: Responda a sua própria pergunta + post_question&answer: Publicação a sua pergunta e resposta + tag_selector: + add_btn: Adicionar marcador + create_btn: Criar novo marcador + search_tag: Procurar marcador + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: Nenhum marcador correspondente + tag_required_text: Marcador obrigatório (ao menos um) + header: + nav: + question: Perguntas + tag: Marcadores + user: Usuários + badges: Emblemas + profile: Perfil + setting: Configurações + logout: Sair + admin: Administrador + review: Revisar + bookmark: Favoritos + moderation: Moderação + search: + placeholder: Procurar + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Mudar + loading: carregando... + pic_auth_code: + title: Captcha + placeholder: Escreva o texto acima + msg: + empty: Captcha não pode ser vazio. + inactive: + first: >- + Você está quase pronto! Enviamos um e-mail de ativação para {{mail}}. Por favor, siga as instruções no e-mail para ativar uma conta sua. + info: "Se não chegar, verifique sua pasta de spam." + another: >- + Enviamos outro e-mail de ativação para você em {{mail}}. Pode levar alguns minutos para chegar; certifique-se de verificar sua pasta de spam. + btn_name: Reenviar e-mail de ativação + change_btn_name: Mudar email + msg: + empty: Não pode ser vazio. + resend_email: + url_label: Tem certeza de que deseja reenviar o e-mail de ativação? + url_text: Você também pode fornecer o link de ativação acima para o usuário. + login: + login_to_continue: Entre para continue + info_sign: Não possui uma conta? <1>Cadastrar-se + info_login: Já possui uma conta? <1>Entre + agreements: Ao se registrar, você concorda com as <1>políticas de privacidades e os <3>termos de serviços. + forgot_pass: Esqueceu a sua senha? + name: + label: Nome + msg: + empty: Nome não pode ser vazio. + range: O nome deve ter entre 2 e 30 caracteres. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: E-mail + msg: + empty: E-mail não pode ser vazio. + password: + label: Senha + msg: + empty: Senha não pode ser vazia. + different: As senhas inseridas em ambos os campos são inconsistentes + account_forgot: + page_title: Esqueceu a sua senha + btn_name: Enviar e-mail de recuperação de senha + send_success: >- + Se uma conta corresponder {{mail}}, você deve receber um e-mail com instruções sobre como redefinir sua senha em breve. + email: + label: E-mail + msg: + empty: E-mail não pode ser vazio. + change_email: + btn_cancel: Cancelar + btn_update: Atualiza email address + send_success: >- + Se uma conta corresponder {{mail}}, você deve receber um e-mail com instruções sobre como redefinir sua senha em breve. + email: + label: Novo E-mail + msg: + empty: E-mail não pode ser vazio. + oauth: + connect: Conecte com {{ auth_name }} + remove: Remover {{ auth_name }} + oauth_bind_email: + subtitle: Adicione um e-mail para recuperação da conta. + btn_update: Atualizar endereço de e-mail + email: + label: E-mail + msg: + empty: E-mail não pode ser vazio. + modal_title: E-mail já existe. + modal_content: Este e-mail já está cadastrado. Você tem certeza que deseja conectar à conta existente? + modal_cancel: Alterar E-mail + modal_confirm: Conectar a uma conta existente + password_reset: + page_title: Redefinir senha + btn_name: Redefinir minha senha + reset_success: >- + Você alterou com sucesso uma senha sua; você será redirecionado para a página de login. + link_invalid: >- + Desculpe, este link de redefinição de senha não é mais válido. Talvez uma senha sua já tenha sido redefinida? + to_login: Continuar para a tela de login + password: + label: Senha + msg: + empty: Senha não pode ser vazio. + length: O comprimento deve estar entre 8 e 32 + different: As senhas inseridas em ambos os campos são inconsistentes + password_confirm: + label: Confirmar Nova senha + settings: + page_title: Configurações + goto_modify: Ir para modificar + nav: + profile: Perfil + notification: Notificações + account: Conta + interface: Interface + profile: + heading: Perfil + btn_name: Salvar + display_name: + label: Nome de exibição + msg: Nome de exibição não pode ser vazio. + msg_range: Display name must be 2-30 characters in length. + username: + label: Nome de usuário + caption: As pessoas poderão mensionar você com "@usuário". + msg: Nome de usuário não pode ser vazio. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Perfil Imagem + gravatar: Gravatar + gravatar_text: Você pode mudar a imagem em <1>gravatar.com + custom: Customizado + custom_text: Você pode enviar a sua image. + default: Padrão do Sistema + msg: Por favor envie um avatar + bio: + label: Sobre mim (opcional) + website: + label: Website (opcional) + placeholder: "https://exemplo.com.br" + msg: Formato incorreto de endereço de Website + location: + label: Localização (opcional) + placeholder: "Cidade, País" + notification: + heading: Notificações por e-mail + turn_on: Ativar + inbox: + label: Notificações na caixa de entrada + description: Responda suas próprias perguntas, comentários, convites e muito mais. + all_new_question: + label: Todas as perguntas novas + description: Seja notificado de todas as novas perguntas. Até 50 perguntas por semana. + all_new_question_for_following_tags: + label: Novas perguntas para os seguintes marcadores + description: Seja notificado de novas perguntas para os seguintes marcadores. + account: + heading: Conta + change_email_btn: Mudar e-mail + change_pass_btn: Mudar senha + change_email_info: >- + Enviamos um e-mail para esse endereço. Siga as instruções de confirmação. + email: + label: Correio eletrónico + new_email: + label: Novo correio eletrónico + msg: Novo correio eletrónico não pode ser vazio. + pass: + label: Senha atual + msg: Senha não pode ser vazio. + password_title: Senha + current_pass: + label: Senha atual + msg: + empty: A Senha não pode ser vazia. + length: O comprimento deve estar entre 8 and 32. + different: As duas senhas inseridas não correspondem. + new_pass: + label: Nova Senha + pass_confirm: + label: Confirmar nova Senha + interface: + heading: Interface + lang: + label: Idioma da Interface + text: Idioma da interface do usuário. A interface mudará quando você atualizar a página. + my_logins: + title: Meus logins + label: Entre ou cadastre-se neste site utilizando estas contas. + modal_title: Remover login + modal_content: Você tem certeza que deseja remover este login da sua conta? + modal_confirm_btn: Remover + remove_success: Removido com sucesso + toast: + update: atualização realizada com sucesso + update_password: Senha alterada com sucesso. + flag_success: Obrigado por marcar. + forbidden_operate_self: Proibido para operar por você mesmo + review: A sua resposta irá aparecer após a revisão. + sent_success: Enviado com sucesso + related_question: + title: Related + answers: respostas + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Pessoas Perguntaram + desc: Select people who you think might know the answer. + invite: Convidar para responder + add: Adicionar pessoas + search: Procurar pessoas + question_detail: + action: Acção + created: Created + Asked: Perguntado + asked: perguntado + update: Modificado + Edited: Edited + edit: modificado + commented: comentado + Views: Visualizado + Follow: Seguir + Following: Seguindo + follow_tip: Siga esta pergunta para receber notificações + answered: respondido + closed_in: Fechado em + show_exist: Mostrar pergunta existente. + useful: Útil + question_useful: Isso é útil e claro + question_un_useful: Isso não está claro ou não é útil + question_bookmark: Favoritar esta pergunta + answer_useful: Isso é útil + answer_un_useful: Isso não é útil + answers: + title: Respostas + score: Pontuação + newest: Mais recente + oldest: Mais Antigos + btn_accept: Aceito + btn_accepted: Aceito + write_answer: + title: A sua Resposta + edit_answer: Editar a minha resposta existente + btn_name: Publicação a sua resposta + add_another_answer: Adicionar outra resposta + confirm_title: Continuar a responder + continue: Continuar + confirm_info: >- +

        Tem certeza de que deseja adicionar outra resposta?

        Você pode usar o link de edição para refinar e melhorar uma resposta existente.

        + empty: Resposta não pode ser vazio. + characters: conteúdo deve ser pelo menos 6 caracteres em comprimento. + tips: + header_1: Obrigado pela sua resposta + li1_1: Por favor, não esqueça de responder a pergunta. Providencie detalhes e compartilhe a sua pesquisa. + li1_2: Faça backup de quaisquer declarações que você fizer com referências ou experiência pessoal. + header_2: Mas evite ... + li2_1: Pedir ajuda, buscar esclarecimentos ou responder a outras respostas. + reopen: + confirm_btn: Reabrir + title: Reabrir esta postagem + content: Você tem certeza que deseja reabrir? + list: + confirm_btn: Lista + title: Liste esta postagem + content: Você tem certeza que deseja listar? + unlist: + confirm_btn: Remover da lista + title: Remover da lista de postagens + content: Tem certeza de que deseja remover da lista? + pin: + title: Fixe esta postagem + content: Tem certeza de que deseja fixar globalmente? Esta postagem aparecerá no topo de todas as listas de postagens. + confirm_btn: Fixar + delete: + title: Excluir esta postagem + question: >- + Nós não recomendamos excluindo perguntas com respostas porque isso priva os futuros leitores desse conhecimento.

        Repeated deletion of answered questions can result in a sua account being blocked from asking. Você tem certeza que deseja deletar? + answer_accepted: >- +

        Nós não recomendamos excluir perguntas com respostas porque isso priva os futuros leitores desse conhecimento.

        A exclusão repetida de respostas aceitas pode resultar no bloqueio de respostas de sua conta.. Você tem certeza que deseja deletar? + other: Você tem certeza que deseja deletar? + tip_answer_deleted: Esta resposta foi deletada + undelete_title: Recuperar esta publicação + undelete_desc: Você tem certeza que deseja recuperar? + btns: + confirm: Confirmar + cancel: Cancelar + edit: Editar + save: Salvar + delete: Excluir + undelete: Recuperar + list: Lista + unlist: Não listar + unlisted: Não listado + login: Entrar + signup: Cadastrar-se + logout: Sair + verify: Verificar + create: Create + approve: Aprovar + reject: Rejetar + skip: Pular + discard_draft: Descartar rascunho + pinned: Fixado + all: Todos + question: Pergunta + answer: Resposta + comment: Comentário + refresh: Atualizar + resend: Reenviar + deactivate: Desativar + active: Ativar + suspend: Suspender + unsuspend: Suspensão cancelada + close: Fechar + reopen: Reabrir + ok: OK + light: Claro + dark: Escuro + system_setting: Definições de sistema + default: Padrão + reset: Reset + tag: Marcador + post_lowercase: publicação + filter: Filtro + ignore: Ignorar + submit: Submeter + normal: Normal + closed: Fechado + deleted: Removido + deleted_permanently: Deleted permanently + pending: Pendente + more: Mais + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Procurar Resultados + keywords: Palavras-chave + options: Opções + follow: Seguir + following: Seguindo + counts: "{{count}} Resultados" + counts_loading: "... Results" + more: Mais + sort_btns: + relevance: Relevância + newest: Mais recente + active: Ativar + score: Pontuação + more: Mais + tips: + title: Dicas de Pesquisa Avançada + tag: "<1>[tag] pesquisar com um marcador" + user: "<1>user:username buscar por autor" + answer: "<1>answers:0 perguntas não respondidas" + score: "<1>score:3 postagens com mais de 3+ placares" + question: "<1>is:question buscar perguntas" + is_answer: "<1>is:answer buscar respostas" + empty: Não conseguimos encontrar nada.
        Tente palavras-chave diferentes ou menos específicas. + share: + name: Compartilhar + copy: Copiar link + via: Compartilhar postagem via... + copied: Copiado + facebook: Compartilhar no Facebook + twitter: Share to X + cannot_vote_for_self: Você não pode votar na sua própria postagem + modal_confirm: + title: Erro... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: A sua nova conta está confirmada; você será redirecionado para a página inicial. + link: Continuar para a página inicial. + oops: Oops! + invalid: O link utilizado não funciona mais. + confirm_new_email: O seu e-mail foi atualizado. + confirm_new_email_invalid: >- + Desculpe, este link de confirmação não é mais válido. Talvez o seu e-mail já tenha sido alterado. + unsubscribe: + page_title: Cancelar subscrição + success_title: Cancelamento de inscrição bem-sucedido + success_desc: Você foi removido com sucesso desta lista de assinantes e não receberá mais nenhum e-mail nosso. + link: Mudar configurações + question: + following_tags: Seguindo Marcadores + edit: Editar + save: Salvar + follow_tag_tip: Seguir tags to curate a sua lista de perguntas. + hot_questions: Perguntas quentes + all_questions: Todas Perguntas + x_questions: "{{ count }} perguntas" + x_answers: "{{ count }} respostas" + x_posts: "{{ count }} Posts" + questions: Perguntas + answers: Respostas + newest: Mais recente + active: Ativo + hot: Popular + frequent: Frequente + recommend: Recomendado + score: Pontuação + unanswered: Não Respondido + modified: modificado + answered: respondido + asked: perguntado + closed: fechado + follow_a_tag: Seguir o marcador + more: Mais + personal: + overview: Visão geral + answers: Respostas + answer: resposta + questions: Perguntas + question: pergunta + bookmarks: Favoritas + reputation: Reputação + comments: Comentários + votes: Votos + badges: Emblemas + newest: Mais recente + score: Pontuação + edit_profile: Editar Perfil + visited_x_days: "Visitado {{ count }} dias" + viewed: Visualizado + joined: Ingressou + comma: "," + last_login: Visto + about_me: Sobre mim + about_me_empty: "// Olá, Mundo !" + top_answers: Melhores Respostas + top_questions: Melhores Perguntas + stats: Estatísticas + list_empty: Postagens não encontradas.
        Talvez você queira selecionar uma guia diferente? + content_empty: Nenhum post encontrado. + accepted: Aceito + answered: respondido + asked: perguntado + downvoted: voto negativo + mod_short: Moderador + mod_long: Moderadores + x_reputation: reputação + x_votes: votos recebidos + x_answers: respostas + x_questions: perguntas + recent_badges: Emblemas recentes + install: + title: Instalação + next: Proximo + done: Completo + config_yaml_error: Não é possível criar o arquivo config.yaml. + lang: + label: Por favor Escolha um Idioma + db_type: + label: Motor do Banco de dados + db_username: + label: Nome de usuário + placeholder: raiz + msg: Nome de usuário não pode ser vazio. + db_password: + label: Senha + placeholder: raiz + msg: Senha não pode ser vazio. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host não pode ser vazio. + db_name: + label: Database Nome + placeholder: resposta + msg: Database Nome não pode ser vazio. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File não pode ser vazio. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Criar config.yaml + label: Arquivo config.yaml criado. + desc: >- + Você pode criar o arquivo <1>config.yaml manualmente no diretório <1>/var/ww/xxx/ e colar o seguinte texto nele. + info: Qlique no botão "Próximo" após finalizar. + site_information: Informação do Site + admin_account: Administrador Conta + site_name: + label: Site Nome + msg: Site Nome não pode ser vazio. + msg_max_length: O nome do site deve ter no máximo 30 caracteres. + site_url: + label: URL do Site + text: O endereço do seu site. + msg: + empty: Site URL não pode ser vazio. + incorrect: URL do site está incorreto. + max_length: O nome do site deve ter no máximo 512 caracteres. + contact_email: + label: E-mail par contato + text: O endereço de e-mail do contato principal deste site. + msg: + empty: E-mail par contato não pode ser vazio. + incorrect: E-mail par contato incorrect format. + login_required: + label: Privado + switch: É necessário fazer login + text: Somente usuários conectados podem acessar esta comunidade. + admin_name: + label: Nome + msg: Nome não pode ser vazio. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Senha + text: >- + You will need this password to log in. Por favor store it in a secure location. + msg: Senha não pode ser vazio. + msg_min_length: A senha deve ser ter pelo menos 8 caracteres. + msg_max_length: A senha deve ter no máximo 32 caracteres. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: E-mail + text: Você precisará deste e-mail para efetuar o login. + msg: + empty: Email não pode ser vazio. + incorrect: O formato do e-mail está incorreto. + ready_title: Seu site está pronto + ready_desc: >- + Se você quiser alterar mais configurações, visite <1>seção de administrador; encontre-o no menu do site. + good_luck: "Divirta-se, e boa sorte!" + warn_title: Atenção + warn_desc: >- + O arquivo <1>config.yaml já existe. Se você precisa redefinir algum dos itens de configuração deste arquivo, apague-o primeiro. + install_now: Você pode tentar <1>instalando agora. + installed: Já instalado + installed_desc: >- + You appear to have already installed. To reinstall please clear a sua old database tables first. + db_failed: Falha ao conectar-se ao banco de dados + db_failed_desc: >- + This either means that the database information in a sua <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean a sua host's database server is down. + counts: + views: visualizações + votes: votos + answers: respostas + accepted: Aceito + page_error: + http_error: Erro HTTP {{ code }} + desc_403: Você não possui permissão para acessar esta página. + desc_404: Infelizmente esta página não existe. + desc_50X: Houve um erro no servidor e não foi possível completar a sua requisição. + back_home: Voltar para a página inicial + page_maintenance: + desc: "Estamos em manutenção, voltaremos em breve." + nav_menus: + dashboard: Painel + contents: Conteúdos + questions: Perguntas + answers: Respostas + users: Usuários + badges: Emblemas + flags: Marcadores + settings: Configurações + general: Geral + interface: Interface + smtp: SMTP + branding: Marca + legal: Informação legal + write: Escrever + terms: Terms + tos: Termos de Serviços + privacy: Privacidade + seo: SEO + customize: Personalização + themes: Temas + login: Entrar + privileges: Privilégios + plugins: Extensões + installed_plugins: Plugins instalados + apperance: Appearance + website_welcome: Bem vindo(a) ao {{site_name}} + user_center: + login: Entrar + qrcode_login_tip: Por favor, utilize {{ agentName }} para escanear o QR code para entrar. + login_failed_email_tip: Falha ao entrar, por favor, permita que este aplicativo acesse a informação do seu e-mail antes de tentar novamente. + badges: + modal: + title: Parabéns + content: Você ganhou um novo emblema. + close: Fechar + confirm: Ver emblemas + title: Emblemas + awarded: Premiado + earned_×: Ganhou ×{{ number }} + ×_awarded: "{{ number }} premiado" + can_earn_multiple: Você pode ganhar isto várias vezes. + earned: Ganhou + admin: + admin_header: + title: Administrador + dashboard: + title: Painel + welcome: Bem-vindo ao Admin! + site_statistics: Estatísticas do site + questions: "Perguntas:" + resolved: "Resolvido:" + unanswered: "Não Respondido:" + answers: "Respostas:" + comments: "Comentários:" + votes: "Votos:" + users: "Usuários:" + flags: "Marcadores:" + reviews: "Revisão:" + site_health: Saúde do site + version: "Versão:" + https: "HTTPS:" + upload_folder: "Upload da pasta:" + run_mode: "Mode de execução:" + private: Privado + public: Público + smtp: "SMTP:" + timezone: "Fuso horário:" + system_info: Informação do sistema + go_version: "Versão do Go:" + database: "Banco de dados:" + database_size: "Tamanho do banco de dados:" + storage_used: "Armazenamento usado:" + uptime: "Tempo de atividade:" + links: Links + plugins: Plugins + github: GitHub + blog: Blog + contact: Contato + forum: Fórum + documents: Documentos + feedback: Opinião + support: Supporte + review: Revisar + config: Configurações + update_to: Atualizar ao + latest: Ultimo + check_failed: Falha na verificação + "yes": "Sim" + "no": "Não" + not_allowed: Não permitido + allowed: Permitido + enabled: Ativo + disabled: Disponível + writable: Possível escrever + not_writable: Não é possível escrever + flags: + title: Marcadores + pending: Pendente + completed: Completo + flagged: Marcado + flagged_type: '{{ type }} sinalizado' + created: Criado + action: Ação + review: Revisar + user_role_modal: + title: Altere a função do usuário para... + btn_cancel: Cancelar + btn_submit: Enviar + new_password_modal: + title: Criar nova senha + form: + fields: + password: + label: Senha + text: O usuário será desconectado e precisar entrar novamente. + msg: A senha precisa ter no mínimo 8-32 caracteres. + btn_cancel: Cancelar + btn_submit: Enviar + edit_profile_modal: + title: Editar profile + form: + fields: + display_name: + label: Nome no display + msg_range: Display name must be 2-30 characters in length. + username: + label: Nome do usuário + msg_range: Username must be 2-30 characters in length. + email: + label: Correio eletrônico + msg_invalid: Correio eletrônico invalido. + edit_success: Editado com sucesso + btn_cancel: Cancelar + btn_submit: Submeter + user_modal: + title: Adicionar novo usuário + form: + fields: + users: + label: Adicionar usuários em massa + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separe "nome, e-mail, senha" com vírgulas. Um usuário por linha. + msg: "Por favor insira o e-mail do usuário, um por linha." + display_name: + label: Nome de exibição + msg: O nome de exibição deve ter entre 2 e 30 caracteres. + email: + label: E-mail + msg: E-mail inválido. + password: + label: Senha + msg: A senha precisa ter no mínimo 8-32 caracteres. + btn_cancel: Cancelar + btn_submit: Enviar + users: + title: Usuários + name: Nome + email: E-mail + reputation: Reputação + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Estado + role: Função + action: Ação + change: Mudar + all: Todos + staff: Funcionários + more: Mais + inactive: Inativo + suspended: Suspenso + deleted: Removido + normal: Normal + Moderator: Moderador + Admin: Administrador + User: Usuário + filter: + placeholder: "Filtrar por nome, user:id" + set_new_password: Configurar nova senha + edit_profile: Editar profile + change_status: Mudar status + change_role: Mudar função + show_logs: Mostrar registros + add_user: Adicionar usuário + deactivate_user: + title: Desativar usuários + content: Um usuário inativo deve revalidar seu e-mail. + delete_user: + title: Remover este usuário + content: Tem certeza de que deseja excluir este usuário? Isso é permanente! + remove: Remover o conteúdo dele + label: Remover todas as perguntas, respostas, comentários etc. + text: Não marque isso se deseja excluir apenas a conta do usuário. + suspend_user: + title: Suspender este usuário + content: Um usuário suspenso não pode fazer login. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Perguntas + unlisted: Não-listado + post: Publicação + votes: Votos + answers: Respostas + created: Criado + status: Estado + action: Ação + change: Mudar + pending: Pendente + filter: + placeholder: "Filtrar por título, question:id" + answers: + page_title: Respostas + post: Publicação + votes: Votos + created: Criado + status: Estado + action: Ação + change: Mudar + filter: + placeholder: "Filtrar por título, answer:id" + general: + page_title: Geral + name: + label: Site Nome + msg: Site name não pode ser vazio. + text: "O nome deste site, conforme usado na tag de título." + site_url: + label: URL do Site + msg: Site url não pode ser vazio. + validate: Por favor digite uma URL válida. + text: O endereço do seu site. + short_desc: + label: Breve Descrição do site (opcional) + msg: Breve Descrição do site não pode ser vazio. + text: "Breve descrição, conforme usado na tag de título na página inicial." + desc: + label: Site Descrição (opcional) + msg: Descrição do site não pode ser vazio. + text: "Descreva este site em uma única sentença, conforme usado na meta tag de descrição." + contact_email: + label: E-mail para contato + msg: E-mail par contato não pode ser vazio. + validate: E-mail par contato não é válido. + text: Endereço de e-mail do principal contato responsável por este site. + check_update: + label: Atualizações de software + text: Verificar se há atualizações automaticamente + interface: + page_title: Interface + language: + label: Idioma da interface + msg: Idioma da Interface não pode ser vazio. + text: Idioma da interface do Usuário. Ele mudará quando você atualizar a página. + time_zone: + label: Fuso horário + msg: Fuso horário não pode ser vazio. + text: Escolha a cidade no mesmo fuso horário que você. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: E-mail de origem + msg: E-mail de origem não pode ser vazio. + text: O endereço de e-mail de onde os e-mails são enviados. + from_name: + label: Nome de origem + msg: Nome de origem não pode ser vazio. + text: O nome de onde os e-mails são enviados. + smtp_host: + label: SMTP Host + msg: SMTP host não pode ser vazio. + text: O seu servidor de e-mails. + encryption: + label: Criptografia + msg: Criptografia não pode ser vazio. + text: Para a maioria dos servidores SSL é a opção recomendada. + ssl: SSL + tls: TLS + none: Nenhum + smtp_port: + label: SMTP Port + msg: Porta SMTP deve ser o número 1 ~ 65535. + text: The port to a sua mail server. + smtp_username: + label: SMTP Nome de usuário + msg: SMTP username não pode ser vazio. + smtp_password: + label: SMTP Senha + msg: SMTP password não pode ser vazio. + test_email_recipient: + label: Test Email Recipients + text: Forneça o endereço de e-mail que irá receber envios de teste. + msg: O e-mail de teste é inválido + smtp_authentication: + label: Habilitar autenticação + title: Autenticação SMTP + msg: Autenticação SMTP não pode ser vazio. + "yes": "Sim" + "no": "Não" + branding: + page_title: Marca + logo: + label: Logo (opcional) + msg: Logo não pode ser vazio. + text: The logo image at the top left of a sua site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (opcional) + text: The logo used on mobile version of a sua site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square Icon (opcional) + msg: Square icon não pode ser vazio. + text: Imagem used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (opcional) + text: A favicon for a sua site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Informação legal + terms_of_service: + label: Terms of Service + text: "Você pode adicionar termos de conteúdo de serviço aqui. Se você já tem um documento hospedado em outro lugar, forneça a URL completa aqui." + privacy_policy: + label: Privacy Policy + text: "Você pode adicionar termos de conteúdo de serviço aqui. Se você já tem um documento hospedado em outro lugar, forneça a URL completa aqui." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Escrever + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Escrever resposta + label: Each user can only write one answer for each question + text: "Desative para permitir que os usuários escrevam várias respostas para a mesma pergunta, o que pode fazer com que as respostas fiquem menos focadas." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Recommend Marcadores + text: "Os marcadores recomendados serão exibidos na lista dropdown por padrão." + msg: + contain_reserved: "tags recomendadas não podem conter tags reservadas" + required_tag: + title: Definir tags necessárias + label: Definir "Tags recomendadas" como tags necessárias + text: "Every new question must have ao menos one recommend tag." + reserved_tags: + label: Reserved Marcadores + text: "Tags reservadas só podem ser usadas pelo moderador." + image_size: + label: Tamanho máximo da imagem (MB) + text: "O tamanho máximo para upload de imagem." + attachment_size: + label: Tamanho máximo do anexo (MB) + text: "O tamanho máximo para o carregamento de arquivos anexados." + image_megapixels: + label: Máximo megapíxels da imagem + text: "Número máximo de megapixels permitido para uma imagem." + image_extensions: + label: Extensões de imagens autorizadas + text: "Uma lista de extensões de arquivo permitidas para exibição de imagens, separadas por vírgula." + attachment_extensions: + label: Extensões autorizadas para anexos + text: "Uma lista de extensões de arquivo permitidas para carregamento, separar por vírgula. AVISO: permitir o carregamento pode causar problemas de segurança." + seo: + page_title: SEO + permalink: + label: Link permanente + text: Custom URL structures can improve the usability, and forward-compatibility of a sua links. + robots: + label: robos.txt + text: Isto irá substituir permanentemente quaisquer configurações do site relacionadas. + themes: + page_title: Temas + themes: + label: Temas + text: Selecionar um tema existente. + color_scheme: + label: Esquema de cores + navbar_style: + label: Navbar background style + primary_color: + label: Cor primária + text: Modifica as cores usadas por seus temas + css_and_html: + page_title: CSS e HTML + custom_css: + label: CSS Personalizado + text: > + + head: + label: Cabeçalho + text: > + + header: + label: Cabeçalho + text: > + + footer: + label: Rodapé + text: Isto será inserido antes de </body>. + sidebar: + label: Barra lateral + text: Isto irá inserir na barra lateral. + login: + page_title: Entrar + membership: + title: Afiliação + label: Permitir novas inscrições + text: Desligue para impedir que alguém crie uma nova conta. + email_registration: + title: Registrar e-mail + label: Permitir registro utilizando e-mail + text: Desative para impedir que qualquer pessoa crie uma nova conta por e-mail. + allowed_email_domains: + title: Domínios de e-mail permitidos + text: Domínios de e-mail com os quais os usuários devem registrar contas. Um domínio por linha. Ignorado quando vazio. + private: + title: Privado + label: Login requirido + text: Somente usuários conectados podem acessar esta comunidade. + password_login: + title: Login com senha + label: Permitir login por e-mail e senha + text: "AVISO: Se desativar, você pode ser incapaz de efetuar login se você não tiver configurado anteriormente outro método de login." + installed_plugins: + title: Extensões instaladas + plugin_link: Plugins ampliam e expandem a funcionalidade. Você pode encontrar plugins no <1>Repositório de Plugins. + filter: + all: Todos + active: Ativo + inactive: Inativo + outdated: Desactualizado + plugins: + label: Extensões + text: Selecionar uma extensão existente. + name: Nome + version: Versão + status: Estado + action: Ação + deactivate: Desativar + activate: Ativado + settings: Configurações + settings_users: + title: Usuários + avatar: + label: Avatar padrão + text: Para usuários sem um avatar personalizado próprio. + gravatar_base_url: + label: Gravatar Base URL + text: URL da API do provedor Gravatar ignorado quando vazio. + profile_editable: + title: Perfil editável + allow_update_display_name: + label: Permitir que os usuários mudem seus nomes de exibição + allow_update_username: + label: Permitem que os usuário mudem seus nomes de usuário + allow_update_avatar: + label: Permitem que os usuário mudem a sua imagem de perfil + allow_update_bio: + label: Permitir que os usuários mudem suas descrições + allow_update_website: + label: Permitir que os usuários mudem seus web-sites + allow_update_location: + label: Permitir que usuários alterem suas localizações + privilege: + title: Privilégios + level: + label: Nível de reputação necessário + text: Escolha a reputação necessária para os privilégios + msg: + should_be_number: o valor de entrada deve ser número + number_larger_1: número deve ser igual ou maior que 1 + badges: + action: Ação + active: Ativo + activate: Ativado + all: Todos + awards: Prêmios + deactivate: Desativar + filter: + placeholder: Filtrar por nome, badge:id + group: Grupo + inactive: Inativo + name: Nome + show_logs: Mostrar registros + status: Status + title: Emblemas + form: + optional: (opcional) + empty: não pode ser vazio + invalid: é inválido + btn_submit: Salvar + not_found_props: "Propriedade requerida {{ key }} não encontrada." + select: Selecionar + page_review: + review: Revisar + proposed: proposto + question_edit: Editar pergunta + answer_edit: Editar resposta + tag_edit: Editar marcador + edit_summary: Editar descrição + edit_question: Editar pergunta + edit_answer: Editar resposta + edit_tag: Editar marcador + empty: Nenhuma tarefa de revisão restante. + approve_revision_tip: Você aprova esta revisão? + approve_flag_tip: Você aprova esta sinalização? + approve_post_tip: Você aprova esta publicação? + approve_user_tip: Você aprova este usuário? + suggest_edits: Edições sugeridas + flag_post: Post sinalizado + flag_user: Sinalizar usuário + queued_post: Publicação na fila + queued_user: Usuário na fila + filter_label: Tipo + reputation: reputação + flag_post_type: Sinalizou esta publicação como {{ type }}. + flag_user_type: Sinalizou este usuário como {{ type }}. + edit_post: Editar publicação + list_post: Listar postagem + unlist_post: Remover postagem da lista + timeline: + undeleted: não removido + deleted: removido + downvote: voto negativo + upvote: voto positivo + accept: aceito + cancelled: cancelado + commented: comentado + rollback: reversão + edited: editado + answered: respondido + asked: perguntado + closed: fechado + reopened: reaberto + created: criado + pin: fixado + unpin: desafixado + show: listadas + hide: não listado + title: "Histórico para" + tag_title: "Título para" + show_votes: "Mostrar Votos" + n_or_a: Não aplicável + title_for_question: "Título para" + title_for_answer: "Título para resposta {{ title }} por {{ author }}" + title_for_tag: "Título para marcador" + datetime: Data e hora + type: Tipo + by: Por + comment: Comentário + no_data: "Não conseguimos encontrar nada." + users: + title: Usuários + users_with_the_most_reputation: Usuários com maior pontuação + users_with_the_most_vote: Usuários que mais votaram + staffs: Nossos colaboradores + reputation: reputação + votes: votos + prompt: + leave_page: Tem a certeza que quer sair desta página? + changes_not_save: Suas alterações não podem ser salvas. + draft: + discard_confirm: Tem certeza que deseja descartar o rascunho? + messages: + post_deleted: Esta publicação foi removida. + post_cancel_deleted: Esta postagem foi restaurada. + post_pin: Esta publicação foi fixada. + post_unpin: Esta postagem foi desafixada. + post_hide_list: Esta postagem foi ocultada da lista. + post_show_list: Esta postagem foi exibida à lista. + post_reopen: Esta publicação foi re-aberta. + post_list: Esta postagem foi listada. + post_unlist: Esta publicação foi removida da lista. + post_pending: A sua postagem está aguardando revisão. Ela ficará visível depois que for aprovada. + post_closed: Esta postagem foi fechada. + answer_deleted: Esta resposta foi excluída. + answer_cancel_deleted: Esta resposta foi restaurada. + change_user_role: O papel deste usuário foi alterado. + user_inactive: Este usuário já está inativo. + user_normal: Este usuário já está normal. + user_suspended: Este usuário foi suspenso. + user_deleted: Este usuário foi removido. + badge_activated: Este emblema foi ativado. + badge_inactivated: Este emblema foi desativado. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/ro_RO.yaml b/data/i18n/ro_RO.yaml new file mode 100644 index 000000000..f001328b6 --- /dev/null +++ b/data/i18n/ro_RO.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Succes. + unknown: + other: Eroare necunoscută. + request_format_error: + other: Formatul cererii nu este valid. + unauthorized_error: + other: Neautorizat. + database_error: + other: Eroare la serverul de date. + forbidden_error: + other: Interzis. + duplicate_request_error: + other: Trimitere dublă. + action: + report: + other: Steag + edit: + other: Editează + delete: + other: Ștergere + close: + other: Închide + reopen: + other: Redeschidere + forbidden_error: + other: Interzis. + pin: + other: Fixează + hide: + other: Dezlistare + unpin: + other: Anulați fixarea + show: + other: Listă + invite_someone_to_answer: + other: Editează + undelete: + other: Restabilește + merge: + other: Îmbinare + role: + name: + user: + other: Utilizator + admin: + other: Administrator + moderator: + other: Moderator + description: + user: + other: Implicit fără acces special. + admin: + other: Ai puterea deplină de a accesa site-ul. + moderator: + other: Are acces la toate postările cu excepţia setărilor administratorului. + privilege: + level_1: + description: + other: Nivel 1 (mai puțină reputație pentru echipa privată, grup) + level_2: + description: + other: Nivelul 2 (reputație scăzută necesară pentru comunitatea de pornire) + level_3: + description: + other: Nivelul 3 (reputație ridicată necesară pentru comunitatea mature) + level_custom: + description: + other: Nivel personalizat + rank_question_add_label: + other: Întreabă ceva + rank_answer_add_label: + other: Scrie răspunsul + rank_comment_add_label: + other: Scrie comentariu + rank_report_add_label: + other: Steag + rank_comment_vote_up_label: + other: Votează comentariul + rank_link_url_limit_label: + other: Postează mai mult de 2 link-uri simultan + rank_question_vote_up_label: + other: Votează întrebarea + rank_answer_vote_up_label: + other: Votează răspunsul + rank_question_vote_down_label: + other: Votează întrebarea ca negativa + rank_answer_vote_down_label: + other: Voteaza răspunsul ca negativ + rank_invite_someone_to_answer_label: + other: Invită pe cineva să răspundă + rank_tag_add_label: + other: Creează o etichetă nouă + rank_tag_edit_label: + other: Editați descrierea etichetei (este nevoie de revizuire) + rank_question_edit_label: + other: Editați altă întrebare (este nevoie de revizuire) + rank_answer_edit_label: + other: Editați altă întrebare (este nevoie de revizuire) + rank_question_edit_without_review_label: + other: Editează întrebarea celuilalt fără revizuire + rank_answer_edit_without_review_label: + other: Editează întrebarea celuilalt fără revizuire + rank_question_audit_label: + other: Revizuiește editarea întrebărilor + rank_answer_audit_label: + other: Revizuiește editările răspunsurilor + rank_tag_audit_label: + other: Revizuiește editarea etichetelor + rank_tag_edit_without_review_label: + other: Editează descrierea etichetei fără revizuire + rank_tag_synonym_label: + other: Gestionează sinonimele etichetelor + email: + other: E-mail + e_mail: + other: E-mail + password: + other: Parolă + pass: + other: Parolă + old_pass: + other: Parolă actuală + original_text: + other: Acest articol + email_or_password_wrong_error: + other: E-mailul și parola nu se potrivesc. + error: + common: + invalid_url: + other: URL invalid. + status_invalid: + other: Stare nevalidă. + password: + space_invalid: + other: Parola nu poate conține spații. + admin: + cannot_update_their_password: + other: Nu vă puteți modifica parola. + cannot_edit_their_profile: + other: Nu vă puteți modifica profilul. + cannot_modify_self_status: + other: Nu vă puteți modifica starea. + email_or_password_wrong: + other: E-mailul și parola nu se potrivesc. + answer: + not_found: + other: Răspunsul nu a fost găsit. + cannot_deleted: + other: Nu există permisiunea de ștergere. + cannot_update: + other: Nu există permisiunea de ștergere. + question_closed_cannot_add: + other: Întrebările sunt închise şi nu pot fi adăugate. + content_cannot_empty: + other: Conținutul răspunsului nu poate fi gol. + comment: + edit_without_permission: + other: Comentariul nu poate fi editat. + not_found: + other: Comentariul nu a fost găsit. + cannot_edit_after_deadline: + other: Comentariul a durat prea mult pentru a fi modificat. + content_cannot_empty: + other: Conținutul comentariului nu poate fi gol. + email: + duplicate: + other: Email-ul există deja. + need_to_be_verified: + other: E-mailul trebuie verificat. + verify_url_expired: + other: Adresa de e-mail verificată a expirat, vă rugăm să retrimiteți e-mailul. + illegal_email_domain_error: + other: E-mailul nu este permis din acel domeniu de e-mail. Vă rugăm să folosiți altul. + lang: + not_found: + other: Fișierul de limbă nu a fost găsit. + object: + captcha_verification_failed: + other: Captcha este greșit. + disallow_follow: + other: Nu vă este permis să urmăriți. + disallow_vote: + other: Nu ai permisiunea de a vota. + disallow_vote_your_self: + other: Nu poți vota pentru propria ta postare. + not_found: + other: Obiectul nu a fost găsit. + verification_failed: + other: Verificarea a eșuat. + email_or_password_incorrect: + other: E-mailul și parola nu se potrivesc. + old_password_verification_failed: + other: Verificarea parolei vechi a eșuat + new_password_same_as_previous_setting: + other: Noua parolă este identică cu cea anterioară. + already_deleted: + other: Acest articol a fost șters. + meta: + object_not_found: + other: Nu s-a găsit obiectul Meta + question: + already_deleted: + other: Această postare a fost ștearsă. + under_review: + other: Articolul tău este în așteptare. Acesta va fi vizibil după ce a fost aprobat. + not_found: + other: Întrebarea nu a fost găsită. + cannot_deleted: + other: Nu există permisiunea de ștergere. + cannot_close: + other: Nu există permisiunea de a închide. + cannot_update: + other: Nu aveți permisiunea de a actualiza. + content_cannot_empty: + other: Conținutul nu poate fi gol. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Rangul de reputaţie nu îndeplineşte condiţia. + vote_fail_to_meet_the_condition: + other: Mulțumim pentru feedback. Aveți nevoie cel puțin de reputația {{.Rank}} pentru a vota. + no_enough_rank_to_operate: + other: Aveți nevoie cel puțin de reputația {{.Rank}} pentru a face asta. + report: + handle_failed: + other: Procesarea raportării a eșuat. + not_found: + other: Raportul nu a fost găsit. + tag: + already_exist: + other: Eticheta există deja. + not_found: + other: Eticheta nu a fost găsită. + recommend_tag_not_found: + other: Eticheta recomandată nu există. + recommend_tag_enter: + other: Te rugăm să introduci cel puțin o etichetă necesară. + not_contain_synonym_tags: + other: Nu trebuie să conțină etichete sinonime. + cannot_update: + other: Nu aveți permisiunea de a actualiza. + is_used_cannot_delete: + other: Nu puteți șterge o etichetă care este în uz. + cannot_set_synonym_as_itself: + other: Nu se poate seta sinonimul etichetei curente ca atare. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: Numele nu poate fi o adresă de e-mail. + theme: + not_found: + other: Tema nu a fost găsită. + revision: + review_underway: + other: Nu se poate edita momentan, există o versiune în coada de revizuire. + no_permission: + other: Nu ai permisiunea de a revizui. + user: + external_login_missing_user_id: + other: Platforma terță nu oferă un Id de utilizator unic, deci nu vă puteți autentifica, contactați administratorul site-ului. + external_login_unbinding_forbidden: + other: Vă rugăm să setaţi o parolă de conectare pentru contul dumneavoastră înainte de a elimina această autentificare. + email_or_password_wrong: + other: + other: E-mailul și parola nu se potrivesc. + not_found: + other: Utilizatorul nu a fost găsit. + suspended: + other: Utilizatorul a fost suspendat. + username_invalid: + other: Numele de utilizator nu este valid. + username_duplicate: + other: Numele de utilizator este deja luat. + set_avatar: + other: Setarea avatarului a eșuat. + cannot_update_your_role: + other: Nu vă puteți modifica rolul. + not_allowed_registration: + other: În prezent, site-ul nu este deschis pentru înregistrare. + not_allowed_login_via_password: + other: În prezent, site-ul nu este permis să se autentifice prin parolă. + access_denied: + other: Acces Blocat + page_access_denied: + other: Nu aveți acces la această pauză. + add_bulk_users_format_error: + other: "{{.Field}} format lângă '{{.Content}}' la linia {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "Numărul de utilizatori pe care îi adăugați odată trebuie să fie în intervalul 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Citirea configurației a eșuat + database: + connection_failed: + other: Conexiunea la baza de date a eșuat + create_table_failed: + other: Crearea tabelului a eșuat + install: + create_config_failed: + other: Nu se poate crea fișierul config.yaml. + upload: + unsupported_file_format: + other: Format de fișier incompatibil. + site_info: + config_not_found: + other: Configurarea site-ului nu a fost găsită. + badge: + object_not_found: + other: Nu s-a găsit obiectul Insignă + reason: + spam: + name: + other: nedorite + desc: + other: Acest post este o reclamă sau un vandalism. Nu este util sau relevant pentru subiectul actual. + rude_or_abusive: + name: + other: nepoliticos sau abuziv + desc: + other: "O persoană rezonabilă ar considera acest conținut nepotrivit pentru un discurs respectuos." + a_duplicate: + name: + other: un duplicat + desc: + other: Această întrebare a fost adresată înainte şi are deja un răspuns. + placeholder: + other: Introduceți link-ul de întrebare existent + not_a_answer: + name: + other: nu este un răspuns + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." + no_longer_needed: + name: + other: nu mai este necesar + desc: + other: Acest comentariu este învechit, conversaţional sau nu are relevanţă pentru această postare. + something: + name: + other: altceva + desc: + other: Acest post necesită atenție din partea personalului, din alt motiv nemenționat mai sus. + placeholder: + other: Spune-ne ce anume vă îngrijorează + community_specific: + name: + other: un motiv specific comunității + desc: + other: Această întrebare nu corespunde cu ghidul comunității. + not_clarity: + name: + other: are nevoie de detalii sau de claritate + desc: + other: Această întrebare include în prezent mai multe întrebări. Ar trebui să se concentreze asupra unei singure probleme. + looks_ok: + name: + other: arată OK + desc: + other: Această postare este bună și nu este de slabă calitate. + needs_edit: + name: + other: are nevoie de editare și am făcut-o + desc: + other: Îmbunătățește și corectează problemele cu această postare. + needs_close: + name: + other: necesită închidere + desc: + other: La o întrebare închisă nu poți răspunde, dar poți totuși să o editezi, să o votezi și să o comentezi. + needs_delete: + name: + other: necesită ștergere + desc: + other: Această postare va fi ștearsă. + question: + close: + duplicate: + name: + other: nedorite + desc: + other: Această întrebare a fost adresată înainte şi are deja un răspuns. + guideline: + name: + other: un motiv specific comunității + desc: + other: Această întrebare nu corespunde cu ghidul comunității. + multiple: + name: + other: necesită detalii sau claritate + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: altceva + desc: + other: Acest post necesită un alt motiv care nu este listat mai sus. + operation_type: + asked: + other: întrebat + answered: + other: răspunse + modified: + other: modificat + deleted_title: + other: Întrebare ștearsă + questions_title: + other: Questions + tag: + tags_title: + other: Tags + no_description: + other: The tag has no description. + notification: + action: + update_question: + other: întrebarea actualizată + answer_the_question: + other: întrebare răspunsă + update_answer: + other: răspuns actualizat + accept_answer: + other: răspuns acceptat + comment_question: + other: întrebare comentată + comment_answer: + other: răspuns comentat + reply_to_you: + other: ți-a răspuns + mention_you: + other: te-a menționat + your_question_is_closed: + other: Întrebarea dumneavoastră a fost închisă + your_question_was_deleted: + other: Întâlnirea dumneavoastră a fost ştearsă + your_answer_was_deleted: + other: Răspunsul dumneavoastră a fost șters + your_comment_was_deleted: + other: Contul dumneavoastră a fost șters + up_voted_question: + other: votează întrebarea + down_voted_question: + other: votează întrebarea negativ + up_voted_answer: + other: votează răspunsul + down_voted_answer: + other: răspuns negativ + up_voted_comment: + other: votează comentariul + invited_you_to_answer: + other: te-a invitat să răspunzi + earned_badge: + other: You've earned the "{{.BadgeName}}" badge + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Confirmați noua dvs. adresă de e-mail" + body: + other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} a răspuns la întrebarea dvs" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} vă invită să răspundeți" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} a răspuns la întrebarea dvs" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_question: + title: + other: "[{{.SiteName}}] Întrebare nouă: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Resetare parolă" + body: + other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + register: + title: + other: "[{{.SiteName}}] Confirmă noul tău cont" + body: + other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + test: + title: + other: "[{{.SiteName}}] Test de e-mail" + body: + other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + action_activity_type: + upvote: + other: votat + upvoted: + other: vot pozitiv + downvote: + other: vot negativ + downvoted: + other: vot negativ + accept: + other: acceptat + accepted: + other: acceptat + edit: + other: editează + review: + queued_post: + other: Posturi în așteptare + flagged_post: + other: Postare marcată + suggested_post_edit: + other: Suggested edits + reaction: + tooltip: + other: "{{ .Names }} and {{ .Count }} more..." + badge: + default_badges: + autobiographer: + name: + other: Autobiographer + desc: + other: Filled out profile information. + certified: + name: + other: Certified + desc: + other: Completed our new user tutorial. + editor: + name: + other: Editor + desc: + other: First post edit. + first_flag: + name: + other: First Flag + desc: + other: First flagged a post. + first_upvote: + name: + other: First Upvote + desc: + other: First up voted a post. + first_link: + name: + other: First Link + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: First Share + desc: + other: First shared a post. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Leave 5 comments. + new_user_of_the_month: + name: + other: New User of the Month + desc: + other: Contribuții restante în prima lor lună. + read_guidelines: + name: + other: Read Guidelines + desc: + other: Read the [community guidelines]. + reader: + name: + other: Reader + desc: + other: Read every answers in a topic with more than 10 answers. + welcome: + name: + other: Welcome + desc: + other: Received a up vote. + nice_share: + name: + other: Nice Share + desc: + other: Shared a post with 25 unique visitors. + good_share: + name: + other: Good Share + desc: + other: Shared a post with 300 unique visitors. + great_share: + name: + other: Distribuire grozavă + desc: + other: Shared a post with 1000 unique visitors. + out_of_love: + name: + other: Out of Love + desc: + other: Used 50 up votes in a day. + higher_love: + name: + other: Higher Love + desc: + other: Used 50 up votes in a day 5 times. + crazy_in_love: + name: + other: Crazy in Love + desc: + other: Used 50 up votes in a day 20 times. + promoter: + name: + other: Promoter + desc: + other: Invited a user. + campaigner: + name: + other: Campaigner + desc: + other: Invited 3 basic users. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: Thank You + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Active member for a year, posted at least once. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Cum se formatează + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Înapoi + next: Înainte + page_title: + question: Întrebare + questions: Întrebări + tag: Etichetă + tags: Etichete + tag_wiki: etichetă wiki + create_tag: Creați etichetă + edit_tag: Modificați eticheta + ask_a_question: Create Question + edit_question: Editați întrebarea + edit_answer: Editaţi răspunsul + search: Caută + posts_containing: Posturi care conțin + settings: Setări + notifications: Notificări + login: Conectează-te + sign_up: Înregistrează-te + account_recovery: Recuperarea contului + account_activation: Activare cont + confirm_email: Confirmare e-mail + account_suspended: Cont suspendat + admin: Administrator + change_email: Modifică E-mail + install: Instalează Answer + upgrade: Actualizare Answer + maintenance: Mentenanță website + users: Utilizatori + oauth_callback: Se procesează + http_404: Eroare HTTP 404 + http_50X: Eroare HTTP 500 + http_403: Eroare HTTP 403 + logout: Deconectare + posts: Posts + notifications: + title: Notificări + inbox: Mesaje primite + achievement: Realizări + new_alerts: Alerte noi + all_read: Marchează totul ca fiind citit + show_more: Arată mai mult + someone: Cineva + inbox_type: + all: Toate + posts: Postări + invites: Invitați + votes: Voturi + answer: Answer + question: Question + badge_award: Badge + suspended: + title: Contul dumneavoastră a fost suspendat + until_time: "Contul dumneavoastră a fost suspendat până la {{ time }}." + forever: Acest utilizator a fost suspendat pentru totdeauna. + end: Această întrebare nu corespunde cu ghidul comunității. + contact_us: Contactați-ne + editor: + blockquote: + text: Citat + bold: + text: Bolt + chart: + text: Diagramă + flow_chart: Diagrama fluxului + sequence_diagram: Diagrama secvenței + class_diagram: Diagrama clasei + state_diagram: Diagrama stării + entity_relationship_diagram: Diagrama relației entității + user_defined_diagram: Diagramă definită de utilizator + gantt_chart: Grafic Gantt + pie_chart: Grafic circular + code: + text: Exemplu de cod + add_code: Adaugă exemplu de cod + form: + fields: + code: + label: Cod + msg: + empty: Corpul mesajului trebuie să conțină text. + language: + label: Limbă + placeholder: Detectare automată + btn_cancel: Anulați + btn_confirm: Adaugă + formula: + text: Formulă + options: + inline: Formula inline + block: Formula blocului + heading: + text: Titlu + options: + h1: Titlu 1 + h2: Titlu 2 + h3: Titlu 3 + h4: Titlu 4 + h5: Titlu 5 + h6: Titlu 6 + help: + text: Ajutor + hr: + text: Linie orizontală + image: + text: Imagine + add_image: Adaugă imagine + tab_image: Incarca poza + form_image: + fields: + file: + label: Fișier imagine + btn: Selectați imaginea + msg: + empty: Fișierul nu poate fi gol. + only_image: Sunt permise doar fișierele imagine. + max_size: File size cannot exceed {{size}} MB. + desc: + label: Descriere + tab_url: URL-ul imaginii + form_url: + fields: + url: + label: URL-ul imaginii + msg: + empty: URL-ul imaginii nu poate fi gol. + name: + label: Descriere + btn_cancel: Anulați + btn_confirm: Adaugă + uploading: Se încarcă + indent: + text: Indentare + outdent: + text: Outdent + italic: + text: Accentuare + link: + text: Hyperlink + add_link: Adaugă hiperlink + form: + fields: + url: + label: URL + msg: + empty: URL-ul nu poate fi gol. + name: + label: Descriere + btn_cancel: Anulează + btn_confirm: Adaugă + ordered_list: + text: Listă numerotată + unordered_list: + text: Listă cu marcatori + table: + text: Tabelă + heading: Titlu + cell: Celulă + file: + text: Attach files + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: Închid această postare ca... + btn_cancel: Anulează + btn_submit: Trimiteți + remark: + empty: Nu poate fi lăsat necompletat. + msg: + empty: Te rugăm să selectezi un motiv. + report_modal: + flag_title: Fac un semnal de alarmă pentru a raporta acest post ca... + close_title: Închid această postare ca... + review_question_title: Revizuiește întrebarea + review_answer_title: Revizuiește răspunsul + review_comment_title: Revizuiește comentariul + btn_cancel: Anulează + btn_submit: Trimiteți + remark: + empty: Nu poate fi lăsat necompletat. + msg: + empty: Te rugăm să selectezi un motiv. + not_a_url: URL format is incorrect. + url_not_match: URL origin does not match the current website. + tag_modal: + title: Creează o etichetă nouă + form: + fields: + display_name: + label: Nume afișat + msg: + empty: Numele afișat nu poate fi gol. + range: Nume afișat până la 35 de caractere. + slug_name: + label: Slug URL + desc: Slug-ul URL pana la 35 de caractere. + msg: + empty: Slug-ul URL nu poate fi gol. + range: Slug-ul URL pana la 35 de caractere. + character: URL-ul slug conţine un set de caractere nepermis. + desc: + label: Descriere + revision: + label: Versiunea + edit_summary: + label: Editează sumarul + placeholder: >- + Explicați pe scurt modificările (ortografie corectată, gramatică fixată, formatare îmbunătățită) + btn_cancel: Anulează + btn_submit: Trimiteți + btn_post: Postează o nouă etichetă + tag_info: + created_at: Creat + edited_at: Editat + history: Istoric + synonyms: + title: Sinonime + text: Următoarele etichete vor fi păstrate la + empty: Nu s-au găsit sinonime. + btn_add: Adaugă un sinonim + btn_edit: Editează + btn_save: Salvează + synonyms_text: Următoarele etichete vor rămâne la + delete: + title: Șterge această etichetă + tip_with_posts: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + tip_with_synonyms: >- +

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        + tip: Sunteţi sigur că doriţi să ştergeţi? + close: Închide + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Editează eticheta + default_reason: Editare etichetă + default_first_reason: Adaugă etichetă + btn_save_edits: Salvați modificările + btn_cancel: Anulați + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, AAAA [at] HH:mm" + now: acum + x_seconds_ago: "acum {{count}} sec" + x_minutes_ago: "acum {{count}} min" + x_hours_ago: "acum {{count}} ore" + hour: oră + day: zi + hours: ore + days: zile + month: month + months: months + year: year + reaction: + heart: heart + smile: smile + frown: frown + btn_label: add or remove reactions + undo_emoji: undo {{ emoji }} reaction + react_emoji: react with {{ emoji }} + unreact_emoji: unreact with {{ emoji }} + comment: + btn_add_comment: Adaugă comentariu + reply_to: Raspunde la + btn_reply: Răspunde + btn_edit: Editează + btn_delete: Ștergeți + btn_flag: Marcaj + btn_save_edits: Salvați modificările + btn_cancel: Anulați + show_more: "{{count}} alte comentarii" + tip_question: >- + Utilizați comentariile pentru a solicita mai multe informații sau pentru a sugera îmbunătățiri. Evitați răspunsul la întrebări în comentarii. + tip_answer: >- + Utilizați comentarii pentru a răspunde la alți utilizatori sau pentru a le notifica modificările. Dacă adăugați informații noi, editați postarea în loc să comentați. + tip_vote: Adaugă ceva util postării + edit_answer: + title: Editaţi răspunsul + default_reason: Editați răspunsul + default_first_reason: Adăugare răspuns + form: + fields: + revision: + label: Revizuire + answer: + label: Răspuns + feedback: + characters: conţinutul trebuie să aibă cel puţin 6 caractere. + edit_summary: + label: Editează sumarul + placeholder: >- + Explicați pe scurt modificările (ortografie corectată, gramatică fixă, formatare îmbunătățită) + btn_save_edits: Salvați modificările + btn_cancel: Anulează + tags: + title: Etichete + sort_buttons: + popular: Popular + name: Nume + newest: Cele mai noi + button_follow: Urmărește + button_following: Urmăriți + tag_label: întrebări + search_placeholder: Filtrare după numele etichetei + no_desc: Această echipă nu are o descriere. + more: Mai multe + wiki: Wiki + ask: + title: Create Question + edit_title: Editați întrebarea + default_reason: Editați întrebarea + default_first_reason: Create question + similar_questions: Întrebări similare + form: + fields: + revision: + label: Revizuire + title: + label: Titlu + placeholder: What's your topic? Be specific. + msg: + empty: Titlul nu poate fi gol. + range: Titlu de până la 150 de caractere + body: + label: Corp + msg: + empty: Corpul mesajului trebuie să conțină text. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Etichete + msg: + empty: Etichetele nu pot fi goale. + answer: + label: Răspuns + msg: + empty: Răspunsul nu poate fi gol. + edit_summary: + label: Editează sumarul + placeholder: >- + Explicați pe scurt modificările (ortografie corectată, gramatică fixă, formatare îmbunătățită) + btn_post_question: Postează întrebarea ta + btn_save_edits: Salvați modificările + answer_question: Răspundeți la propria întrebare + post_question&answer: Postează-ți întrebarea și răspunsul + tag_selector: + add_btn: Adaugă etichetă + create_btn: Creează o etichetă nouă + search_tag: Căutare etichetă + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: Nicio etichetă potrivită + tag_required_text: Etichetă necesară (cel puțin una) + header: + nav: + question: Întrebări + tag: Etichete + user: Utilizatori + badges: Badges + profile: Profil + setting: Setări + logout: Deconectaţi-vă + admin: Administrator + review: Recenzie + bookmark: Semne de carte + moderation: Moderare + search: + placeholder: Caută + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Schimbare + loading: încarcare... + pic_auth_code: + title: Captcha + placeholder: Introdu textul de mai sus + msg: + empty: Captcha nu poate fi gol. + inactive: + first: >- + Ești aproape gata! Am trimis un e-mail de activare la {{mail}}. Te rugăm să urmezi instrucțiunile din e-mail pentru a-ți activa contul. + info: "Dacă nu ajunge, verifică folderul Spam." + another: >- + Ți-am trimis un alt e-mail de activare la {{mail}}. Poate dura câteva minute până ajuns; asiguraţi-vă că verificaţi folderul Spam. + btn_name: Retrimitere link de activare + change_btn_name: Schimbați e-mailul + msg: + empty: Nu poate fi lăsat necompletat. + resend_email: + url_label: Sunteţi sigur că doriţi să retrimiteţi e-mailul de activare? + url_text: De asemenea, puteți da link-ul de activare de mai sus utilizatorului. + login: + login_to_continue: Conectează-te pentru a continua + info_sign: Nu ai un cont? Înregistrează-te + info_login: Ai deja un cont? <1>Autentifică-te + agreements: Prin înregistrare, ești de acord cu <1>politica de confidențialitate și <3>termenii și condițiile de utilizare. + forgot_pass: Ai uitat parola? + name: + label: Nume + msg: + empty: Câmpul Nume trebuie completat. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: E-mail + msg: + empty: Câmpul e-mail nu poate fi gol. + password: + label: Parolă + msg: + empty: Parola nu poate fi goală. + different: Parolele introduse pe ambele părți sunt incompatibile + account_forgot: + page_title: Ati uitat parola + btn_name: Trimite-mi e-mail de recuperare + send_success: >- + Dacă un cont corespunde cu {{mail}}, ar trebui să primiți un e-mail cu instrucțiuni despre cum să resetați parola în scurt timp. + email: + label: E-mail + msg: + empty: Câmpul e-mail nu poate fi gol. + change_email: + btn_cancel: Anulați + btn_update: Actualizare adresă de e-mail + send_success: >- + Dacă un cont corespunde cu {{mail}}, ar trebui să primiți un e-mail cu instrucțiuni despre cum să resetați parola în scurt timp. + email: + label: E-mail nou + msg: + empty: Câmpul e-mail nu poate fi gol. + oauth: + connect: Conectează-te cu {{ auth_name }} + remove: Elimină {{ auth_name }} + oauth_bind_email: + subtitle: Adăugați un e-mail de recuperare la contul dvs. + btn_update: Actualizare adresă de e-mail + email: + label: E-mail + msg: + empty: E-mail-ul nu poate fi gol. + modal_title: E-mail deja existent. + modal_content: Această adresă de e-mail este deja înregistrată. Sigur doriți să vă conectați la contul existent? + modal_cancel: Schimbați e-mailul + modal_confirm: Conectează-te la contul existent + password_reset: + page_title: Resetează parola + btn_name: Resetează-mi parola + reset_success: >- + Ați schimbat cu succes parola; veți fi redirecționat către pagina de conectare. + link_invalid: >- + Ne pare rău, acest link de resetare a parolei nu mai este valabil. Poate că parola este deja resetată? + to_login: Continuă autentificarea în pagină + password: + label: Parolă + msg: + empty: Parola nu poate fi goală. + length: Lungimea trebuie să fie între 8 și 32 + different: Parolele introduse pe ambele părți sunt incompatibile + password_confirm: + label: Confirmă parola nouă + settings: + page_title: Setări + goto_modify: Du-te pentru a modifica + nav: + profile: Profil + notification: Notificări + account: Cont + interface: Interfață + profile: + heading: Profil + btn_name: Salvează + display_name: + label: Nume afișat + msg: Numele afișat nu poate fi gol. + msg_range: Display name must be 2-30 characters in length. + username: + label: Nume de utilizator + caption: Oamenii te pot menționa ca "@utilizator". + msg: Numele de utilizator nu poate fi gol. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Imaginea de profil + gravatar: Gravatar + gravatar_text: Poți schimba imaginea pe + custom: Personalizat + custom_text: Poți să încarci imaginea. + default: Sistem + msg: Te rugăm să încarci un avatar + bio: + label: Despre mine + website: + label: Website + placeholder: "https://exemplu.com" + msg: Format incorect pentru website + location: + label: Locație + placeholder: "Oraş, Ţară" + notification: + heading: Notificări prin e-mail + turn_on: Pornire + inbox: + label: Notificări primite + description: Răspunde la întrebări, comentarii, invitații și multe altele. + all_new_question: + label: Adauga o intrebare noua + description: Primiți notificări despre toate întrebările noi. Până la 50 de întrebări pe săptămână. + all_new_question_for_following_tags: + label: Toate întrebările noi pentru etichetele următoare + description: Primiți notificări despre întrebări noi pentru următoarele etichete. + account: + heading: Cont + change_email_btn: Schimbați e-mailul + change_pass_btn: Schimbați parola + change_email_info: >- + Am trimis un e-mail la acea adresă. Vă rugăm să urmați instrucțiunile de confirmare. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + pass: + label: Parolă actuală + msg: Parola nu poate fi goală. + password_title: Parolă + current_pass: + label: Parola curentă + msg: + empty: Parola curentă nu poate fi goală. + length: Lungimea trebuie să fie între 8 și 32. + different: Cele două parole introduse nu se potrivesc. + new_pass: + label: Parola nouă + pass_confirm: + label: Confirmă parola nouă + interface: + heading: Interfață + lang: + label: Limba interfeței + text: Limba interfeței utilizatorului. Se va schimba atunci când se reîmprospătează pagina. + my_logins: + title: Autentificările mele + label: Autentifică-te sau înregistrează-te pe acest site folosind aceste conturi. + modal_title: Elimină autentificarea + modal_content: Sunteţi sigur că doriţi să eliminaţi această autentificare din contul dumneavoastră? + modal_confirm_btn: Eliminare + remove_success: Eliminată cu succes + toast: + update: actualizare reușită + update_password: Parola schimbata cu succes. + flag_success: Mulțumim pentru marcare. + forbidden_operate_self: Interzis să operezi singur + review: Revizuirea ta va arăta după recenzie. + sent_success: Trimis cu succes + related_question: + title: Related + answers: răspunsuri + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Persoane întrebate + desc: Invită persoane care crezi că știu răspunsul. + invite: Invită să răspundă + add: Adaugă persoane + search: Caută persoane + question_detail: + action: Acţiune + created: Created + Asked: Întrebat + asked: întrebat + update: Modificat + Edited: Edited + edit: editat + commented: commented + Views: Văzute + Follow: Urmărește + Following: Urmăriți + follow_tip: Urmărește această întrebare pentru a primi notificări + answered: răspunse + closed_in: Închis în + show_exist: Arată întrebarea existentă. + useful: Utilă + question_useful: Acest lucru este util și clar + question_un_useful: Nu este clar sau nu este util + question_bookmark: Marchează această întrebare + answer_useful: Este util + answer_un_useful: Nu este util + answers: + title: Răspunsuri + score: Scor + newest: Cele mai noi + oldest: Cel mai vechi + btn_accept: Acceptă + btn_accepted: Acceptă + write_answer: + title: Răspunsul tău + edit_answer: Editează răspunsul meu existent + btn_name: Postează răspunsul tău + add_another_answer: Adaugă un alt răspuns + confirm_title: Continuă să răspunzi + continue: Continuare + confirm_info: >- +

        Sunteţi sigur că doriţi să adăugaţi un alt răspuns?

        Puteţi folosi link-ul de editare pentru a perfecţiona şi îmbunătăţi răspunsul existent, în schimb.

        + empty: Răspunsul nu poate fi gol. + characters: conţinutul trebuie să aibă cel puţin 6 caractere. + tips: + header_1: Îți mulțumim pentru răspuns + li1_1: Asigurați-vă că răspundeți la întrebarea. Furnizați detalii și împărtășiți cercetările dvs. + li1_2: Faceți o copie de rezervă cu referințe sau experiență personală. + header_2: Dar evită... + li2_1: Solicită ajutor, caută clarificări sau răspunsuri la alte răspunsuri. + reopen: + confirm_btn: Redeschide + title: Redeschide această postare + content: Sunteţi sigur că doriţi să redeschideţi? + list: + confirm_btn: List + title: List this post + content: Are you sure you want to list? + unlist: + confirm_btn: Unlist + title: Unlist this post + content: Are you sure you want to unlist? + pin: + title: Fixează această postare + content: Sunteţi sigur că doriţi să fixaţi la nivel global? Acest post va apărea în partea de sus a tuturor listelor de postări. + confirm_btn: Fixează + delete: + title: Șterge această postare + question: >- + Nu recomandăm ștergerea întrebărilor cu răspunsuri deoarece acest lucru privează viitorii cititori de aceste cunoștințe.

        Ștergerea repetată a întrebărilor cu răspuns poate duce la blocarea contului dvs. de a întreba. Sigur doriți să ștergeți? + answer_accepted: >- +

        Nu recomandăm ștergerea răspunsului acceptat deoarece acest lucru privează viitorii cititori de aceste cunoștințe.

        Ștergerea repetată a răspunsurilor acceptate poate duce la blocarea contului dvs. de a răspunde. Sigur doriți să ștergeți? + other: Sunteţi sigur că doriţi să ştergeţi? + tip_answer_deleted: Aceasta postare a fost stearsa + undelete_title: Anulează ștergerea acestei postări + undelete_desc: Sunteți sigur că doriți să adulați ștergerea? + btns: + confirm: Confirmați + cancel: Anulați + edit: Editează + save: Salvează + delete: Ștergeți + undelete: Restabilește + list: List + unlist: Unlist + unlisted: Unlisted + login: Autentifică-te + signup: Înscrieți-vă + logout: Deconectaţi-vă + verify: Verificare + create: Create + approve: Aprobă + reject: Respins + skip: Treci peste + discard_draft: Respingeți draftul + pinned: Fixat + all: Toate + question: Întrebare + answer: Răspuns + comment: Comentariu + refresh: Actualizare + resend: Retrimite + deactivate: Dezactivare + active: Activați + suspend: Suspendați + unsuspend: Anulează suspendare + close: Închide + reopen: Redeschide + ok: OK + light: Luminoasă + dark: Întunecată + system_setting: Setări de sistem + default: Default + reset: Resetează + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignore + submit: Submit + normal: Normal + closed: Closed + deleted: Deleted + deleted_permanently: Deleted permanently + pending: Pending + more: More + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Rezultatele căutării + keywords: Cuvinte cheie + options: Opţiuni + follow: Urmărește + following: Urmăriți + counts: "{{count}} rezultatele" + counts_loading: "... Results" + more: Mai mult + sort_btns: + relevance: Relevanță + newest: Cele mai noi + active: Activ + score: Scor + more: Mai mult + tips: + title: Sfaturi de căutare avansate + tag: "<1>[tag] search with a tag" + user: "<1>utilizator:username căutare de către autor" + answer: "<1>răspunsuri:0 întrebări fără răspuns" + score: "<1>scor:3 postări cu un scor de 3+" + question: "<1>este:question întrebări de căutare" + is_answer: "<1>este:răspuner răspunsuri la căutare" + empty: Nu am putut găsi nimic.
        Încearcă cuvinte cheie diferite sau mai puţin specifice. + share: + name: Distribuiți + copy: Copiază linkul + via: Distribuie postarea prin... + copied: Copiat + facebook: Partajează pe Facebook + twitter: Share to X + cannot_vote_for_self: Nu poți vota pentru propria ta postare. + modal_confirm: + title: Eroare... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Noul tău cont este confirmat; vei fi redirecționat către pagina de pornire. + link: Continuă la pagina principală + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: E-mailul dvs. a fost actualizat. + confirm_new_email_invalid: >- + Ne pare rău, acest link de confirmare nu mai este valabil. Poate că e-mailul dvs. a fost deja modificat? + unsubscribe: + page_title: Dezabonează-te + success_title: Dezabonare cu succes + success_desc: Ați fost eliminat cu succes din această listă de abonați și nu veți mai primi alte e-mailuri de la noi. + link: Modificați setările + question: + following_tags: Etichete urmărite + edit: Editează + save: Salvează + follow_tag_tip: Urmărește etichetele pentru a curăța lista ta de întrebări. + hot_questions: Întrebări importante + all_questions: Toate întrebările + x_questions: "{{ count }} Întrebări" + x_answers: "{{ count }} răspunsuri" + x_posts: "{{ count }} Posts" + questions: Întrebări + answers: Răspunsuri + newest: Cele mai noi + active: Activ + hot: Hot + frequent: Frequent + recommend: Recommend + score: Scor + unanswered: Fără răspuns + modified: modificat + answered: răspunse + asked: întrebat + closed: închise + follow_a_tag: Urmărește o etichetă + more: Mai multe + personal: + overview: Privire de ansamblu + answers: Răspunsuri + answer: răspuns + questions: Întrebări + question: întrebare + bookmarks: Semne de carte + reputation: Reputație + comments: Comentarii + votes: Voturi + badges: Badges + newest: Cele mai noi + score: Scor + edit_profile: Editare profil + visited_x_days: "{{ count }} zile vizitate" + viewed: Văzute + joined: Înscris + comma: "," + last_login: Văzut + about_me: Despre mine + about_me_empty: "// Salut, Lumea !" + top_answers: Top răspunsuri + top_questions: Top Intrebari + stats: Statistici + list_empty: Nici o postare găsită.
        Poate doriţi să selectaţi o filă diferită? + content_empty: No posts found. + accepted: Acceptat + answered: răspunse + asked: întrebat + downvoted: vot negativ + mod_short: MOD + mod_long: Moderatori + x_reputation: reputație + x_votes: voturi primite + x_answers: răspunsuri + x_questions: întrebări + recent_badges: Recent Badges + install: + title: Installation + next: Înainte + done: Finalizat + config_yaml_error: Nu se poate crea fișierul config.yaml. + lang: + label: Vă rugăm să selectați limba + db_type: + label: Motorul Bazei de Date + db_username: + label: Nume de utilizator + placeholder: root + msg: Numele de utilizator nu poate fi gol. + db_password: + label: Parolă + placeholder: root + msg: Parola nu poate fi goală. + db_host: + label: Numele serverului de baze de date + placeholder: "db:3306" + msg: Adresa bazei de date nu poate fi goală. + db_name: + label: Numele bazei de date + placeholder: răspuns + msg: Numele bazei de date nu poate fi gol. + db_file: + label: Fișierul bazei de date + placeholder: /data/answer.db + msg: Fişierul bazei de date nu poate fi gol. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Crează config.yaml + label: Fișierul config.yaml a fost creat. + desc: >- + Puteți crea fișierul <1>config.yaml manual în directorul <1>/var/wwww/xxx/ și inserați următorul text în el. + info: După ce ai făcut asta, apasă butonul "Înainte". + site_information: Informatii site + admin_account: Contul de admin + site_name: + label: Numele site-ului + msg: Numele site-ului nu poate fi gol. + msg_max_length: Numele site-ului trebuie să aibă maximum 30 de caractere lungime. + site_url: + label: URL-ul site-ului + text: Adresa site-ului dvs. + msg: + empty: URL-ul site-ului nu poate fi gol. + incorrect: Format incorect pentru URL-ul site-ului. + max_length: URL-ul site-ului trebuie să aibă maximum 512 caractere lungime. + contact_email: + label: E-mail de contact + text: Adresa de e-mail a persoanei cheie responsabile pentru acest site. + msg: + empty: E-mailul de contact nu poate fi gol. + incorrect: E-mail de contact are un format incorect. + login_required: + label: Privat + switch: Autentificare necesară + text: Numai utilizatorii autentificați pot accesa această comunitate. + admin_name: + label: Nume + msg: Câmpul Nume trebuie completat. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Parolă + text: >- + Veți avea nevoie de această parolă pentru autentificare. Vă rugăm să o păstrați într-o locație sigură. + msg: Parola nu poate fi goală. + msg_min_length: Parola trebuie să aibă cel puțin 8 caractere. + msg_max_length: Parola trebuie să aibă cel puțin 32 caractere. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: E-mail + text: Veţi avea nevoie de acest e-mail pentru a vă autentifica. + msg: + empty: Câmpul e-mail nu poate fi gol. + incorrect: Campul e-mail are formatul incorect. + ready_title: Your site is ready + ready_desc: >- + Dacă te simți vreodată ca și cum ai schimba mai multe setări, vizitează <1>secțiunea de administrare ; găsește-o în meniul site-ului. + good_luck: "Distracție plăcută și noroc!" + warn_title: Atenţie + warn_desc: >- + Fișierul <1>config.yaml există deja. Dacă trebuie să resetați oricare dintre elementele de configurare din acest fișier, vă rugăm să îl ștergeți mai întâi. + install_now: Puteți încerca <1>să instalați acum. + installed: Deja instalat + installed_desc: >- + Se pare că ai instalat deja. Pentru a reinstala vă rugăm să ștergeți mai întâi vechile tabele ale bazei de date. + db_failed: Conexiunea la baza de date a eșuat + db_failed_desc: >- + Acest lucru înseamnă fie că baza de date este în configurația ta <1>. config yaml este incorect sau contactul cu serverul bazei de date nu a putut fi stabilit. Acest lucru ar putea însemna că serverul gazdei nu este în funcțiune. + counts: + views: vizualizări + votes: voturi + answers: răspunsuri + accepted: Acceptat + page_error: + http_error: HTTP - {{ code }} + desc_403: Nu ai permisiunea să accesezi pagina. + desc_404: Din păcate, această pagină nu există. + desc_50X: Serverul a întâmpinat o eroare și nu a putut finaliza cererea. + back_home: Înapoi la pagina principală + page_maintenance: + desc: "Suntem în mentenanță, ne vom întoarce în curând." + nav_menus: + dashboard: Panou de control + contents: Conţinut + questions: Întrebări + answers: Răspunsuri + users: Utilizatori + badges: Badges + flags: Marcaj + settings: Setări + general: General + interface: Interfață + smtp: SMTP + branding: Marcă + legal: Juridic + write: Scrie + terms: Terms + tos: Condiții de utilizare + privacy: Confidențialitate + seo: SEO + customize: Personalizează + themes: Teme + login: Autentifică-te + privileges: Privilegii + plugins: Extensii + installed_plugins: Extensii instalate + apperance: Appearance + website_welcome: Bun venit la {{site_name}} + user_center: + login: Autentifică-te + qrcode_login_tip: Vă rugăm să folosiți {{ agentName }} pentru a scana codul QR și a vă autentifica. + login_failed_email_tip: Autentificare eșuată. Vă rugăm să permiteți acestei aplicații să vă acceseze informațiile de e-mail înainte de a încerca din nou. + badges: + modal: + title: Congratulations + content: You've earned a new badge. + close: Close + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + admin: + admin_header: + title: Administrator + dashboard: + title: Panou de control + welcome: Welcome to Admin! + site_statistics: Statisticile site-ului + questions: "Întrebări:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "Răspunsuri:" + comments: "Comentarii:" + votes: "Voturi:" + users: "Utilizatori:" + flags: "Marcaje:" + reviews: "Reviews:" + site_health: Site health + version: "Versiune:" + https: "HTTPS:" + upload_folder: "Director încărcare:" + run_mode: "Modul de rulare:" + private: Privat + public: Public + smtp: "SMTP:" + timezone: "Fusul orar:" + system_info: Informaţii despre sistem + go_version: "Versiune Go:" + database: "Baza de date:" + database_size: "Dimensiune bază de date:" + storage_used: "Spațiu utilizat:" + uptime: "Timpul de funcționare:" + links: Links + plugins: Pluginuri + github: GitHub + blog: Blog + contact: Contact + forum: Forum + documents: Ducumente + feedback: Feedback + support: Suport + review: Recenzie + config: Configurație + update_to: Actualizare la + latest: Recente + check_failed: Verificarea eșuată + "yes": "Da" + "no": "Nu" + not_allowed: Nu este permis + allowed: Permis + enabled: Activat + disabled: Dezactivat + writable: Inscriptibil + not_writable: Neinscriptibil + flags: + title: Steaguri + pending: În așteptare + completed: Finalizată + flagged: Semnalizat + flagged_type: Marcat {{ type }} + created: Creată + action: Actiune + review: Recenzie + user_role_modal: + title: Schimbă rolul utilizatorului la... + btn_cancel: Anulați + btn_submit: Trimiteți + new_password_modal: + title: Setați parola nouă + form: + fields: + password: + label: Parolă + text: Utilizatorul va fi deconectat și trebuie să se conecteze din nou. + msg: Parola trebuie să aibă o lungime de 8-32 caractere. + btn_cancel: Anulați + btn_submit: Trimiteți + edit_profile_modal: + title: Edit profile + form: + fields: + display_name: + label: Display name + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Invalid Email Address. + edit_success: Edited successfully + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Adaugă un nou utilizator + form: + fields: + users: + label: Adăugare utilizator în bloc + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separați “nume, email, parola” cu virgulă. Un utilizator pe linie. + msg: "Te rugăm să introduci e-mailul utilizatorului, câte unul pe linie." + display_name: + label: Nume afișat + msg: Display name must be 2-30 characters in length. + email: + label: E-mail + msg: E-mail nu este validă. + password: + label: Parolă + msg: Parola trebuie să aibă o lungime de 8-32 caractere. + btn_cancel: Anulați + btn_submit: Trimiteți + users: + title: Utilizatori + name: Nume + email: E-mail + reputation: Reputație + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Stare + role: Rol + action: Acţiune + change: Schimbare + all: Toate + staff: Personal + more: Mai mult + inactive: Inactiv + suspended: Suspendat + deleted: Şters + normal: Normal + Moderator: Moderator + Admin: Administrator + User: Utilizator + filter: + placeholder: "Filtrare după nume, utilizator:id" + set_new_password: Setați parola nouă + edit_profile: Edit profile + change_status: Schimba starea + change_role: Schimbare rol + show_logs: Arată jurnalele + add_user: Adaugă utilizator + deactivate_user: + title: Dezactivare utilizator + content: Un utilizator inactiv trebuie să își revalideze e-mailul. + delete_user: + title: Ștergeți acest utilizator + content: Sunteţi sigur că doriţi să ştergeţi acest utilizator? Acest lucru este permanent! + remove: Eliminaţi acest conţinut + label: Elimină toate întrebările, răspunsurile, comentariile etc. + text: Nu bifați acest lucru dacă doriți să ștergeți doar contul utilizatorului. + suspend_user: + title: Suspendă acest utilizator + content: Un utilizator suspendat nu se poate autentifica. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Întrebări + unlisted: Unlisted + post: Postare + votes: Voturi + answers: Răspunsuri + created: Creată + status: Stare + action: Actiune + change: Schimbare + pending: În așteptare + filter: + placeholder: "Filtrează după titlu, întrebare: id" + answers: + page_title: Răspunsuri + post: Postare + votes: Voturi + created: Creată + status: Stare + action: Acţiune + change: Schimbare + filter: + placeholder: "Filtrează după titlu, întrebare: id" + general: + page_title: General + name: + label: Numele site-ului + msg: Numele site-ului nu poate fi gol. + text: "Numele acestui site, așa cum este folosit în eticheta de titlu." + site_url: + label: URL-ul site-ului + msg: Url-ul site-ului nu poate fi gol. + validate: Introduceți un URL valid. + text: Adresa site-ului dvs. + short_desc: + label: Scurtă descriere a site-ului + msg: Scurtă descriere a site-ului nu poate fi goală. + text: "Scurtă descriere, așa cum este folosit în eticheta titlu pe website." + desc: + label: Descriere site + msg: Descrierea site-ului nu poate fi goală. + text: "Descrie acest site într-o propoziție, așa cum este folosit în tag-ul meta descriere." + contact_email: + label: E-mail de contact + msg: E-mailul de contact nu poate fi gol. + validate: E-mailul de contact nu este valid. + text: Adresa de e-mail a persoanei cheie responsabile pentru acest site. + check_update: + label: Software updates + text: Automatically check for updates + interface: + page_title: Interfață + language: + label: Limba interfeței + msg: Limba interfata nu poate fi goala. + text: Limba interfeței utilizatorului. Se va schimba atunci când se reîmprospătează pagina. + time_zone: + label: Fusul orar + msg: Fusul orar nu poate fi gol. + text: Alege un oraș în același fus orar cu tine. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: De la e-mail + msg: Câmpul e-mail nu poate fi gol. + text: Adresa de e-mail de la care e-mailurile sunt trimise. + from_name: + label: Din numele + msg: Numele nu poate fi gol. + text: Numele de la care sunt trimise e-mailurile. + smtp_host: + label: Gazda SMTP + msg: Gazda SMTP nu poate fi goală. + text: Serverul tau de mail. + encryption: + label: Criptare + msg: Câmpul decriptare nu poate fi gol. + text: Pentru majoritatea serverelor SSL este opțiunea recomandată. + ssl: SSL + tls: TLS + none: Niciuna + smtp_port: + label: Portul SMTP + msg: Portul SMTP trebuie să fie numărul 1 ~ 65535. + text: Portul către serverul de mail. + smtp_username: + label: Utilizatorul SMTP + msg: Numele de utilizator SMTP nu poate fi gol. + smtp_password: + label: Parola SMTP + msg: Parola SMTP nu poate fi goală. + test_email_recipient: + label: Destinatari de e-mail test + text: Furnizați adresa de e-mail care va primi trimiterile de teste. + msg: Destinatarii de e-mail de test sunt invalizi + smtp_authentication: + label: Activare Authenticator + title: Autentificare SMTP + msg: Autentificarea SMTP nu poate fi goală. + "yes": "Da" + "no": "Nu" + branding: + page_title: Marcă + logo: + label: Logo + msg: Logo-ul nu poate fi gol. + text: Imaginea logo-ului din stânga sus a site-ului dvs. Utilizaţi o imagine dreptunghiulară largă cu o înălţime de 56 şi un raport de aspect mai mare de 3:1. Dacă nu se completează, textul pentru titlul site-ului va fi afișat. + mobile_logo: + label: Logo mobil + text: Logo-ul folosit pe versiunea mobila a site-ului dvs. Utilizați o imagine dreptunghiulară largă cu o înălțime de 56. Dacă nu o completați, va fi utilizată imaginea din setarea "logo". + square_icon: + label: Pictogramă pătrată + msg: Pictograma pătrată nu poate fi goală. + text: Imaginea folosită ca bază pentru pictogramele de metadate. Ar trebui să fie, în mod ideal, mai mare de 512x512. + favicon: + label: Favicon + text: O pictogramă favorită pentru site-ul dvs. Pentru a lucra corect peste un CDN trebuie să fie un png. Va fi redimensionată la 32x32. Dacă este lăsat necompletat, va fi folosită "iconiță pătrată". + legal: + page_title: Juridic + terms_of_service: + label: Termeni și condiții + text: "Puteți adăuga aici termeni de conținut pentru serviciu. Dacă aveți deja un document găzduit în altă parte, furnizați URL-ul complet aici." + privacy_policy: + label: Politică de confidențialitate + text: "Puteți adăuga aici termeni politicii de confidențialitate. Dacă aveți deja un document găzduit în altă parte, furnizați URL-ul complet aici." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Scrie + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Fiecare utilizator poate scrie doar câte un răspuns pentru fiecare întrebare + text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Etichete recomandate + text: "Recommend tags will show in the dropdown list by default." + msg: + contain_reserved: "recommended tags cannot contain reserved tags" + required_tag: + title: Set required tags + label: Set “Recommend tags” as required tags + text: "Fiecare întrebare nouă trebuie să aibă cel puțin o etichetă recomandată." + reserved_tags: + label: Etichete rezervate + text: "Reserved tags can only be used by moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: SEO + permalink: + label: Legătură permanenta + text: Structurile URL personalizate pot îmbunătăți capacitatea de utilizare și compatibilitatea link-urilor tale. + robots: + label: robots.txt + text: Acest lucru va suprascrie permanent orice setări ale site-ului. + themes: + page_title: Teme + themes: + label: Teme + text: Selectaţi o temă existentă. + color_scheme: + label: Paletă de culori + navbar_style: + label: Navbar background style + primary_color: + label: Culoare primară + text: Modifică culorile folosite de temele tale + css_and_html: + page_title: CSS și HTML + custom_css: + label: CSS personalizat + text: > + + head: + label: Cap + text: > + + header: + label: Antet + text: > + + footer: + label: Subsol + text: Se va insera înainte de </body>. + sidebar: + label: Bară laterală + text: Acesta va fi inserat în bara laterală. + login: + page_title: Autentifică-te + membership: + title: Calitatea de membru + label: Permite înregistrări noi + text: Dezactivați pentru a împiedica pe oricine să creeze un cont nou. + email_registration: + title: Înregistrare e-mail + label: Permite înregistrări noi + text: Dezactivați pentru a preveni crearea unui cont nou prin e-mail. + allowed_email_domains: + title: Domenii de e-mail permise + text: Domeniile de e-mail cu care utilizatorii trebuie să înregistreze conturi. Un domeniu pe linie. Se ignoră atunci când este gol. + private: + title: Privat + label: Autentificare necesară + text: Numai utilizatorii autentificați pot accesa această comunitate. + password_login: + title: Parola de login + label: Permiteți autentificarea prin e-mail și parolă + text: "AVERTISMENT: Dacă opriți, este posibil să nu vă puteți conecta dacă nu ați configurat anterior o altă metodă de autentificare." + installed_plugins: + title: Extensii instalate + plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + filter: + all: Toate + active: Activ + inactive: Inactiv + outdated: Învechit + plugins: + label: Extensii + text: Selectați un plugin existent. + name: Nume + version: Versiune + status: Stare + action: Acţiune + deactivate: Dezactivare + activate: Activare + settings: Setări + settings_users: + title: Utilizatori + avatar: + label: Avatarul implicit + text: Pentru utilizatorii fără un avatar personalizat propriu. + gravatar_base_url: + label: URL de bază Gravatar + text: URL-ul bazei API a furnizorului de Gravatar. Ignorat când este gol. + profile_editable: + title: Profil editabil + allow_update_display_name: + label: Permite utilizatorilor să își schimbe numele afișat + allow_update_username: + label: Permite utilizatorilor să își schimbe numele de utilizator + allow_update_avatar: + label: Permite utilizatorilor să își schimbe imaginea de profil + allow_update_bio: + label: Permite utilizatorilor să își schimbe propriul lor despre mine + allow_update_website: + label: Permite utilizatorilor să îşi schimbe website-ul + allow_update_location: + label: Permite utilizatorilor să își schimbe locația + privilege: + title: Privilegii + level: + label: Nivel necesar de reputație + text: Alegeți reputația necesară pentru privilegii + msg: + should_be_number: the input should be number + number_larger_1: number should be equal or larger than 1 + badges: + action: Action + active: Active + activate: Activate + all: All + awards: Awards + deactivate: Deactivate + filter: + placeholder: Filter by name, badge:id + group: Group + inactive: Inactive + name: Name + show_logs: Show logs + status: Status + title: Badges + form: + optional: (opțional) + empty: nu poate fi lăsat necompletat + invalid: nu este valid + btn_submit: Salvează + not_found_props: "Proprietatea solicitată {{ key }} nu a fost găsită." + select: Selectează + page_review: + review: Recenzie + proposed: propus + question_edit: Editare întrebări + answer_edit: Editările răspunsului + tag_edit: Editare etichetă + edit_summary: Editează sumarul + edit_question: Editați întrebarea + edit_answer: Editați răspunsul + edit_tag: Editare etichetă + empty: Nu au mai rămas sarcini de evaluare. + approve_revision_tip: Do you approve this revision? + approve_flag_tip: Do you approve this flag? + approve_post_tip: Do you approve this post? + approve_user_tip: Do you approve this user? + suggest_edits: Suggested edits + flag_post: Flag post + flag_user: Flag user + queued_post: Queued post + queued_user: Queued user + filter_label: Tip + reputation: reputation + flag_post_type: Acest post a fost marcat de {{ type }}. + flag_user_type: Flagged this user as {{ type }}. + edit_post: Editează postarea + list_post: Listează postarea + unlist_post: Unlist post + timeline: + undeleted: restabilește + deleted: şterse + downvote: vot negativ + upvote: vot pozitiv + accept: acceptat + cancelled: anulat + commented: comentat + rollback: revenire + edited: editat + answered: răspunse + asked: întrebat + closed: închise + reopened: redeschise + created: creat + pin: fixat + unpin: nefixat + show: listă + hide: nelistat + title: "Istoric pentru" + tag_title: "Cronologie pentru" + show_votes: "Afișare voturi" + n_or_a: N/A + title_for_question: "Cronologie pentru" + title_for_answer: "Calendarul răspunsului la {{ title }} cu {{ author }}" + title_for_tag: "Cronologie pentru etichetă" + datetime: Dată și oră + type: Tip + by: De către + comment: Comentariu + no_data: "Nu a fost găsit nimic." + users: + title: Utilizatori + users_with_the_most_reputation: Utilizatori cu cele mai mari scoruri ale reputaţiei în această săptămână + users_with_the_most_vote: Utilizatorii care au votat cel mai mult săptămâna aceasta + staffs: Personalul acestei comunități + reputation: reputație + votes: voturi + prompt: + leave_page: Sunteți sigur că doriți să ieșiți din pagina asta? + changes_not_save: Modificările nu pot fi salvate. + draft: + discard_confirm: Ești sigur că vrei să renunți la ciornă? + messages: + post_deleted: Această postare a fost ștearsă. + post_cancel_deleted: This post has been undeleted. + post_pin: Această postare a fost fixată. + post_unpin: Această postare nu a fost fixată. + post_hide_list: Această postare a fost ascunsă din listă. + post_show_list: Această postare a fost afișată în listă. + post_reopen: Această postare a fost redeschisă. + post_list: This post has been listed. + post_unlist: This post has been unlisted. + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/ru_RU.yaml b/data/i18n/ru_RU.yaml new file mode 100644 index 000000000..e181656f4 --- /dev/null +++ b/data/i18n/ru_RU.yaml @@ -0,0 +1,2360 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Выполнено. + unknown: + other: Неизвестная ошибка. + request_format_error: + other: Формат файла не корректен. + unauthorized_error: + other: Авторизация не выполнена. + database_error: + other: Ошибка сервера данных. + forbidden_error: + other: Доступ запрещен. + duplicate_request_error: + other: Дублирующая отправка. + action: + report: + other: Пожаловаться + edit: + other: Редактировать + delete: + other: Удалить + close: + other: Закрыть + reopen: + other: Открыть + forbidden_error: + other: Доступ запрещен. + pin: + other: Закрепить + hide: + other: Убрать + unpin: + other: Открепить + show: + other: Список + invite_someone_to_answer: + other: Редактировать + undelete: + other: Отменить удаление + merge: + other: Merge + role: + name: + user: + other: Пользователь + admin: + other: Администратор + moderator: + other: Модератор + description: + user: + other: По умолчанию, без специального доступа. + admin: + other: Имейте все полномочия для доступа к сайту. + moderator: + other: Имеет доступ ко всем сообщениям, кроме настроек администратора. + privilege: + level_1: + description: + other: Уровень 1 (для приватной команды, группы требуется наименьшая репутация) + level_2: + description: + other: Уровень 2 (для стартапа достаточен низкий уровень репутации) + level_3: + description: + other: Уровень 3 (для зрелого сообщества требуется высокая репутация) + level_custom: + description: + other: Настраиваемый уровень + rank_question_add_label: + other: Задать вопрос + rank_answer_add_label: + other: Написать ответ + rank_comment_add_label: + other: Написать комментарий + rank_report_add_label: + other: Пожаловаться + rank_comment_vote_up_label: + other: Полезный комментарий + rank_link_url_limit_label: + other: Опубликовать более 2 ссылок за раз + rank_question_vote_up_label: + other: Полезный вопрос + rank_answer_vote_up_label: + other: Полезный ответ + rank_question_vote_down_label: + other: Бесполезный вопрос + rank_answer_vote_down_label: + other: Бесполезный ответ + rank_invite_someone_to_answer_label: + other: Пригласить кого-нибудь ответить + rank_tag_add_label: + other: Новый тег + rank_tag_edit_label: + other: Редактировать описание тега (требуется проверка) + rank_question_edit_label: + other: Редактировать вопрос другого пользователя (требуется проверка) + rank_answer_edit_label: + other: Редактировать ответ другого пользователя (требуется проверка) + rank_question_edit_without_review_label: + other: Редактировать вопрос другого пользователя без проверки + rank_answer_edit_without_review_label: + other: Редактировать ответ другого пользователя без проверки + rank_question_audit_label: + other: Проверить изменения вопроса + rank_answer_audit_label: + other: Проверить изменения ответа + rank_tag_audit_label: + other: Проверить изменения тегов + rank_tag_edit_without_review_label: + other: Редактировать описание тега без проверки + rank_tag_synonym_label: + other: Управлять синонимами тегов + email: + other: Эл. почта + e_mail: + other: Почта + password: + other: Пароль + pass: + other: Пароль + old_pass: + other: Current password + original_text: + other: Это сообщение + email_or_password_wrong_error: + other: Неверное имя пользователя или пароль. + error: + common: + invalid_url: + other: Неверная URL. + status_invalid: + other: Неверный статус. + password: + space_invalid: + other: Пароль не должен содержать пробелы. + admin: + cannot_update_their_password: + other: Вы не можете изменить свой пароль. + cannot_edit_their_profile: + other: Вы не можете изменять свой профиль. + cannot_modify_self_status: + other: Вы не можете изменить свой статус. + email_or_password_wrong: + other: Неверное имя пользователя или пароль. + answer: + not_found: + other: Ответ не найден. + cannot_deleted: + other: Недостаточно прав для удаления. + cannot_update: + other: Нет прав для обновления. + question_closed_cannot_add: + other: Вопросы закрыты и не могут быть добавлены. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Комментарий не может редактироваться. + not_found: + other: Комментарий не найден. + cannot_edit_after_deadline: + other: Невозможно редактировать комментарий из-за того, что он был создан слишком давно. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: Адрес электронной почты уже существует. + need_to_be_verified: + other: Адрес электронной почты должен быть подтвержден. + verify_url_expired: + other: Срок действия подтверждённого адреса электронной почты истек, пожалуйста, отправьте письмо повторно. + illegal_email_domain_error: + other: Невозможно использовать email с этим доменом. Пожалуйста, используйте другой. + lang: + not_found: + other: Языковой файл не найден. + object: + captcha_verification_failed: + other: Captcha введена неверно. + disallow_follow: + other: Вы не можете подписаться. + disallow_vote: + other: Вы не можете голосовать. + disallow_vote_your_self: + other: Вы не можете голосовать за собственный отзыв. + not_found: + other: Объект не найден. + verification_failed: + other: Проверка не удалась. + email_or_password_incorrect: + other: Email или пароль не совпадают. + old_password_verification_failed: + other: Не удалось подтвердить старый пароль + new_password_same_as_previous_setting: + other: Пароль не может быть таким же как прежний. + already_deleted: + other: Этот пост был удален. + meta: + object_not_found: + other: Объект мета не найден + question: + already_deleted: + other: Этот пост был удалён. + under_review: + other: Ваш пост ожидает проверки. Он станет видимым после одобрения. + not_found: + other: Вопрос не найден. + cannot_deleted: + other: Недостаточно прав для удаления. + cannot_close: + other: Нет разрешения на закрытие. + cannot_update: + other: Нет разрешения на обновление. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Ранг репутации не соответствует условию. + vote_fail_to_meet_the_condition: + other: Спасибо за отзыв. Вам нужно как минимум {{.Rank}} репутация для голосования. + no_enough_rank_to_operate: + other: Для этого вам нужна репутация {{.Rank}}. + report: + handle_failed: + other: Не удалось обработать отчет. + not_found: + other: Отчет не найден. + tag: + already_exist: + other: Тег уже существует. + not_found: + other: Тег не найден. + recommend_tag_not_found: + other: Рекомендуемый тег не существует. + recommend_tag_enter: + other: Пожалуйста, введите хотя бы один тег. + not_contain_synonym_tags: + other: Не должно содержать теги синонимы. + cannot_update: + other: Нет прав для обновления. + is_used_cannot_delete: + other: Вы не можете удалить метку, которая используется. + cannot_set_synonym_as_itself: + other: Вы не можете установить синоним текущего тега. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: Поле отправителя не может содержать email адрес. + theme: + not_found: + other: Тема не найдена. + revision: + review_underway: + other: В настоящее время не удается редактировать версию, в очереди на проверку. + no_permission: + other: Разрешения на пересмотр нет. + user: + external_login_missing_user_id: + other: Сторонняя платформа не предоставляет уникальный идентификатор пользователя, поэтому вы не можете войти в систему, пожалуйста, свяжитесь с администратором веб-сайта. + external_login_unbinding_forbidden: + other: Пожалуйста, установите пароль для входа в свою учетную запись, прежде чем удалять этот логин. + email_or_password_wrong: + other: + other: Почта и пароль введены неправильно. + not_found: + other: Пользователь не найден. + suspended: + other: Пользователь был заблокирован. + username_invalid: + other: Недопустимое имя пользователя. + username_duplicate: + other: Имя пользователя уже используется. + set_avatar: + other: Не удалось установить аватар. + cannot_update_your_role: + other: Вы не можете изменить свою роль. + not_allowed_registration: + other: В данный момент регистрация на сайте выключена. + not_allowed_login_via_password: + other: В настоящее время вход на сайт по паролю отключен. + access_denied: + other: Доступ запрещен + page_access_denied: + other: У вас нет доступа к этой странице. + add_bulk_users_format_error: + other: "Ошибка формата {{.Field}} рядом с '{{.Content}}' в строке {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "Количество пользователей, которое Вы добавляете, должно быть в промежутке от 1 до {{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Не удалось прочитать конфигурацию + database: + connection_failed: + other: Ошибка подключения к базе данных + create_table_failed: + other: Не удалось создать таблицу + install: + create_config_failed: + other: Не удалось создать файл config.yaml. + upload: + unsupported_file_format: + other: Неподдерживаемый формат файла. + site_info: + config_not_found: + other: Конфигурация сайта не найдена. + badge: + object_not_found: + other: Объект бейджа не найден + reason: + spam: + name: + other: Спам + desc: + other: Этот пост является рекламой или вандализмом. Он не полезен и не имеет отношения к текущей теме. + rude_or_abusive: + name: + other: Грубость или оскорбления + desc: + other: "Человек может посчитать такое содержимое неподходящим для уважительной беседы." + a_duplicate: + name: + other: дубликат + desc: + other: Этот вопрос уже был задан, и на него уже был получен ответ. + placeholder: + other: Введите существующую ссылку на вопрос + not_a_answer: + name: + other: это не ответ + desc: + other: "Это сообщение было опубликовано в качестве ответа, но оно не пытается ответить на вопрос. Возможно, оно должно быть отредактировано, дополнено, быть другим вопросом или удалено навсегда." + no_longer_needed: + name: + other: Не актуально + desc: + other: Этот комментарий устарел, носит разговорный характер или не имеет отношения к данному сообщению. + something: + name: + other: Прочее + desc: + other: Этот пост требует внимания администрации по другой причине, не перечисленной выше. + placeholder: + other: Уточните, что именно Вас беспокоит + community_specific: + name: + other: специфическая для сообщества причина + desc: + other: Этот вопрос не соответствует рекомендациям сообщества. + not_clarity: + name: + other: нуждается в деталях или ясности + desc: + other: В настоящее время этот вопрос включает в себя несколько вопросов в одном. Он должен быть сосредоточен только на одной проблеме. + looks_ok: + name: + other: выглядит нормально + desc: + other: Этот пост хороший и достойного качества. + needs_edit: + name: + other: нуждается в редактировании, и я сделал это + desc: + other: Устраните проблемы с этим сообщением самостоятельно. + needs_close: + name: + other: требует закрытия + desc: + other: На закрытый вопрос нельзя ответить, но все равно можно редактировать, голосовать и комментировать. + needs_delete: + name: + other: требует удаления + desc: + other: Этот пост будет удален. + question: + close: + duplicate: + name: + other: спам + desc: + other: Этот вопрос был задан ранее и уже имеет ответ. + guideline: + name: + other: специфическая для сообщества причина + desc: + other: Этот вопрос не соответствует рекомендациям сообщества. + multiple: + name: + other: нуждается в деталях или ясности + desc: + other: В настоящее время этот вопрос включает в себя несколько вопросов в одном. Он должен быть сосредоточен только на одной проблеме. + other: + name: + other: прочее + desc: + other: Для этого поста требуется другая причина, не указанная выше. + operation_type: + asked: + other: вопросы + answered: + other: отвеченные + modified: + other: измененные + deleted_title: + other: Удаленные вопросы + questions_title: + other: Вопросы + tag: + tags_title: + other: Теги + no_description: + other: Тег не имеет описания. + notification: + action: + update_question: + other: обновленные вопросы + answer_the_question: + other: отвеченные вопросы + update_answer: + other: обновленные ответы + accept_answer: + other: принятые ответы + comment_question: + other: Прокомментированные ответы + comment_answer: + other: прокоментированные ответы + reply_to_you: + other: отвеченные вам + mention_you: + other: с упоминанием вас + your_question_is_closed: + other: Ваш вопрос был закрыт + your_question_was_deleted: + other: Ваш вопрос был удален + your_answer_was_deleted: + other: Ваш ответ был удален + your_comment_was_deleted: + other: Ваш комментарий был удален + up_voted_question: + other: поддержанный вопрос + down_voted_question: + other: неподдержанный вопрос + up_voted_answer: + other: ответ "за" + down_voted_answer: + other: ответ "против" + up_voted_comment: + other: поддержанный комментарий + invited_you_to_answer: + other: пригласил вас ответить + earned_badge: + other: Вы заработали значок "{{.BadgeName}}" + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Подтвердите новый адрес электронной почты" + body: + other: "Подтвердите свой новый адрес электронной почты для {{.SiteName}}, перейдя по следующей ссылке:
        {{.ChangeEmailUrl}}

        Если вы не запрашивали это изменение, пожалуйста, проигнорируйте это электронное письмо.

        -
        Примечание: Данное сообщение является автоматическим, отвечать на него не нужно." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} ответил на ваш вопрос" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nОткрыть {{.SiteName}}

        \n\n--
        \nПримечание: Данное сообщение является автоматическим, отвечать на него не нужно.

        \n\nОтписаться." + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} приглашает вас в Answer" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Я думаю, что вы можете знать ответ.

        \nОткрыть {{.SiteName}}

        \n\n--
        \nПримечание: Данное сообщение является автоматическим, отвечать на него не нужно.

        \n\nОтписаться" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} прокомментировал под вашей публикацией" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nОткрыть {{.SiteName}}

        \n\n--
        \nПримечание: Данное сообщение является автоматическим, отвечать на него не нужно.

        \n\nОтписаться" + new_question: + title: + other: "[{{.SiteName}}] Новый вопрос: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Пароль сброшен" + body: + other: "Кто-то попросил сбросить ваш пароль на {{.SiteName}}.

        \n\nЕсли это не вы, вы можете проигнорировать это письмо.

        \n\nПерейдите по следующей ссылке, чтобы выбрать новый пароль:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nПримечание: Данное сообщение является автоматическим, отвечать на него не нужно." + register: + title: + other: "[{{.SiteName}}] Подтвердите Ваш новый аккаунт" + body: + other: "Добро пожаловать в {{.SiteName}}!

        \n\nПерейдите по следующей ссылке для подтверждения и активации вашей новой учетной записи:
        \n{{.RegisterUrl}}

        \n\nЕсли ссылка выше не нажата, попробуйте скопировать и вставить её в адресную строку вашего браузера.\n

        \n\n--
        \nПримечание: Данное сообщение является автоматическим, отвечать на него не нужно." + test: + title: + other: "[{{.SiteName}}] Проверочное электронное письмо" + body: + other: "Это тестовое сообщение.\n

        \n\n--
        \nПримечание: Данное сообщение является автоматическим, отвечать на него не нужно." + action_activity_type: + upvote: + other: проголосовать за + upvoted: + other: проголосовано за + downvote: + other: бесполезный + downvoted: + other: проголосовано против + accept: + other: принять + accepted: + other: принято + edit: + other: редактировать + review: + queued_post: + other: Задан вопрос + flagged_post: + other: Отмеченный пост + suggested_post_edit: + other: Предложенные исправления + reaction: + tooltip: + other: "{{ .Names }} и {{ .Count }} еще..." + badge: + default_badges: + autobiographer: + name: + other: Автобиограф + desc: + other: Заполнена информация об профиле. + certified: + name: + other: Сертифицированный + desc: + other: Завершил наше новое руководство пользователя. + editor: + name: + other: Редактор + desc: + other: Впервые отредактировать сообщение + first_flag: + name: + other: Первый флаг + desc: + other: Впервые проставить флаг в сообщения + first_upvote: + name: + other: Первый голос + desc: + other: Впервые добавить голос в сообщении. + first_link: + name: + other: First Link + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: First Share + desc: + other: First shared a post. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Оставить 5 комментариев. + new_user_of_the_month: + name: + other: New User of the Month + desc: + other: Outstanding contributions in their first month. + read_guidelines: + name: + other: Read Guidelines + desc: + other: Прочтите [правила сообщества]. + reader: + name: + other: Читатель + desc: + other: Прочитать каждый ответ в разделе с более чем 10 ответами. + welcome: + name: + other: Добро пожаловать + desc: + other: Получен голос «за». + nice_share: + name: + other: Неплохо поделился + desc: + other: Shared a post with 25 unique visitors. + good_share: + name: + other: Good Share + desc: + other: Shared a post with 300 unique visitors. + great_share: + name: + other: Great Share + desc: + other: Shared a post with 1000 unique visitors. + out_of_love: + name: + other: Out of Love + desc: + other: Used 50 up votes in a day. + higher_love: + name: + other: Higher Love + desc: + other: Used 50 up votes in a day 5 times. + crazy_in_love: + name: + other: Crazy in Love + desc: + other: Used 50 up votes in a day 20 times. + promoter: + name: + other: Promoter + desc: + other: Invited a user. + campaigner: + name: + other: Campaigner + desc: + other: Invited 3 basic users. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: Спасибо + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Активный участник на год, опубликовал по крайней мере один раз. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: 'Форматирование:' + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Назад + next: Следующий + page_title: + question: Вопрос + questions: Вопросы + tag: Тэг + tags: Теги + tag_wiki: wiki тэг + create_tag: Создать тег + edit_tag: Изменить тег + ask_a_question: Create Question + edit_question: Редактировать вопрос + edit_answer: Редактировать ответ + search: Поиск + posts_containing: Посты содержащие + settings: Настройки + notifications: Уведомления + login: Вход + sign_up: Регистрация + account_recovery: Восстановление аккаунта + account_activation: Активация учётной записи + confirm_email: Подтвердить адрес электронной почты + account_suspended: Аккаунт заблокирован + admin: Управление + change_email: Изменить Email + install: Установка ответа + upgrade: Обновить ответ + maintenance: Обслуживание сайта + users: Пользователи + oauth_callback: Идет обработка + http_404: Ошибка HTTP 404 + http_50X: Ошибка HTTP 500 + http_403: Ошибка HTTP 403 + logout: Выйти + posts: Posts + notifications: + title: Уведомления + inbox: Входящие + achievement: Достижения + new_alerts: Новые оповещения + all_read: Отметить всё как прочитанное + show_more: Показать еще + someone: Кто-то + inbox_type: + all: Все + posts: Посты + invites: Приглашения + votes: Голоса + answer: Ответ + question: Вопрос + badge_award: Значок + suspended: + title: Ваш аккаунт заблокирован + until_time: "Ваша учетная запись была заблокирована до {{ time }}." + forever: Этот пользователь был навсегда заблокирован. + end: Вы не соответствуете правилам сообщества. + contact_us: Связаться с нами + editor: + blockquote: + text: Цитата + bold: + text: Сильный + chart: + text: Диаграмма + flow_chart: Блок-схема + sequence_diagram: Диаграмма последовательности + class_diagram: Диаграмма классов + state_diagram: Диаграмма состояний + entity_relationship_diagram: Диаграмма связей сущностей + user_defined_diagram: Пользовательская диаграмма + gantt_chart: Диаграмма Гантта + pie_chart: Круговая диаграмма + code: + text: Фрагмент кода + add_code: Добавить пример кода + form: + fields: + code: + label: Код + msg: + empty: Код не может быть пустым. + language: + label: Язык + placeholder: Автоматический выбор + btn_cancel: Отменить + btn_confirm: Добавить + formula: + text: Формула + options: + inline: Встроенная формула + block: Блочная формула + heading: + text: Заголовок + options: + h1: Заголовок 1 + h2: Заголовок 2 + h3: Заголовок 3 + h4: Заголовок 4 + h5: Заголовок 5 + h6: Заголовок 6 + help: + text: Помощь + hr: + text: Горизонтальная линия + image: + text: Изображение + add_image: Добавить изображение + tab_image: Загрузить изображение + form_image: + fields: + file: + label: Файл изображения + btn: Выбрать изображение + msg: + empty: Файл не может быть пустым. + only_image: Разрешены только изображения. + max_size: Размер файла не может превышать {{size}} МБ. + desc: + label: Описание + tab_url: URL изображения + form_url: + fields: + url: + label: URL изображения + msg: + empty: URL изображения не может быть пустым. + name: + label: Описание + btn_cancel: Отменить + btn_confirm: Добавь + uploading: Загрузка + indent: + text: Абзац + outdent: + text: Уменьшить отступ + italic: + text: Курсив + link: + text: Гиперссылка + add_link: Вставить гиперссылку + form: + fields: + url: + label: URL-адрес + msg: + empty: URL не может быть пустым. + name: + label: Описание + btn_cancel: Отменить + btn_confirm: Добавить + ordered_list: + text: Нумерованный список + unordered_list: + text: Маркированный список + table: + text: Таблица + heading: Заголовок + cell: Ячейка + file: + text: Прикрепить файлы + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: Я закрываю этот пост как... + btn_cancel: Отменить + btn_submit: Сохранить + remark: + empty: Не может быть пустым. + msg: + empty: Пожалуйста, выбери причину. + report_modal: + flag_title: 'Причина жалобы:' + close_title: Я закрываю этот пост как... + review_question_title: Проверить вопрос + review_answer_title: Проверить ответ + review_comment_title: Просмотр комментариев + btn_cancel: Отмена + btn_submit: Сохранить + remark: + empty: Не может быть пустым. + msg: + empty: Пожалуйста, выбери причину. + not_a_url: Недопустимый формат URL. + url_not_match: URL адрес не соответствует текущему веб-сайту. + tag_modal: + title: Новый тег + form: + fields: + display_name: + label: Отображаемое имя + msg: + empty: Отображаемое название не может быть пустым. + range: Отображаемое имя до 35 символов. + slug_name: + label: URL-адрес тега + desc: URL-адрес тега длиной до 35 символов. + msg: + empty: URL slug не может быть пустым. + range: URL slug до 35 символов. + character: URL slug содержит недопустимый набор символов. + desc: + label: Описание + revision: + label: Версия + edit_summary: + label: Отредактировать сводку + placeholder: >- + Коротко опишите изменения (орфография, грамматики, улучшение формата) + btn_cancel: Отмена + btn_submit: Сохрнаить + btn_post: Создать новый тег + tag_info: + created_at: Создано + edited_at: Отредактировано + history: История + synonyms: + title: Синонимы + text: Следующие теги будут переназначены на + empty: Синонимы не найдены. + btn_add: Добавить синоним + btn_edit: Редактировать + btn_save: Сохранить + synonyms_text: Следующие теги будут переназначены на + delete: + title: Удалить этот тег + tip_with_posts: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + tip_with_synonyms: >- +

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        + tip: Вы уверены, что хотите удалить? + close: Закрыть + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Изменить тег + default_reason: Правка тега + default_first_reason: Добавить метку + btn_save_edits: Сохранить изменения + btn_cancel: Отмена + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: сейчас + x_seconds_ago: "{{count}}с назад" + x_minutes_ago: "{{count}}м назад" + x_hours_ago: "{{count}}ч назад" + hour: часы + day: дней + hours: часов + days: дней + month: month + months: months + year: year + reaction: + heart: сердечко + smile: smile + frown: frown + btn_label: добавить или удалить реакции + undo_emoji: отменить реакцию {{ emoji }} + react_emoji: react with {{ emoji }} + unreact_emoji: unreact with {{ emoji }} + comment: + btn_add_comment: Добавить комментарий + reply_to: Ответить на + btn_reply: Ответить + btn_edit: Редактирование + btn_delete: Удалить + btn_flag: Пожаловаться + btn_save_edits: Сохранить изменения + btn_cancel: Отменить + show_more: "Еще {{count}} комментарий" + tip_question: >- + Воспользуйтесь комментариями, чтобы запросить больше информации или предложить улучшения. Не отвечайте на вопросы в комментариях. + tip_answer: >- + Используйте комментарии для ответа другим пользователям или уведомления об изменениях. Если вы добавляете новую информацию, редактируйте ваше сообщение вместо комментариев. + tip_vote: Это добавляет кое-что полезное к сообщению + edit_answer: + title: Редактировать ответ + default_reason: Редактировать ответ + default_first_reason: Добавить ответ + form: + fields: + revision: + label: Пересмотр + answer: + label: Ответ + feedback: + characters: длина пароля должна составлять не менее 6 символов. + edit_summary: + label: Изменить краткое описание + placeholder: >- + Кратко опишите вносимые изменения (исправлена орфография, исправлена грамматика, улучшено форматирование) + btn_save_edits: Сохранить изменения + btn_cancel: Отменить + tags: + title: Теги + sort_buttons: + popular: Популярное + name: Имя + newest: Последние + button_follow: Подписаться + button_following: Подписки + tag_label: вопросы + search_placeholder: Фильтр по названию тега + no_desc: Тег не имеет описания. + more: Подробнее + wiki: Wiki + ask: + title: Create Question + edit_title: Редактировать вопрос + default_reason: Редактировать вопрос + default_first_reason: Create question + similar_questions: Похожие вопросы + form: + fields: + revision: + label: Версия + title: + label: Заголовок + placeholder: What's your topic? Be specific. + msg: + empty: Заголовок не может быть пустым. + range: Заголовок должен быть меньше 150 символов + body: + label: 'Вопрос:' + msg: + empty: Вопрос не может быть пустым. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Теги + msg: + empty: Теги не могут быть пустыми. + answer: + label: Ответ + msg: + empty: Ответ не может быть пустым. + edit_summary: + label: Изменить краткое описание + placeholder: >- + Кратко опишите вносимые изменения (исправлена орфография, исправлена грамматика, улучшено форматирование) + btn_post_question: Задать вопрос + btn_save_edits: Сохранить изменения + answer_question: Ответить на свой собственный вопрос + post_question&answer: Опубликуйте свой вопрос и ответ + tag_selector: + add_btn: Тег + create_btn: новый тег + search_tag: Поиск тега + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: Нет соответствующих тэгов + tag_required_text: Обязательный тег (хотя бы один) + header: + nav: + question: Вопросы + tag: Теги + user: Пользователи + badges: Значки + profile: Профиль + setting: Настройки + logout: Выйти + admin: Управление + review: Рецензия + bookmark: Закладки + moderation: Модерирование + search: + placeholder: Поиск + footer: + build_on: >- + Работает на <1> Apache Answer - программном обеспечении с открытым исходным кодом, которое поддерживает сообщества вопросов и ответов.
        Сделано с любовью © {{cc}}. + upload_img: + name: Изменить + loading: загрузка... + pic_auth_code: + title: Капча + placeholder: Введите текст выше + msg: + empty: Капча не может быть пустой. + inactive: + first: >- + Вы почти закончили! Мы отправили письмо с активацией на адрес {{mail}}. Пожалуйста, следуйте инструкциям в письме, чтобы активировать свою учетную запись. + info: "Если оно не пришло, проверьте свою папку со спамом." + another: >- + Мы отправили вам еще одно электронное письмо с активацией по адресу {{mail}}. Его получение может занять несколько минут; обязательно проверьте папку со спамом. + btn_name: Повторно отправить письмо с активацией + change_btn_name: Изменить email + msg: + empty: Не может быть пустым. + resend_email: + url_label: Вы уверены, что хотите повторно отправить письмо с активацией? + url_text: Вы также можете предоставить пользователю ссылку для активации выше. + login: + login_to_continue: Войдите, чтобы продолжить + info_sign: У вас нет аккаунта? <1>Зарегистрируйтесь + info_login: Уже есть аккаунт? <1>Войти + agreements: Регистрируясь, вы соглашаетесь с <1>политикой конфиденциальности и <3>условиями обслуживания. + forgot_pass: Забыли пароль? + name: + label: Имя пользователя + msg: + empty: Имя пользователя не должно быть пустым. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: Email адрес + msg: + empty: Адрес электронной почты не может быть пустым. + password: + label: Пароль + msg: + empty: Пароль не может быть пустым. + different: Введенные пароли не совпадают + account_forgot: + page_title: Забыли свой пароль + btn_name: Отправить мне письмо для восстановления пароля + send_success: >- + Если учетная запись соответствует {{mail}}, вы должны в ближайшее время получить электронное письмо с инструкциями о том, как сбросить пароль. + email: + label: Email адрес + msg: + empty: Адрес электронной почты не может быть пустым. + change_email: + btn_cancel: Отмена + btn_update: Сменить адрес email + send_success: >- + Если учетная запись соответствует {{mail}}, вы должны в ближайшее время получить электронное письмо с инструкциями о том, как сбросить пароль. + email: + label: Новый email + msg: + empty: Email не может быть пустым. + oauth: + connect: Связаться с {{ auth_name }} + remove: Удалить {{ auth_name }} + oauth_bind_email: + subtitle: Добавьте адрес электронной почты для восстановления учетной записи. + btn_update: Сменить адрес email + email: + label: Электронная почта + msg: + empty: Адрес электронной почты не может быть пустым. + modal_title: Электронная почта уже существует. + modal_content: Этот адрес электронной почты уже зарегистрирован. Вы уверены, что хотите подключиться к существующей учетной записи? + modal_cancel: Изменить адрес электронной почты + modal_confirm: Подключение к существующей учетной записи + password_reset: + page_title: Сброс пароля + btn_name: Сбросить мой пароль + reset_success: >- + Вы успешно сменили свой пароль; вы будете перенаправлены на страницу входа в систему. + link_invalid: >- + Извините, эта ссылка для сброса пароля больше недействительна. Возможно, ваш пароль уже сброшен? + to_login: Перейдите на страницу входа в систему + password: + label: Пароль + msg: + empty: Пароль не может быть пустым. + length: Длина должна быть от 8 до 32 + different: Введенные пароли не совпадают + password_confirm: + label: Подтвердите новый пароль + settings: + page_title: Настройки + goto_modify: Перейдите к изменению + nav: + profile: Профиль + notification: Уведомления + account: Учетная запись + interface: Интерфейс + profile: + heading: Профиль + btn_name: Сохранить + display_name: + label: Отображаемое имя + msg: Отображаемое имя не может быть пустым. + msg_range: Display name must be 2-30 characters in length. + username: + label: Имя пользователя + caption: Люди могут упоминать вас как "@username". + msg: Имя пользователя не может быть пустым. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Изображение профиля + gravatar: Gravatar + gravatar_text: Вы можете изменить изображение на + custom: Другой + custom_text: Вы можете загрузить свое изображение. + default: Системные + msg: Пожалуйста, загрузите аватар + bio: + label: Обо мне + website: + label: Сайт + placeholder: "https://example.com" + msg: Неправильный формат веб-сайта + location: + label: Местоположение + placeholder: "Город, страна" + notification: + heading: Уведомления по эл. почте + turn_on: Вкл. + inbox: + label: Email уведомления + description: Ответы на ваши вопросы, комментарии, приглашения и многое другое. + all_new_question: + label: Все новые вопросы + description: Получайте уведомления обо всех новых вопросах. До 50 вопросов в неделю. + all_new_question_for_following_tags: + label: Все новые вопросы для тегов из подписок + description: Получайте уведомления о новых вопросах по следующим тегам. + account: + heading: Учетная запись + change_email_btn: Изменить e-mail + change_pass_btn: Изменить пароль + change_email_info: >- + Мы отправили электронное письмо на этот адрес. Пожалуйста, следуйте инструкциям из письма. + email: + label: Email + new_email: + label: Новый email + msg: Новый email не может быть пустым. + pass: + label: Текущий пароль + msg: Пароль не может быть пустым. + password_title: Пароль + current_pass: + label: Текущий пароль + msg: + empty: Текущий пароль не может быть пустым. + length: Длина должна быть от 8 до 32. + different: Введенные пароли не совпадают. + new_pass: + label: Новый пароль + pass_confirm: + label: Подтвердите новый пароль + interface: + heading: Интерфейс + lang: + label: Язык интерфейса + text: Язык пользовательского интерфейса. Он изменится при обновлении страницы. + my_logins: + title: Мои логины + label: Войдите в систему или зарегистрируйтесь на этом сайте, используя эти учетные записи. + modal_title: Удаление логина + modal_content: Вы уверены, что хотите удалить этот логин из своей учетной записи? + modal_confirm_btn: Удалить + remove_success: Успешно удалено + toast: + update: успешное обновление + update_password: Пароль успешно изменен. + flag_success: Благодарим за отметку. + forbidden_operate_self: Запрещено работать с собой + review: Ваша версия будет отображаться после проверки. + sent_success: Отправлено успешно + related_question: + title: Related + answers: ответы + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Позвать на помощь + desc: Выберите людей, которые, по вашему мнению, могут знать ответ. + invite: Пригласил вас ответить + add: Добавить пользователей + search: Поиск людей + question_detail: + action: Действия + created: Created + Asked: Спросил(а) + asked: спросил(а) + update: Изменён + Edited: Edited + edit: отредактировал + commented: commented + Views: Просмотрен + Follow: Подписаться + Following: Подписки + follow_tip: Подпишитесь на этот вопрос для получения уведомлений + answered: отвеченные + closed_in: Закрыто в + show_exist: Показать существующий вопрос. + useful: Полезный + question_useful: Это полезно и понятно + question_un_useful: Это непонятно или не полезно + question_bookmark: Добавьте этот вопрос в закладки + answer_useful: Это полезно + answer_un_useful: Это бесполезно + answers: + title: Ответы + score: Оценка + newest: Последние + oldest: Oldest + btn_accept: Принять + btn_accepted: Принято + write_answer: + title: Ваш ответ + edit_answer: Редактировать мой существующий ответ + btn_name: Ответить + add_another_answer: Добавить другой ответ + confirm_title: Перейти к ответу + continue: Продолжить + confirm_info: >- +

        Вы уверены, что хотите добавить другой ответ?

        Вы можете использовать ссылку редактирования для уточнения и улучшения существующего ответа.

        + empty: Ответ не может быть пустым. + characters: длина содержимого должна составлять не менее 6 символов. + tips: + header_1: Спасибо за ответ + li1_1: Пожалуйста, обязательно отвечайте на вопрос. Предоставьте подробности и поделитесь результатами своих исследований. + li1_2: Поддерживайте свои высказывания ссылками или личным опытом. + header_2: Но избегайте ... + li2_1: Просить о помощи, запрашивать уточнения или отвечать на другие ответы. + reopen: + confirm_btn: Снова открыть + title: Открыть повторно этот пост + content: Вы уверены, что хотите открыть заново? + list: + confirm_btn: Список + title: List this post + content: Are you sure you want to list? + unlist: + confirm_btn: Убрать из списка + title: Unlist this post + content: Are you sure you want to unlist? + pin: + title: Закрепить сообщение + content: Вы уверены, что хотите закрепить глобально? Это сообщение появится вверху всех списков сообщений. + confirm_btn: Закрепить + delete: + title: Удалить сообщение + question: >- + Мы не рекомендуем удалять вопросы с ответами, поскольку это лишает будущих читателей этих знаний.

        Повторное удаление вопросов с ответами может привести к блокировке вашей учетной записи. Вы уверены, что хотите удалить? + answer_accepted: >- + Мы не рекомендуем удалять вопросы с ответами, поскольку это лишает будущих читателей этих знаний.

        Повторное удаление вопросов с ответами может привести к блокировке вашей учетной записи. Вы уверены, что хотите удалить? + other: Вы уверены, что хотите удалить? + tip_answer_deleted: Этот ответ был удален + undelete_title: Восстановить сообщение + undelete_desc: Вы уверены, что хотите отменить удаление? + btns: + confirm: Подтвердить + cancel: Отменить + edit: Редактировать + save: Сохранить + delete: Удалить + undelete: Отменить удаление + list: List + unlist: Unlist + unlisted: Unlisted + login: Авторизоваться + signup: Регистрация + logout: Выйти + verify: Подтвердить + create: Create + approve: Одобрить + reject: Отклонить + skip: Пропустить + discard_draft: Удалить черновик + pinned: Закрепленный + all: Все + question: Вопрос + answer: Ответ + comment: Комментарий + refresh: Обновить + resend: Отправить повторно + deactivate: Отключить + active: Активные + suspend: Заблокировать + unsuspend: Разблокировать + close: Закрыть + reopen: Открыть повторно + ok: ОК + light: Светлая тема + dark: Темная тема + system_setting: Настройки системы + default: По умолчанию + reset: Сбросить + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignore + submit: Submit + normal: Normal + closed: Closed + deleted: Deleted + deleted_permanently: Deleted permanently + pending: Pending + more: More + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Результаты поиска + keywords: Ключевые слова + options: Настройки + follow: Подписаться + following: Подписка + counts: "Результатов: {{count}}" + counts_loading: "... Results" + more: Ещё + sort_btns: + relevance: По релевантности + newest: Последние + active: Активные + score: Оценки + more: Больше + tips: + title: Советы по расширенному поиску + tag: "<1>[tag] search with a tag" + user: "<1>user:username поиск по автору" + answer: "<1>ответов:0 вопросы без ответов" + score: "<1>score:3 записи с рейтингом 3+" + question: "<1>is:question поиск по вопросам" + is_answer: "<1>ответ поиск ответов" + empty: Мы ничего не смогли найти.
        Попробуйте другие или менее специфичные ключевые слова. + share: + name: Поделиться + copy: Скопировать ссылку + via: Поделитесь постом через... + copied: Скопировано + facebook: Поделиться на Facebook + twitter: Share to X + cannot_vote_for_self: Вы не можете проголосовать за свой собственный пост. + modal_confirm: + title: Ошибка... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Ваша новая учетная запись подтверждена; вы будете перенаправлены на главную страницу. + link: Перейти на главную + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: Ваш адрес электронной почты был обновлен. + confirm_new_email_invalid: >- + Извините, эта ссылка для подтверждения больше недействительна. Возможно, ваш адрес электронной почты уже был изменен? + unsubscribe: + page_title: Отписаться + success_title: Вы успешно отписались от рассылки + success_desc: Вы были успешно удалены из этого списка подписчиков и больше не будете получать от нас никаких электронных писем. + link: Изменить настройки + question: + following_tags: Подписка на теги + edit: Редактировать + save: Сохранить + follow_tag_tip: Подпишитесь на теги, чтобы следить за интересующими темами. + hot_questions: Популярные вопросы + all_questions: Все вопросы + x_questions: "{{ count }} вопросов" + x_answers: "{{ count }} ответов" + x_posts: "{{ count }} Posts" + questions: Вопросы + answers: Ответы + newest: Последние + active: Активные + hot: Hot + frequent: Frequent + recommend: Recommend + score: Оценка + unanswered: Без ответа + modified: изменён + answered: отвеченные + asked: спросил(а) + closed: закрытый + follow_a_tag: Следить за тегом + more: Подробнее + personal: + overview: Обзор + answers: Ответы + answer: ответ + questions: Вопросы + question: вопрос + bookmarks: Закладки + reputation: Репутация + comments: Комментарии + votes: Голоса + badges: Badges + newest: Последние + score: Оценки + edit_profile: Редактировать профиль + visited_x_days: "Посещено {{ count }} дней" + viewed: Просмотрен + joined: Присоединился + comma: "," + last_login: Просмотрен(-а) + about_me: О себе + about_me_empty: "// Привет, Мир!" + top_answers: Лучшие ответы + top_questions: Топ вопросов + stats: Статистика + list_empty: Сообщений не найдено.
        Возможно, вы хотели бы выбрать другую вкладку? + content_empty: No posts found. + accepted: Принято + answered: отвеченные + asked: спросил + downvoted: проголосовано против + mod_short: MOD + mod_long: Модераторы + x_reputation: репутация + x_votes: полученные голоса + x_answers: ответы + x_questions: вопросы + recent_badges: Recent Badges + install: + title: Installation + next: Следующий + done: Готово + config_yaml_error: Не удается создать файл config.yaml. + lang: + label: Пожалуйста, выберите язык + db_type: + label: База данных + db_username: + label: Имя пользователя + placeholder: root + msg: Имя пользователя не может быть пустым. + db_password: + label: Пароль + placeholder: root + msg: Пароль не может быть пустым. + db_host: + label: Сервер базы данных + placeholder: "db:3306" + msg: Сервер базы данных не может быть пустым. + db_name: + label: Название базы данных + placeholder: ответ + msg: Имя базы данных не может быть пустым. + db_file: + label: Файл базы данных + placeholder: /data/answer.db + msg: Файл базы данных не может быть пустым. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Создайте файл config.yaml + label: Файл config.yaml создан. + desc: >- + Вы можете создать файл <1>config.yaml вручную в каталоге <1>/var/wwww/xxx/ и вставить в него следующий текст. + info: После этого нажмите на кнопку "Далее". + site_information: Информация о сайте + admin_account: Администратор + site_name: + label: Название сайта + msg: Название сайта не может быть пустым. + msg_max_length: Длина названия сайта должна составлять не более 30 символов. + site_url: + label: Адрес сайта + text: Адрес вашего сайта. + msg: + empty: URL-адрес сайта не может быть пустым. + incorrect: Неверный формат URL-адреса сайта. + max_length: Длина URL-адреса сайта должна составлять не более 512 символов. + contact_email: + label: Контактный адрес электронной почты + text: Адрес электронной почты контактного лица, ответственного за этот сайт. + msg: + empty: Контактный адрес электронной почты не может быть пустым. + incorrect: Некорректный формат контактного адреса электронной почты. + login_required: + label: Приватный + switch: Требуется авторизация + text: Только зарегистрированные пользователи могут получить доступ к этому сообществу. + admin_name: + label: Имя + msg: Имя не может быть пустым. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Пароль + text: >- + Этот пароль понадобится вам для входа в систему. Пожалуйста, сохраните его в надежном месте. + msg: Пароль не может быть пустым. + msg_min_length: Длина пароля должна составлять не менее 8 символов. + msg_max_length: Длина пароля должна составлять не более 32 символов. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: Email + text: Вам понадобится этот адрес электронной почты для входа в систему. + msg: + empty: Адрес электронной почты не может быть пустым. + incorrect: Недопустимый формат e-mail адреса. + ready_title: Your site is ready + ready_desc: >- + Если вам когда-нибудь захочется изменить дополнительные настройки, посетите <1>раздел администратора; найдите его в меню сайта. + good_luck: "Получайте удовольствие и удачи!" + warn_title: Предупреждение + warn_desc: >- + Файл <1>config.yaml уже существует. Если вам нужно сбросить любой из элементов конфигурации в этом файле, пожалуйста, удалите его. + install_now: Вы можете попробовать <1>установить сейчас. + installed: Уже установлено + installed_desc: >- + Похоже, вы уже установили. Для переустановки, пожалуйста, сначала очистите ваши старые таблицы базы данных. + db_failed: Ошибка подключения к базе данных + db_failed_desc: >- + Это означает, что информация о базе данных в вашем файле <1>config.yaml неверна, либо не удалось установить контакт с сервером базы данных. Это может означать, что сервер базы данных вашего хоста недоступен. + counts: + views: просмотры + votes: голоса + answers: ответы + accepted: Принято + page_error: + http_error: Ошибка HTTP {{ code }} + desc_403: Нет прав доступа для просмотра этой страницы. + desc_404: К сожалению, эта страница не существует. + desc_50X: Сервер обнаружил ошибку и не смог выполнить ваш запрос. + back_home: Вернуться на главную страницу + page_maintenance: + desc: "Мы выполняем техническое обслуживание, скоро вернемся." + nav_menus: + dashboard: Панель управления + contents: Содержимое + questions: Вопросы + answers: Ответы + users: Пользователи + badges: Badges + flags: Отметить + settings: Настройки + general: Основные + interface: Интерфейс + smtp: SMTP + branding: Фирменное оформление + legal: Правовая информация + write: Написать + terms: Terms + tos: Пользовательское Соглашение + privacy: Конфиденциальность + seo: SEO + customize: Настройки интерфейса + themes: Темы + login: Вход + privileges: Привилегии + plugins: Плагины + installed_plugins: Установленные плагины + apperance: Appearance + website_welcome: Добро пожаловать на {{site_name}} + user_center: + login: Вход + qrcode_login_tip: Пожалуйста, используйте {{ agentName }} для сканирования QR-кода и входа в систему. + login_failed_email_tip: Не удалось войти в систему, пожалуйста, разрешите этому приложению получить доступ к вашей электронной почте, прежде чем повторять попытку. + badges: + modal: + title: Congratulations + content: You've earned a new badge. + close: Close + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + admin: + admin_header: + title: Администратор + dashboard: + title: Панель управления + welcome: Welcome to Admin! + site_statistics: Статистика сайта + questions: "Вопросы:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "Ответы:" + comments: "Комментарии:" + votes: "Голоса:" + users: "Пользователи:" + flags: "Жалобы:" + reviews: "Reviews:" + site_health: Здоровье сайта + version: "Версия:" + https: "HTTPS:" + upload_folder: "Каталог загрузки:" + run_mode: "Режим приватности:" + private: Приватный + public: Публичные + smtp: "SMTP:" + timezone: "Часовой пояс:" + system_info: Информация о системе + go_version: "Версия GO:" + database: "База данных:" + database_size: "Размер базы данных:" + storage_used: "Использовано хранилища: " + uptime: "Время работы:" + links: Ссылки + plugins: Плагины + github: GitHub + blog: Блог + contact: Контакты + forum: Форум + documents: Документы + feedback: Обратная связь + support: Поддержка + review: Обзор + config: Конфигурация + update_to: Обновление до + latest: Последние + check_failed: Проверка не удалась + "yes": "Да" + "no": "Нет" + not_allowed: Запрещено + allowed: Разрешено + enabled: Включено + disabled: Отключено + writable: Доступен для записи + not_writable: Не доступен для записи + flags: + title: Жалобы + pending: Ожидают + completed: Рассмотрены + flagged: Жалобы + flagged_type: Жалоба {{ type }} + created: Создано + action: Действие + review: На проверку + user_role_modal: + title: Изменить роль пользователя на... + btn_cancel: Отмена + btn_submit: Отправить + new_password_modal: + title: Задать новый пароль + form: + fields: + password: + label: Пароль + text: Сессия пользователя будет завершена и ему придется повторить вход. + msg: Длина пароля должна составлять от 8 до 32 символов. + btn_cancel: Отменить + btn_submit: Отправить + edit_profile_modal: + title: Edit profile + form: + fields: + display_name: + label: Display name + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Invalid Email Address. + edit_success: Edited successfully + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Создание новых пользователей + form: + fields: + users: + label: Массовое добавление пользователей + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Разделите “name, email, password” запятыми. По одному пользователю в строке. + msg: "Пожалуйста, введите адрес электронной почты пользователя, по одному на строку." + display_name: + label: Отображаемое имя + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Некорректный email. + password: + label: Пароль + msg: Длина пароля должна составлять от 8 до 32 символов. + btn_cancel: Отменить + btn_submit: Отправить + users: + title: Пользователи + name: Имя + email: Email + reputation: Репутация + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Статус + role: Роль + action: Действия + change: Изменить + all: Все + staff: Сотрудники + more: Ещё + inactive: Неактивные + suspended: Заблокированные + deleted: Удаленные + normal: Обычный + Moderator: Модератор + Admin: Администратор + User: Пользователь + filter: + placeholder: "Фильтровать по имени, user:id" + set_new_password: Задать новый пароль + edit_profile: Edit profile + change_status: Изменить статус + change_role: Изменить роль + show_logs: Показать логи + add_user: Добавить пользователя + deactivate_user: + title: Деактивировать пользователя + content: Неактивный пользователь должен будет повторно подтвердить свою электронную почту. + delete_user: + title: Удалить этого пользователя + content: Вы уверены, что хотите удалить этого пользователя? Это действие необратимо! + remove: Удалить контент пользователя (опционально) + label: Удалить все вопросы, ответы, комментарии и т.д. + text: Не устанавливайте этот флажок, если вы хотите удалить только учетную запись пользователя. + suspend_user: + title: Заблокировать этого пользователя + content: Заблокированный пользователь не сможет войти. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Вопросы + unlisted: Unlisted + post: Публикация + votes: Голоса + answers: Ответы + created: Создан + status: Статус + action: Действие + change: Изменить + pending: Ожидают + filter: + placeholder: "Фильтровать по заголовку, question:id" + answers: + page_title: Ответы + post: Публикация + votes: Голоса + created: Создан + status: Статус + action: Действие + change: Изменить + filter: + placeholder: "Фильтровать по заголовку, answer:id" + general: + page_title: Основные + name: + label: Название сайта + msg: Название сайта не может быть пустым. + text: "Название сайта, используемое в теге title." + site_url: + label: URL-адрес сайта + msg: URL-адрес сайта не может быть пустым. + validate: Пожалуйста, введите корректный URL. + text: Адрес вашего сайта. + short_desc: + label: Краткое описание + msg: Краткое описание сайта не может быть пустым. + text: "Краткое описание, используемое в теге заголовка на домашней странице." + desc: + label: Описание сайта + msg: Описание сайта не может быть пустым. + text: "Опишите этот сайт одним предложением, как используется в теге meta description" + contact_email: + label: Контактный адрес электронной почты + msg: Контактный адрес электронной почты не может быть пустым. + validate: Контактный адрес электронной почты не может быть пустым. + text: Адрес электронной почты контактного лица, ответственного за данный сайт. + check_update: + label: Обновления программного обеспечения + text: Автоматически проверять наличие обновлений + interface: + page_title: Интерфейс + language: + label: Язык интерфейса + msg: Язык интерфейса не может быть пустым. + text: Язык пользовательского интерфейса. Он изменится при обновлении страницы. + time_zone: + label: Часовой пояс + msg: Часовой пояс не может быть пустым. + text: Выберите город в том же часовом поясе, что и вы. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: С эл. почты + msg: Адрес электронной почты отправителя не может быть пустым. + text: Адрес электронной почты, с которого отправляются письма. + from_name: + label: Имя отправителя + msg: Имя пользователя не может быть пустым. + text: Имя, с которого отправляются электронные письма. + smtp_host: + label: Сервер SMTP + msg: Сервер SMTP не может быть пустым. + text: Ваш почтовый сервер. + encryption: + label: Шифрование + msg: Шифрование не может быть пустым. + text: Для большинства серверов рекомендуется использовать протокол SSL. + ssl: SSL + tls: TLS + none: Нет + smtp_port: + label: Порт SMTP + msg: Порт SMTP должен быть числом 1 ~ 65535. + text: Порт для вашего почтового сервера. + smtp_username: + label: Имя пользователя SMTP + msg: Имя пользователя SMTP не может быть пустым. + smtp_password: + label: Пароль SMTP + msg: Пароль SMTP не может быть пустым. + test_email_recipient: + label: Тестовые получатели электронной почты + text: Укажите адрес электронной почты, на который будут отправляться тестовые сообщения. + msg: Некорректный тестовый адрес электронной почты + smtp_authentication: + label: Включить авторизацию + title: Аутентификация SMTP + msg: Аутентификационные данные для SMTP не могут быть пустыми. + "yes": "Да" + "no": "Нет" + branding: + page_title: Фирменное оформление + logo: + label: Логотип + msg: Логотип не может быть пустым. + text: Изображение логотипа в левом верхнем углу вашего сайта. Используйте широкое прямоугольное изображение высотой 56 см с соотношением сторон более 3:1. Если оставить поле пустым, будет показан текст заголовка сайта. + mobile_logo: + label: Мобильный логотип + text: Логотип, используемый в мобильной версии вашего сайта. Используйте широкое прямоугольное изображение высотой 56. Если оставить пустым, будет использоваться изображение из настройки "Логотип". + square_icon: + label: Квадратный значок + msg: Square icon не может быть пустым. + text: Изображение, используемое в качестве основы для значков метаданных. В идеале должно быть больше 512x512. + favicon: + label: Иконка + text: Значок для вашего сайта. Для корректной работы через CDN он должен быть в формате png. Размер будет изменен до 32x32. Если оставить пустым, будет использоваться "square icon". + legal: + page_title: Правовая информация + terms_of_service: + label: Условия использования + text: "Вы можете добавить содержимое условий предоставления услуг здесь. Если у вас уже есть документ, размещенный в другом месте, укажите полный URL-адрес здесь." + privacy_policy: + label: Условия конфиденциальности + text: "Вы можете добавить содержание политики конфиденциальности здесь. Если у вас уже есть документ, размещенный в другом месте, укажите полный URL-адрес здесь." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Написать + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Каждый пользователь может написать только один ответ на каждый вопрос + text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Рекомендованные теги + text: "Recommend tags will show in the dropdown list by default." + msg: + contain_reserved: "recommended tags cannot contain reserved tags" + required_tag: + title: Set required tags + label: Set “Recommend tags” as required tags + text: "Каждый новый вопрос должен иметь хотя бы один рекомендуемый тег." + reserved_tags: + label: Зарезервированные теги + text: "Reserved tags can only be used by moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: SEO + permalink: + label: Постоянная ссылка + text: Пользовательские структуры URL-адресов могут улучшить удобство использования и обратную совместимость ваших ссылок. + robots: + label: robots.txt + text: Это приведет к необратимому переопределению всех связанных настроек сайта. + themes: + page_title: Темы + themes: + label: Темы + text: Выберите существующую тему. + color_scheme: + label: Цветовая схема + navbar_style: + label: Navbar background style + primary_color: + label: Основной цвет + text: Измените цвета, используемые в ваших темах + css_and_html: + page_title: CSS и HTML + custom_css: + label: Пользовательский CSS + text: > + + head: + label: Head + text: > + + header: + label: Header + text: > + + footer: + label: Нижняя панель + text: Это будет вставлено перед </body>. + sidebar: + label: Боковая панель + text: Это будет вставлено в боковую панель. + login: + page_title: Авторизоваться + membership: + title: Участие в сообществах + label: Разрешить новые регистрации + text: Отключите, чтобы никто не мог создать новую учетную запись. + email_registration: + title: Регистрация по электронной почте + label: Разрешить регистрацию по электронной почте + text: Отключите, чтобы предотвратить создание новой учетной записи через электронную почту. + allowed_email_domains: + title: Разрешенные домены электронной почты + text: Домены электронной почты, с которыми пользователи должны регистрировать аккаунты. Один домен на каждой строке. Игнорируется, если пусто. + private: + title: Приватный + label: Требуется авторизация + text: Только зарегистрированные пользователи могут получить доступ к этому сообществу. + password_login: + title: Вход в пароль + label: Разрешить вход по паролю + text: "Предупреждение: При отключении, вы не сможете войти, если ранее не настроили другой способ входа." + installed_plugins: + title: Установленные плагины + plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + filter: + all: Все + active: Активные + inactive: Неактивные + outdated: Устаревшие + plugins: + label: Плагины + text: Выберите существующий плагин. + name: Название + version: Версия + status: Статус + action: Действие + deactivate: Деактивировать + activate: Активировать + settings: Настройки + settings_users: + title: Пользователи + avatar: + label: Аватар по умолчанию + text: Для пользователей, у которых нет собственного пользовательского аватара. + gravatar_base_url: + label: Базовый URL Gravatar + text: URL базы API провайдера Gravatar. Игнорируется, если пусто. + profile_editable: + title: Настройки профилей + allow_update_display_name: + label: Разрешить пользователям изменять отображаемое имя + allow_update_username: + label: Разрешить пользователям изменять свой username + allow_update_avatar: + label: Разрешить пользователям изменять изображение своего профиля + allow_update_bio: + label: Разрешить пользователям изменять свои сведения в поле "обо мне" + allow_update_website: + label: Разрешить пользователям изменять свой веб-сайт + allow_update_location: + label: Разрешить пользователям изменять свое местоположение + privilege: + title: Привилегии + level: + label: Необходимый уровень репутации + text: Выберите количество репутации, необходимое для получения привилегий + msg: + should_be_number: the input should be number + number_larger_1: number should be equal or larger than 1 + badges: + action: Action + active: Active + activate: Activate + all: All + awards: Awards + deactivate: Deactivate + filter: + placeholder: Filter by name, badge:id + group: Group + inactive: Inactive + name: Name + show_logs: Show logs + status: Status + title: Badges + form: + optional: (опционально) + empty: не может быть пустым + invalid: недействителен + btn_submit: Сохранить + not_found_props: "Требуемое свойство {{ key }} не найдено." + select: Select + page_review: + review: На проверку + proposed: предложенный + question_edit: Редактировать вопрос + answer_edit: Редактирование ответа + tag_edit: Редактирование тега + edit_summary: Редактирование краткого описания + edit_question: Редактирование вопроса + edit_answer: Редактирование ответа + edit_tag: Редактирование тега + empty: Нет задач для проверки. + approve_revision_tip: Do you approve this revision? + approve_flag_tip: Do you approve this flag? + approve_post_tip: Do you approve this post? + approve_user_tip: Do you approve this user? + suggest_edits: Предложенные исправления + flag_post: Flag post + flag_user: Flag user + queued_post: Queued post + queued_user: Queued user + filter_label: Type + reputation: репутация + flag_post_type: Flagged this post as {{ type }}. + flag_user_type: Flagged this user as {{ type }}. + edit_post: Edit post + list_post: List post + unlist_post: Unlist post + timeline: + undeleted: Восстановлен + deleted: Удаленные + downvote: бесполезный + upvote: оценить + accept: принять + cancelled: отменен + commented: прокомментированный + rollback: откатить + edited: отредактированный + answered: отвеченные + asked: asked + closed: закрытый + reopened: Открыт повторно + created: созданный + pin: закрепленный + unpin: незакреплённые + show: listed + hide: unlisted + title: "History for" + tag_title: "Хронология" + show_votes: "Show votes" + n_or_a: Недоступно + title_for_question: "Хронология" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Дата и время + type: Тип + by: Автор + comment: Комментарий + no_data: "Ничего не найдено." + users: + title: Пользователи + users_with_the_most_reputation: Пользователи с самой высокой репутацией на этой неделе + users_with_the_most_vote: Пользователи, которые больше всего проголосовали на этой неделе + staffs: Сотрудники нашего сообщества + reputation: репутация + votes: голоса + prompt: + leave_page: Вы уверены, что хотите покинуть страницу? + changes_not_save: Ваши изменения могут не быть сохранены. + draft: + discard_confirm: Вы уверены, что хотите отказаться от своего черновика? + messages: + post_deleted: Этот пост был удалён. + post_cancel_deleted: This post has been undeleted. + post_pin: Этот пост был закреплен. + post_unpin: Этот пост был откреплен. + post_hide_list: Это сообщение было скрыто из списка. + post_show_list: Этот пост был показан в списке. + post_reopen: Этот пост был вновь открыт. + post_list: This post has been listed. + post_unlist: This post has been unlisted. + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/sk_SK.yaml b/data/i18n/sk_SK.yaml new file mode 100644 index 000000000..4daa2ab02 --- /dev/null +++ b/data/i18n/sk_SK.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Úspech. + unknown: + other: Neznáma chyba. + request_format_error: + other: Formát žiadosti nie je platný. + unauthorized_error: + other: Neoprávnené. + database_error: + other: Chyba dátového servera. + forbidden_error: + other: Forbidden. + duplicate_request_error: + other: Duplicate submission. + action: + report: + other: Flag + edit: + other: Edit + delete: + other: Delete + close: + other: Close + reopen: + other: Reopen + forbidden_error: + other: Forbidden. + pin: + other: Pin + hide: + other: Unlist + unpin: + other: Unpin + show: + other: List + invite_someone_to_answer: + other: Edit + undelete: + other: Undelete + merge: + other: Merge + role: + name: + user: + other: Užívateľ + admin: + other: Správca + moderator: + other: Moderátor + description: + user: + other: Predvolené bez špeciálneho prístupu. + admin: + other: Má plnú moc a prístup ku stránke. + moderator: + other: Má prístup ku všetkým príspevkom okrem nastavenia správcu. + privilege: + level_1: + description: + other: Level 1 (less reputation required for private team, group) + level_2: + description: + other: Level 2 (low reputation required for startup community) + level_3: + description: + other: Level 3 (high reputation required for mature community) + level_custom: + description: + other: Custom Level + rank_question_add_label: + other: Ask question + rank_answer_add_label: + other: Write answer + rank_comment_add_label: + other: Write comment + rank_report_add_label: + other: Flag + rank_comment_vote_up_label: + other: Upvote comment + rank_link_url_limit_label: + other: Post more than 2 links at a time + rank_question_vote_up_label: + other: Upvote question + rank_answer_vote_up_label: + other: Upvote answer + rank_question_vote_down_label: + other: Downvote question + rank_answer_vote_down_label: + other: Downvote answer + rank_invite_someone_to_answer_label: + other: Invite someone to answer + rank_tag_add_label: + other: Create new tag + rank_tag_edit_label: + other: Edit tag description (need to review) + rank_question_edit_label: + other: Edit other's question (need to review) + rank_answer_edit_label: + other: Edit other's answer (need to review) + rank_question_edit_without_review_label: + other: Edit other's question without review + rank_answer_edit_without_review_label: + other: Edit other's answer without review + rank_question_audit_label: + other: Review question edits + rank_answer_audit_label: + other: Review answer edits + rank_tag_audit_label: + other: Review tag edits + rank_tag_edit_without_review_label: + other: Edit tag description without review + rank_tag_synonym_label: + other: Manage tag synonyms + email: + other: E-mail + e_mail: + other: Email + password: + other: Heslo + pass: + other: Password + old_pass: + other: Current password + original_text: + other: This post + email_or_password_wrong_error: + other: E-mail a heslo sa nezhodujú. + error: + common: + invalid_url: + other: Invalid URL. + status_invalid: + other: Invalid status. + password: + space_invalid: + other: Password cannot contain spaces. + admin: + cannot_update_their_password: + other: Svoje heslo upraviť. + cannot_edit_their_profile: + other: You cannot modify your profile. + cannot_modify_self_status: + other: Nemôžete upraviť svoj stav. + email_or_password_wrong: + other: E-mail a heslo sa nezhodujú. + answer: + not_found: + other: Odpoveď sa nenašla. + cannot_deleted: + other: Žiadne povolenie na odstránenie. + cannot_update: + other: Žiadne povolenie na aktualizáciu. + question_closed_cannot_add: + other: Questions are closed and cannot be added. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Komentár nie je dovolené upravovať. + not_found: + other: Komentár sa nenašiel. + cannot_edit_after_deadline: + other: Čas na úpravu komentára bol príliš dlhý. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: E-mail už existuje. + need_to_be_verified: + other: E-mail by sa mal overiť. + verify_url_expired: + other: Platnosť overenej adresy URL e-mailu vypršala, pošlite e-mail znova. + illegal_email_domain_error: + other: Email is not allowed from that email domain. Please use another one. + lang: + not_found: + other: Jazykový súbor sa nenašiel. + object: + captcha_verification_failed: + other: Captcha zle. + disallow_follow: + other: Nemáte dovolené sledovať. + disallow_vote: + other: Nemáte povolené hlasovať. + disallow_vote_your_self: + other: Nemôžete hlasovať za svoj vlastný príspevok. + not_found: + other: Objekt sa nenašiel. + verification_failed: + other: Overenie zlyhalo. + email_or_password_incorrect: + other: E-mail a heslo sa nezhodujú. + old_password_verification_failed: + other: Overenie starého hesla zlyhalo + new_password_same_as_previous_setting: + other: Nové heslo je rovnaké ako predchádzajúce. + already_deleted: + other: This post has been deleted. + meta: + object_not_found: + other: Meta object not found + question: + already_deleted: + other: Tento príspevok bol odstránený. + under_review: + other: Your post is awaiting review. It will be visible after it has been approved. + not_found: + other: Otázka sa nenašla. + cannot_deleted: + other: Žiadne povolenie na odstránenie. + cannot_close: + other: Žiadne povolenie na uzavretie. + cannot_update: + other: Žiadne povolenie na aktualizáciu. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Reputation rank fail to meet the condition. + vote_fail_to_meet_the_condition: + other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. + no_enough_rank_to_operate: + other: You need at least {{.Rank}} reputation to do this. + report: + handle_failed: + other: Spracovanie prehľadu zlyhalo. + not_found: + other: Hlásenie sa nenašlo. + tag: + already_exist: + other: Značka už existuje. + not_found: + other: Značka sa nenašla. + recommend_tag_not_found: + other: Recommend tag is not exist. + recommend_tag_enter: + other: Zadajte aspoň jednu požadovanú značku. + not_contain_synonym_tags: + other: Nemal by obsahovať synonymické značky. + cannot_update: + other: Žiadne povolenie na aktualizáciu. + is_used_cannot_delete: + other: You cannot delete a tag that is in use. + cannot_set_synonym_as_itself: + other: Synonymum aktuálnej značky nemôžete nastaviť ako samotnú. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: The from name cannot be a email address. + theme: + not_found: + other: Téma sa nenašla. + revision: + review_underway: + other: Momentálne nie je možné upravovať, vo fronte na kontrolu je verzia. + no_permission: + other: No permission to revise. + user: + external_login_missing_user_id: + other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. + external_login_unbinding_forbidden: + other: Please set a login password for your account before you remove this login. + email_or_password_wrong: + other: + other: E-mail a heslo sa nezhodujú. + not_found: + other: Používateľ nenájdený. + suspended: + other: Používateľ bol pozastavený. + username_invalid: + other: Používateľské meno je neplatné. + username_duplicate: + other: Používateľské meno sa už používa. + set_avatar: + other: Nastavenie avatara zlyhalo. + cannot_update_your_role: + other: Svoju rolu nemôžete zmeniť. + not_allowed_registration: + other: Currently the site is not open for registration. + not_allowed_login_via_password: + other: Currently the site is not allowed to login via password. + access_denied: + other: Access denied + page_access_denied: + other: You do not have access to this page. + add_bulk_users_format_error: + other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Read Config zlyhal + database: + connection_failed: + other: Databázové pripojenie zlyhalo + create_table_failed: + other: Vytvorenie tabuľky zlyhalo + install: + create_config_failed: + other: Nie je možné vytvoriť súbor config.yaml. + upload: + unsupported_file_format: + other: Nepodporovaný formát súboru. + site_info: + config_not_found: + other: Site config not found. + badge: + object_not_found: + other: Badge object not found + reason: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude_or_abusive: + name: + other: rude or abusive + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + a_duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + placeholder: + other: Enter the existing question link + not_a_answer: + name: + other: not an answer + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." + no_longer_needed: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + something: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + placeholder: + other: Let us know specifically what you are concerned about + community_specific: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + not_clarity: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + looks_ok: + name: + other: looks OK + desc: + other: This post is good as-is and not low quality. + needs_edit: + name: + other: needs edit, and I did it + desc: + other: Improve and correct problems with this post yourself. + needs_close: + name: + other: needs close + desc: + other: A closed question can't answer, but still can edit, vote and comment. + needs_delete: + name: + other: needs delete + desc: + other: This post will be deleted. + question: + close: + duplicate: + name: + other: nevyžiadaná pošta + desc: + other: Táto otázka už bola položená a už má odpoveď. + guideline: + name: + other: dôvod špecifický pre komunitu + desc: + other: Táto otázka nespĺňa pokyny pre komunitu. + multiple: + name: + other: potrebuje podrobnosti alebo jasnosť + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: niečo iné + desc: + other: Tento príspevok vyžaduje iný dôvod, ktorý nie je uvedený vyššie. + operation_type: + asked: + other: požiadaný + answered: + other: zodpovedaný + modified: + other: upravený + deleted_title: + other: Deleted question + questions_title: + other: Questions + tag: + tags_title: + other: Tags + no_description: + other: The tag has no description. + notification: + action: + update_question: + other: aktualizovaná otázka + answer_the_question: + other: zodpovedaná otázka + update_answer: + other: aktualizovaná odpoveď + accept_answer: + other: prijatá odpoveď + comment_question: + other: komentovaná otázka + comment_answer: + other: komentovaná odpoveď + reply_to_you: + other: odpovedal vám + mention_you: + other: spomenul vás + your_question_is_closed: + other: Vaša otázka bola uzavretá + your_question_was_deleted: + other: Vaša otázka bola odstránená + your_answer_was_deleted: + other: Vaša odpoveď bola odstránená + your_comment_was_deleted: + other: Váš komentár bol odstránený + up_voted_question: + other: upvoted question + down_voted_question: + other: downvoted question + up_voted_answer: + other: upvoted answer + down_voted_answer: + other: downvoted answer + up_voted_comment: + other: upvoted comment + invited_you_to_answer: + other: invited you to answer + earned_badge: + other: You've earned the "{{.BadgeName}}" badge + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Confirm your new email address" + body: + other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} answered your question" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n

        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_question: + title: + other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Password reset" + body: + other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + register: + title: + other: "[{{.SiteName}}] Confirm your new account" + body: + other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + test: + title: + other: "[{{.SiteName}}] Test Email" + body: + other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + action_activity_type: + upvote: + other: upvote + upvoted: + other: upvoted + downvote: + other: downvote + downvoted: + other: downvoted + accept: + other: accept + accepted: + other: accepted + edit: + other: edit + review: + queued_post: + other: Queued post + flagged_post: + other: Flagged post + suggested_post_edit: + other: Suggested edits + reaction: + tooltip: + other: "{{ .Names }} and {{ .Count }} more..." + badge: + default_badges: + autobiographer: + name: + other: Autobiographer + desc: + other: Filled out profile information. + certified: + name: + other: Certified + desc: + other: Completed our new user tutorial. + editor: + name: + other: Editor + desc: + other: First post edit. + first_flag: + name: + other: First Flag + desc: + other: First flagged a post. + first_upvote: + name: + other: First Upvote + desc: + other: First up voted a post. + first_link: + name: + other: First Link + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: First Share + desc: + other: First shared a post. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Leave 5 comments. + new_user_of_the_month: + name: + other: New User of the Month + desc: + other: Outstanding contributions in their first month. + read_guidelines: + name: + other: Read Guidelines + desc: + other: Read the [community guidelines]. + reader: + name: + other: Reader + desc: + other: Read every answers in a topic with more than 10 answers. + welcome: + name: + other: Welcome + desc: + other: Received a up vote. + nice_share: + name: + other: Nice Share + desc: + other: Shared a post with 25 unique visitors. + good_share: + name: + other: Good Share + desc: + other: Shared a post with 300 unique visitors. + great_share: + name: + other: Great Share + desc: + other: Shared a post with 1000 unique visitors. + out_of_love: + name: + other: Out of Love + desc: + other: Used 50 up votes in a day. + higher_love: + name: + other: Higher Love + desc: + other: Used 50 up votes in a day 5 times. + crazy_in_love: + name: + other: Crazy in Love + desc: + other: Used 50 up votes in a day 20 times. + promoter: + name: + other: Promoter + desc: + other: Invited a user. + campaigner: + name: + other: Campaigner + desc: + other: Invited 3 basic users. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: Thank You + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Active member for a year, posted at least once. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Ako formátovať + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Predch + next: Ďalšie + page_title: + question: Otázka + questions: Otázky + tag: Značka + tags: Značky + tag_wiki: značka wiki + create_tag: Vytvoriť štítok + edit_tag: Upraviť značku + ask_a_question: Create Question + edit_question: Úpraviť otázku + edit_answer: Úpraviť odpoveť + search: Vyhľadávanie + posts_containing: Príspevky obsahujúce + settings: Nastavenie + notifications: Oznámenia + login: Prihlásiť sa + sign_up: Prihlásiť Se + account_recovery: Obnovenie účtu + account_activation: Aktivácia účtu + confirm_email: Potvrď e-mail + account_suspended: Účet pozastavený + admin: Administrátor + change_email: Upraviť e-mail + install: Odpoveď Inštalácia + upgrade: Answer Upgrade + maintenance: Údržba webových stránok + users: Užívatelia + oauth_callback: Processing + http_404: HTTP chyba 404 + http_50X: HTTP chyba 403 + http_403: HTTP Error 403 + logout: Log Out + posts: Posts + notifications: + title: Oznámenia + inbox: Doručená pošta + achievement: Úspechy + new_alerts: New alerts + all_read: Označiť všetko ako prečítané + show_more: Zobraziť viac + someone: Someone + inbox_type: + all: All + posts: Posts + invites: Invites + votes: Votes + answer: Answer + question: Question + badge_award: Badge + suspended: + title: Váš účet bol pozastavený + until_time: "Váš účet bol pozastavený do {{ time }}." + forever: Tento používateľ bol navždy pozastavený. + end: Nespĺňate pokyny pre komunitu. + contact_us: Contact us + editor: + blockquote: + text: Blockquote + bold: + text: Silný + chart: + text: Rebríček + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Ganttov diagram + pie_chart: Koláčový graf + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Kód + msg: + empty: Code cannot be empty. + language: + label: Jazyk + placeholder: Automatic detection + btn_cancel: Zrušiť + btn_confirm: Pridať + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Pomoc + hr: + text: Horizontal rule + image: + text: Obrázok + add_image: Pridať obrázok + tab_image: Nahrať obrázok + form_image: + fields: + file: + label: Image file + btn: Vyberte obrázok + msg: + empty: Názov súboru nemôže byť prázdny. + only_image: Povolené sú iba obrázkové súbory. + max_size: File size cannot exceed {{size}} MB. + desc: + label: Popis + tab_url: URL obrázka + form_url: + fields: + url: + label: URL obrázka + msg: + empty: URL obrázka nemôže byť prázdna. + name: + label: Description + btn_cancel: Zrušiť + btn_confirm: Pridať + uploading: Nahráva sa + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hypertextový odkaz + add_link: Pridať hypertextový odkaz + form: + fields: + url: + label: URL + msg: + empty: URL adresa nemôže byť prázdna. + name: + label: Popis + btn_cancel: Zrušiť + btn_confirm: Pridať + ordered_list: + text: Numbered list + unordered_list: + text: Bulleted list + table: + text: Table + heading: Heading + cell: Bunka + file: + text: Attach files + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: Tento príspevok uzatváram ako... + btn_cancel: Zrušiť + btn_submit: Potvrdiť + remark: + empty: Nemôže byť prázdny. + msg: + empty: Vyberte dôvod. + report_modal: + flag_title: Nahlasujem nahlásenie tohto príspevku ako... + close_title: Tento príspevok zatváram ako ... + review_question_title: Kontrola otázky + review_answer_title: Kontrola odpovede + review_comment_title: Kontrola komentára + btn_cancel: Zrušiť + btn_submit: Potvrdiť + remark: + empty: Nemôže byť prázdny. + msg: + empty: Vyberte dôvod. + not_a_url: URL format is incorrect. + url_not_match: URL origin does not match the current website. + tag_modal: + title: Vytvorte novú značku + form: + fields: + display_name: + label: Display name + msg: + empty: Zobrazovaný názov nemôže byť prázdny. + range: Zobrazovaný názov do 35 znakov. + slug_name: + label: URL slug + desc: URL slug do 35 znakov. + msg: + empty: URL slug nemôže byť prázdny. + range: URL slug do 35 znakov. + character: URL slug obsahuje nepovolenú znakovú sadu. + desc: + label: Opis + revision: + label: Revision + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_cancel: Zrušiť + btn_submit: Potvrdiť + btn_post: Post new tag + tag_info: + created_at: Vytvorená + edited_at: Upravená + history: História + synonyms: + title: Synonymá + text: Nasledujúce značky budú premapované na + empty: Nenašli sa žiadne synonymá. + btn_add: Pridajte synonymum + btn_edit: Upraviť + btn_save: Uložiť + synonyms_text: Nasledujúce značky budú premapované na + delete: + title: Odstrániť túto značku + tip_with_posts: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + tip_with_synonyms: >- +

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        + tip: Naozaj chcete odstrániť? + close: Zavrieť + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Upraviť značku + default_reason: Upraviť značku + default_first_reason: Add tag + btn_save_edits: Uložiť úpravy + btn_cancel: Zrušiť + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [o] HH:mm" + now: teraz + x_seconds_ago: "pred {{count}}s" + x_minutes_ago: "pred {{count}}m" + x_hours_ago: "pred {{count}}h" + hour: hodina + day: deň + hours: hours + days: days + month: month + months: months + year: year + reaction: + heart: heart + smile: smile + frown: frown + btn_label: add or remove reactions + undo_emoji: undo {{ emoji }} reaction + react_emoji: react with {{ emoji }} + unreact_emoji: unreact with {{ emoji }} + comment: + btn_add_comment: Pridať komentár + reply_to: Odpovedať + btn_reply: Odpovedať + btn_edit: Upraviť + btn_delete: Zmazať + btn_flag: Vlajka + btn_save_edits: Uložiť zmeny + btn_cancel: Zrušiť + show_more: "{{count}} more comments" + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + tip_vote: It adds something useful to the post + edit_answer: + title: Uprav odpoveď + default_reason: Uprav odpoveď + default_first_reason: Add answer + form: + fields: + revision: + label: Revízia + answer: + label: Odpoveď + feedback: + characters: Obsah musí mať dĺžku najmenej 6 znakov. + edit_summary: + label: Edit summary + placeholder: >- + Stručne vysvetlite svoje zmeny (opravený pravopis, opravená gramatika, vylepšené formátovanie) + btn_save_edits: Uložiť úpravy + btn_cancel: Zrušiť + tags: + title: Značky + sort_buttons: + popular: Populárne + name: názov + newest: Newest + button_follow: Sledovať + button_following: Sledované + tag_label: otázky + search_placeholder: Filtrujte podľa názvu značky + no_desc: Značka nemá popis. + more: Viac + wiki: Wiki + ask: + title: Create Question + edit_title: Upraviť otázku + default_reason: Upraviť otázku + default_first_reason: Create question + similar_questions: Podobné otázky + form: + fields: + revision: + label: Revízia + title: + label: Názov + placeholder: What's your topic? Be specific. + msg: + empty: Názov nemôže byť prázdny. + range: Názov do 150 znakov + body: + label: Telo + msg: + empty: Telo nemôže byť prázdne. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Značky -- + msg: + empty: Štítky nemôžu byť prázdne. + answer: + label: Odpoveď + msg: + empty: Odpoveď nemôže byť prázdna. + edit_summary: + label: Edit summary + placeholder: >- + Stručne vysvetlite svoje zmeny (opravený pravopis, opravená gramatika, vylepšené formátovanie) + btn_post_question: Uverejnite svoju otázku + btn_save_edits: Uložiť úpravy + answer_question: Odpovedzte na svoju vlastnú otázku + post_question&answer: Uverejnite svoju otázku a odpoveď + tag_selector: + add_btn: Pridať značku + create_btn: Vytvoriť novú značku + search_tag: Vyhľadať značku -- + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: Nezodpovedajú žiadne značky + tag_required_text: Povinný štítok (aspoň jeden) + header: + nav: + question: Otázky + tag: Značky + user: Užívatelia + badges: Badges + profile: Profil + setting: Nastavenia + logout: Odhlásiť sa + admin: Správca + review: Preskúmanie + bookmark: Bookmarks + moderation: Moderation + search: + placeholder: Vyhľadávanie + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Zmena + loading: načítavanie... + pic_auth_code: + title: captcha + placeholder: Zadajte vyššie uvedený text + msg: + empty: Captcha nemôže byť prázdna. + inactive: + first: >- + Ste takmer na konci! Poslali sme Vám aktivačný mail na adresu {{mail}}. K aktivácií účtu postupujte prosím podľa pokynov v e-maily. + info: "Ak neprichádza, skontrolujte priečinok spamu." + another: >- + Poslali sme vám ďalší aktivačný e-mail na adresu {{mail}}. Môže to trvať niekoľko minút; Nezabudnite skontrolovať priečinok spamu. + btn_name: Opätovne odoslať aktivačný e-mail + change_btn_name: Zmeniť e-mail + msg: + empty: Nemôže byť prázdny. + resend_email: + url_label: Are you sure you want to resend the activation email? + url_text: You can also give the activation link above to the user. + login: + login_to_continue: Pre pokračovanie sa prihláste + info_sign: Nemáte účet? <1>Sign up + info_login: Máte už účet? <1>Log in + agreements: Registráciou súhlasíte s <1>zásadami ochrany osobných údajov a <3>podmienkami služby. + forgot_pass: Zabudli ste heslo? + name: + label: Prihlasovacie meno + msg: + empty: Prihlasovacie meno nemôže byť prázdne. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: E-mail + msg: + empty: E-mail nemôže byť prázdny. + password: + label: Heslo + msg: + empty: Heslo nemôže byť prázdne. + different: Heslá zadané na oboch stranách sú nekonzistentné + account_forgot: + page_title: Zabudli ste heslo + btn_name: Pošlite mi e-mail na obnovenie + send_success: >- + Ak sa účet zhoduje s {{mail}}, tak by ste mali čoskoro dostať e-mail s pokynmi, ako resetovať svoje heslo. + email: + label: E-mail + msg: + empty: E-mail nemôže byť prázdny. + change_email: + btn_cancel: Zrušiť + btn_update: Aktualizovať e-mailovú adresu + send_success: >- + Ak sa účet zhoduje s {{mail}}, tak by ste mali čoskoro dostať e-mail s pokynmi, ako resetovať svoje heslo. + email: + label: New email + msg: + empty: E-mail nemôže byť prázdny. + oauth: + connect: Connect with {{ auth_name }} + remove: Remove {{ auth_name }} + oauth_bind_email: + subtitle: Add a recovery email to your account. + btn_update: Update email address + email: + label: Email + msg: + empty: Email cannot be empty. + modal_title: Email already existes. + modal_content: This email address already registered. Are you sure you want to connect to the existing account? + modal_cancel: Change email + modal_confirm: Connect to the existing account + password_reset: + page_title: Resetovanie hesla + btn_name: Obnoviť heslo + reset_success: >- + Úspešne ste zmenili svoje heslo; Budete presmerovaný na prihlásenie. + link_invalid: >- + Ospravedlňujeme sa, tento odkaz na obnovenie hesla už nie je platný. Možno už došlo k resetovaniu vašho hesla? + to_login: Continue to log in page + password: + label: Heslo + msg: + empty: Heslo nemôže byť prázdne. + length: Dĺžka musí byť medzi 8 a 32 + different: Heslá zadané na oboch stranách sú nekonzistentné + password_confirm: + label: Confirm new password + settings: + page_title: Nastavenia + goto_modify: Go to modify + nav: + profile: Profil + notification: Oznámenia + account: Účet + interface: Rozhranie + profile: + heading: Profil + btn_name: Uložiť + display_name: + label: Display name + msg: Zobrazované meno nemôže byť prázdne. + msg_range: Display name must be 2-30 characters in length. + username: + label: Užívateľské meno + caption: Ľudia vás môžu spomenúť ako „@používateľské meno“. + msg: Užívateľské meno nemôže byť prázdne. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile image + gravatar: Gravatar + gravatar_text: You can change image on + custom: Vlastný + custom_text: Môžete nahrať svoj obrázok. + default: Systém + msg: Nahrajte avatara prosím + bio: + label: About me + website: + label: Webová stránka + placeholder: "https://priklad.com" + msg: Nesprávny formát webovej stránky + location: + label: Poloha + placeholder: "Mesto, Krajina" + notification: + heading: Email Notifications + turn_on: Turn on + inbox: + label: Inbox notifications + description: Answers to your questions, comments, invites, and more. + all_new_question: + label: All new questions + description: Get notified of all new questions. Up to 50 questions per week. + all_new_question_for_following_tags: + label: All new questions for following tags + description: Get notified of new questions for following tags. + account: + heading: Účet + change_email_btn: Zmeniť e-mail + change_pass_btn: Zmeniť heslo + change_email_info: >- + Na túto adresu sme poslali e-mail. Postupujte podľa pokynov na potvrdenie. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + pass: + label: Current password + msg: Password cannot be empty. + password_title: Heslo + current_pass: + label: Current password + msg: + empty: Current password cannot be empty. + length: Dĺžka musí byť medzi 8 a 32. + different: Dve zadané heslá sa nezhodujú. + new_pass: + label: New password + pass_confirm: + label: Confirm new password + interface: + heading: Rozhranie + lang: + label: Interface language + text: Jazyk používateľského rozhrania. Zmení sa pri obnove stránky. + my_logins: + title: My logins + label: Log in or sign up on this site using these accounts. + modal_title: Remove login + modal_content: Are you sure you want to remove this login from your account? + modal_confirm_btn: Remove + remove_success: Removed successfully + toast: + update: aktualizácia úspešna + update_password: Heslo bolo úspešne zmenené. + flag_success: Ďakujeme za nahlásenie. + forbidden_operate_self: Zakázané operovať seba + review: Vaša revízia sa zobrazí po preskúmaní. + sent_success: Sent successfully + related_question: + title: Related + answers: odpovede + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: People Asked + desc: Select people who you think might know the answer. + invite: Invite to answer + add: Add people + search: Search people + question_detail: + action: Action + created: Created + Asked: Opýtané + asked: opýtané + update: Aktualizované + Edited: Edited + edit: upravené + commented: commented + Views: Videné + Follow: Sledovať + Following: Sledované + follow_tip: Follow this question to receive notifications + answered: zodpovedaný + closed_in: Uzatvorené + show_exist: Ukázať existujúcu otázku. + useful: Useful + question_useful: It is useful and clear + question_un_useful: It is unclear or not useful + question_bookmark: Bookmark this question + answer_useful: It is useful + answer_un_useful: It is not useful + answers: + title: Odpovede + score: Skóre + newest: Najnovšie + oldest: Oldest + btn_accept: Súhlasiť + btn_accepted: Prijaté + write_answer: + title: Vaša odpoveď + edit_answer: Edit my existing answer + btn_name: Pošlite svoju odpoveď + add_another_answer: Pridajte ďalšiu odpoveď + confirm_title: Pokračovať v odpovedi + continue: Pokračovať + confirm_info: >- +

        Ste si istí, že chcete pridať ďalšiu odpoveď?

        Mohli by ste namiesto toho použiť úpravu na vylepšenie svojej už existujúcej odpovede.

        + empty: Odpoveď nemôže byť prázdna. + characters: Minimálna dĺžka obsahu musí byť 6 znakov. + tips: + header_1: Thanks for your answer + li1_1: Please be sure to answer the question. Provide details and share your research. + li1_2: Back up any statements you make with references or personal experience. + header_2: But avoid ... + li2_1: Asking for help, seeking clarification, or responding to other answers. + reopen: + confirm_btn: Reopen + title: Znovu otvoriť tento príspevok + content: Ste si istý, že ho chcete znovu otvoriť? + list: + confirm_btn: List + title: List this post + content: Are you sure you want to list? + unlist: + confirm_btn: Unlist + title: Unlist this post + content: Are you sure you want to unlist? + pin: + title: Pin this post + content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. + confirm_btn: Pin + delete: + title: Odstrániť tento príspevok + question: >- + Neodporúčame mazanie otázok s odpoveďmi pretože týmto oberáte budúcich čitateľov o tieto vedomostí.

        Opakované mazanie zodpovedaných otázok môže mať za následok zablokovanie možnosti kladenia otázok z vášho účtu. Ste si istí, že chcete otázku odstrániť? + answer_accepted: >- +

        Neodporúčame odstránenie akceptovanej odpovede pretože týmto oberáte budúcich čitateľov o tieto vedomostí.

        Opakované mazanie akceptovaných odpovedí môže mať za následok zablokovanie možnosti odpovedať z vášho účtu. Ste si istí, že chcete odstrániť odpoveď? + other: Ste si istí, že ju chcete odstrániť? + tip_answer_deleted: Táto odpoveď bola odstránená + undelete_title: Undelete this post + undelete_desc: Are you sure you wish to undelete? + btns: + confirm: Potvrdiť + cancel: Zrušiť + edit: Edit + save: Uložiť + delete: Vymazať + undelete: Undelete + list: List + unlist: Unlist + unlisted: Unlisted + login: Prihlásiť sa + signup: Registrovať sa + logout: Odhlásiť sa + verify: Preveriť + create: Create + approve: Schváliť + reject: Odmietnuť + skip: Preskočiť + discard_draft: Zahodiť koncept + pinned: Pinned + all: All + question: Question + answer: Answer + comment: Comment + refresh: Refresh + resend: Resend + deactivate: Deactivate + active: Active + suspend: Suspend + unsuspend: Unsuspend + close: Close + reopen: Reopen + ok: OK + light: Light + dark: Dark + system_setting: System setting + default: Default + reset: Reset + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignore + submit: Submit + normal: Normal + closed: Closed + deleted: Deleted + deleted_permanently: Deleted permanently + pending: Pending + more: More + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Výsledky vyhľadávania + keywords: Kľúčové slová + options: možnosti + follow: Sledovať + following: Sledované + counts: "{{count}} výsledky" + counts_loading: "... Results" + more: Viac + sort_btns: + relevance: Relevantnosť + newest: Najnovšie + active: Aktívne + score: Skóre + more: Viac + tips: + title: Tipy na pokročilé vyhľadávanie + tag: "<1>[tag] hľadať v rámci značky" + user: "<1>user:username hľadať podľa autora" + answer: "<1>answers:0 nezodpovedané otázky" + score: "<1>score:3 Príspevky so skóre 3+" + question: "<1>is:question hľadať otázky" + is_answer: "<1>is:answer hľadať odpovede" + empty: Nemohli sme nič nájsť.
        Vyskúšajte iné alebo menej špecifické kľúčové slová. + share: + name: Zdieľať + copy: Skopírovať odkaz + via: Zdieľajte príspevok cez... + copied: Skopírované + facebook: Zdieľať na Facebooku + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post. + modal_confirm: + title: Chyba... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Váš nový účet je potvrdený; Budete presmerovaný na domovskú stránku. + link: Pokračovať na domovskú stránku + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: Váš e-mail bol aktualizovaný. + confirm_new_email_invalid: >- + Ospravedlňujeme sa, tento potvrdzovací odkaz už nie je platný. Váš e-mail je už môžno zmenený. + unsubscribe: + page_title: Zrušiť odber + success_title: Úspešne zrušenie odberu + success_desc: Boli ste úspešne odstránený zo zoznamu odoberateľov a nebudete od nás dostávať žiadne ďalšie e-maily. + link: Zmeniť nastavenia + question: + following_tags: Nasledujúce značky + edit: Upraviť + save: Uložiť + follow_tag_tip: Postupujte podľa značiek a upravte si zoznam otázok. + hot_questions: Najlepšie otázky + all_questions: Všetky otázky + x_questions: "{{ count }} otázky/otázok" + x_answers: "{{ count }} odpovede/odpovedí" + x_posts: "{{ count }} Posts" + questions: Otázky + answers: Odpovede + newest: Najnovšie + active: Aktívne + hot: Hot + frequent: Frequent + recommend: Recommend + score: Skóre + unanswered: Nezodpovedané + modified: upravené + answered: zodpovedané + asked: opýtané + closed: uzatvorené + follow_a_tag: Postupujte podľa značky + more: Viac + personal: + overview: Prehľad + answers: Odpovede + answer: odpoveď + questions: Otázky + question: otázka + bookmarks: Záložky + reputation: Reputácia + comments: Komentáre + votes: Hlasovanie + badges: Badges + newest: Najnovšie + score: Skóre + edit_profile: Edit profile + visited_x_days: "Navštívené {{ count }} dni" + viewed: Videné + joined: Pripojené + comma: "," + last_login: Videné + about_me: O mne + about_me_empty: "// Dobrý deň, svet!" + top_answers: Najlepšie odpovede + top_questions: Najlepšie otázky + stats: Štatistiky + list_empty: Nenašli sa žiadne príspevky.
        Možno by ste chceli vybrať inú kartu? + content_empty: No posts found. + accepted: Prijaté + answered: zodpovedané + asked: opýtané + downvoted: downvoted + mod_short: MOD + mod_long: Moderátori + x_reputation: reputácia + x_votes: prijatých hlasov + x_answers: odpovede + x_questions: otázky + recent_badges: Recent Badges + install: + title: Installation + next: Ďalšie + done: Hotový + config_yaml_error: Nie je možné vytvoriť súbor config.yaml. + lang: + label: Please choose a language + db_type: + label: Database engine + db_username: + label: Užívateľské meno + placeholder: super užívateľ + msg: Užívateľské meno nemôže byť prázdne. + db_password: + label: Heslo + placeholder: super užívateľ + msg: Heslo nemôže byť prázdne. + db_host: + label: Database host + placeholder: "db:3306" + msg: Database host cannot be empty. + db_name: + label: Database name + placeholder: odpoveď + msg: Database name cannot be empty. + db_file: + label: Database file + placeholder: /data/answer.db + msg: Database file cannot be empty. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Vytvoriť config.yaml + label: Vytvorený súbor Config.yaml. + desc: >- + Súbor <1>config.yaml môžete vytvoriť manuálne v adresári <1>/var/www/xxx/ a vložiť doň nasledujúci text. + info: Potom, čo ste to urobili, kliknite na tlačidlo „Ďalej“. + site_information: Informácie o stránke + admin_account: Správca + site_name: + label: Site name + msg: Site name cannot be empty. + msg_max_length: Site name must be at maximum 30 characters in length. + site_url: + label: URL stránky + text: Adresa vašej stránky. + msg: + empty: URL stránky nemôže byť prázdny. + incorrect: Nesprávny formát adresy URL. + max_length: Site URL must be at maximum 512 characters in length. + contact_email: + label: Contact email + text: E-mailová adresa kontaktu zodpovedného za túto stránku. + msg: + empty: Contact email cannot be empty. + incorrect: Contact email incorrect format. + login_required: + label: Private + switch: Login required + text: Only logged in users can access this community. + admin_name: + label: Meno + msg: Meno nemôže byť prázdne. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Heslo + text: >- + Na prihlásenie budete potrebovať toto heslo. Uložte si ho na bezpečné miesto. + msg: Heslo nemôže byť prázdne. + msg_min_length: Password must be at least 8 characters in length. + msg_max_length: Password must be at maximum 32 characters in length. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: E-mail + text: Na prihlásenie budete potrebovať tento e-mail. + msg: + empty: E-mail nemôže byť prázdny. + incorrect: Nesprávny formát e-mailu + ready_title: Your site is ready + ready_desc: >- + Ak niekedy budete chcieť zmeniť viac nastavení, navštívte stránku <1>admin section; Nájdete ju v ponuke stránok. + good_luck: "„Bavte sa a veľa šťastia!“" + warn_title: Upozornenie + warn_desc: >- + Súbor <1>config.yaml už existuje. Ak potrebujete resetovať niektorú z konfiguračných položiek v tomto súbore, najskôr ju odstráňte. + install_now: Môžete skúsiť <1>installing now. + installed: Už nainštalované + installed_desc: >- + Zdá sa, že ste už aplikáciu answer nainštalovali. Ak chcete aplikáciu preinštalovať, najprv vymažte staré tabuľky z databázy. + db_failed: Databázové pripojenie zlyhalo + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: názory + votes: hlasy + answers: odpovede + accepted: prijaté + page_error: + http_error: HTTP Error {{ code }} + desc_403: You don't have permission to access this page. + desc_404: Unfortunately, this page doesn't exist. + desc_50X: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "Prebieha údržba, čoskoro sa vrátime." + nav_menus: + dashboard: Nástenka + contents: Obsah + questions: Otázky + answers: Odpovede + users: Užívatelia + badges: Badges + flags: Vlajky + settings: Nastavenia + general: Všeobecné + interface: Rozhranie + smtp: SMTP + branding: Budovanie značky + legal: legálne + write: písať + terms: Terms + tos: Podmienky služby + privacy: Súkromie + seo: SEO + customize: Prispôsobiť + themes: Témy + login: Prihlásiť sa + privileges: Privileges + plugins: Plugins + installed_plugins: Installed Plugins + apperance: Appearance + website_welcome: Welcome to {{site_name}} + user_center: + login: Login + qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. + login_failed_email_tip: Login failed, please allow this app to access your email information before try again. + badges: + modal: + title: Congratulations + content: You've earned a new badge. + close: Close + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + admin: + admin_header: + title: Administrátor + dashboard: + title: Nástenka + welcome: Welcome to Admin! + site_statistics: Site statistics + questions: "Otázky:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "Odpovede:" + comments: "Komentáre:" + votes: "Hlasy:" + users: "Users:" + flags: "Vlajky:" + reviews: "Reviews:" + site_health: Site health + version: "Verzia:" + https: "HTTPS:" + upload_folder: "Upload folder:" + run_mode: "Running mode:" + private: Private + public: Public + smtp: "SMTP:" + timezone: "Časové pásmo:" + system_info: System info + go_version: "Go version:" + database: "Database:" + database_size: "Database size:" + storage_used: "Použité úložisko:" + uptime: "Doba prevádzky:" + links: Links + plugins: Plugins + github: GitHub + blog: Blog + contact: Contact + forum: Forum + documents: Dokumenty + feedback: Spätná väzba + support: Podpora + review: Preskúmanie + config: Konfigurácia + update_to: Aktualizovať na + latest: Posledné + check_failed: Skontrolovať zlyhanie + "yes": "Áno" + "no": "Nie" + not_allowed: Nepovolené + allowed: Povolené + enabled: Povolené + disabled: Zablokované + writable: Writable + not_writable: Not writable + flags: + title: Vlajky + pending: Prebiehajúce + completed: Dokončené + flagged: Označené + flagged_type: Flagged {{ type }} + created: Vytvorené + action: Akcia + review: Preskúmanie + user_role_modal: + title: Zmeňte rolu používateľa na... + btn_cancel: Zrušiť + btn_submit: Odovzdať + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + edit_profile_modal: + title: Edit profile + form: + fields: + display_name: + label: Display name + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Invalid Email Address. + edit_success: Edited successfully + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + users: + label: Bulk add user + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separate “name, email, password” with commas. One user per line. + msg: "Please enter the user's email, one per line." + display_name: + label: Display name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + users: + title: Používatelia + name: Meno + email: E-mail + reputation: Reputácia + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Stav + role: Rola + action: Akcia + change: Zmena + all: Všetko + staff: Personál + more: More + inactive: Neaktívne + suspended: Pozastavené + deleted: Vymazané + normal: Normálné + Moderator: Moderátor + Admin: Správca + User: Používateľ + filter: + placeholder: "Filter podľa mena, používateľ: ID" + set_new_password: Nastaviť nové heslo + edit_profile: Edit profile + change_status: Zmentiť stavu + change_role: Zmeniť rolu + show_logs: Zobraziť protokoly + add_user: Pridať používateľa + deactivate_user: + title: Deactivate user + content: An inactive user must re-validate their email. + delete_user: + title: Delete this user + content: Are you sure you want to delete this user? This is permanent! + remove: Remove their content + label: Remove all questions, answers, comments, etc. + text: Don’t check this if you wish to only delete the user’s account. + suspend_user: + title: Suspend this user + content: A suspended user can't log in. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Otázky + unlisted: Unlisted + post: poslané + votes: Hlasy + answers: Odpovede + created: Vytvorené + status: Stav + action: Akcia + change: Zmena + pending: Pending + filter: + placeholder: "Filter podľa názvu, otázka:id" + answers: + page_title: Odpovede + post: Poslané + votes: Hlasy + created: Vytvorené + status: Stav + action: Akcia + change: Zmena + filter: + placeholder: "Filter podľa názvu, odpoveď:id" + general: + page_title: Všeobecné + name: + label: Site name + msg: Názov stránky nemôže byť prázdny. + text: "Názov tejto lokality, ako sa používa v značke názvu." + site_url: + label: URL stránky + msg: Adresa Url stránky nemôže byť prázdna. + validate: Prosím uveďte platnú webovú adresu. + text: Adresa vašej stránky. + short_desc: + label: Short site description + msg: Krátky popis stránky nemôže byť prázdny. + text: "Krátky popis, ako sa používa v značke názvu na domovskej stránke." + desc: + label: Site description + msg: Popis stránky nemôže byť prázdny. + text: "Opíšte túto stránku jednou vetou, ako sa používa v značke meta description." + contact_email: + label: Contact email + msg: Kontaktný e-mail nemôže byť prázdny. + validate: Kontaktný e-mail je neplatný. + text: E-mailová adresa kontaktu zodpovedného za túto stránku. + check_update: + label: Software updates + text: Automatically check for updates + interface: + page_title: Rozhranie + language: + label: Interface language + msg: Jazyk rozhrania nemôže byť prázdny. + text: Jazyk používateľského rozhrania. Zmení sa, keď stránku obnovíte. + time_zone: + label: Časové pásmo + msg: Časové pásmo nemôže byť prázdne. + text: Vyberte si mesto v rovnakom časovom pásme ako vy. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: From email + msg: Z e-mailu nemôže byť prázdne. + text: E-mailová adresa, z ktorej sa odosielajú e-maily. + from_name: + label: From name + msg: Názov od nemôže byť prázdny. + text: Meno, z ktorého sa odosielajú e-maily. + smtp_host: + label: SMTP host + msg: Hostiteľ SMTP nemôže byť prázdny. + text: Váš mailový server. + encryption: + label: Šifrovanie + msg: Šifrovanie nemôže byť prázdne. + text: Pre väčšinu serverov je SSL odporúčaná možnosť. + ssl: SSL + tls: TLS + none: Žiadne + smtp_port: + label: SMTP port + msg: Port SMTP musí byť číslo 1 ~ 65535. + text: Port na váš poštový server. + smtp_username: + label: SMTP username + msg: Používateľské meno SMTP nemôže byť prázdne. + smtp_password: + label: SMTP password + msg: Heslo SMTP nemôže byť prázdne. + test_email_recipient: + label: Test email recipients + text: Zadajte e-mailovú adresu, na ktorú sa budú odosielať testy. + msg: Príjemcovia testovacieho e-mailu sú neplatní + smtp_authentication: + label: Povoliť autentifikáciu + title: SMTP authentication + msg: Overenie SMTP nemôže byť prázdne. + "yes": "Áno" + "no": "Nie" + branding: + page_title: Budovanie značky + logo: + label: Logo + msg: Logo nemôže byť prázdne. + text: Obrázok loga v ľavej hornej časti vašej stránky. Použite široký obdĺžnikový obrázok s výškou 56 a pomerom strán väčším ako 3:1. Ak ho ponecháte prázdne, zobrazí sa text názvu stránky. + mobile_logo: + label: Mobile logo + text: Logo použité na mobilnej verzii vášho webu. Použite široký obdĺžnikový obrázok s výškou 56. Ak pole ponecháte prázdne, použije sa obrázok z nastavenia „logo“. + square_icon: + label: Square icon + msg: Ikona štvorca nemôže byť prázdna. + text: Obrázok použitý ako základ pre ikony metadát. V ideálnom prípade by mal byť väčšií ako 512 x 512. + favicon: + label: favicon + text: Favicon pre váš web. Ak chcete správne fungovať cez CDN, musí to byť png. Veľkosť sa zmení na 32 x 32. Ak zostane prázdne, použije sa „štvorcová ikona“. + legal: + page_title: Legálne + terms_of_service: + label: Terms of service + text: "Tu môžete pridať obsah zmluvných podmienok. Ak už máte dokument umiestnený inde, uveďte tu celú URL adresu." + privacy_policy: + label: Privacy policy + text: "Tu môžete pridať obsah zásad ochrany osobných údajov. Ak už máte dokument umiestnený inde, uveďte tu celú URL adresu." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Písať + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Each user can only write one answer for each question + text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Recommend tags + text: "Recommend tags will show in the dropdown list by default." + msg: + contain_reserved: "recommended tags cannot contain reserved tags" + required_tag: + title: Set required tags + label: Set “Recommend tags” as required tags + text: "Každá nová otázka musí mať aspoň jedenu odporúčaciu značku." + reserved_tags: + label: Reserved tags + text: "Reserved tags can only be used by moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: SEO + permalink: + label: trvalý odkaz + text: Vlastné štruktúry URL môžu zlepšiť použiteľnosť a doprednú kompatibilitu vašich odkazov. + robots: + label: robots.txt + text: Toto natrvalo prepíše všetky nastavenia súvisiace so stránkou. + themes: + page_title: Témy + themes: + label: Témy + text: Vyberte existujúcu tému. + color_scheme: + label: Color scheme + navbar_style: + label: Navbar background style + primary_color: + label: Primary color + text: Upraviť farby používané vašími motívmi + css_and_html: + page_title: CSS a HTML + custom_css: + label: Vlastné CSS + text: > + + head: + label: Head + text: > + + header: + label: Hlavička + text: > + + footer: + label: Päta + text: This will insert before </body>. + sidebar: + label: Sidebar + text: This will insert in sidebar. + login: + page_title: Prihlásenie + membership: + title: Členstvo + label: Povoliť nové registrácie + text: Vypnúť, aby sa zabránilo vytvorenie nového účtu hocikým. + email_registration: + title: Email registration + label: Allow email registration + text: Turn off to prevent anyone creating new account through email. + allowed_email_domains: + title: Allowed email domains + text: Email domains that users must register accounts with. One domain per line. Ignored when empty. + private: + title: Súkromné + label: Vyžaduje sa prihlásenie + text: Do tejto komunity majú prístup iba prihlásení používatelia + password_login: + title: Password login + label: Allow email and password login + text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." + installed_plugins: + title: Installed Plugins + plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + filter: + all: All + active: Active + inactive: Inactive + outdated: Outdated + plugins: + label: Plugins + text: Select an existing plugin. + name: Name + version: Version + status: Status + action: Action + deactivate: Deactivate + activate: Activate + settings: Settings + settings_users: + title: Users + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar Base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + profile_editable: + title: Profile editable + allow_update_display_name: + label: Allow users to change their display name + allow_update_username: + label: Allow users to change their username + allow_update_avatar: + label: Allow users to change their profile image + allow_update_bio: + label: Allow users to change their about me + allow_update_website: + label: Allow users to change their website + allow_update_location: + label: Allow users to change their location + privilege: + title: Privileges + level: + label: Reputation required level + text: Choose the reputation required for the privileges + msg: + should_be_number: the input should be number + number_larger_1: number should be equal or larger than 1 + badges: + action: Action + active: Active + activate: Activate + all: All + awards: Awards + deactivate: Deactivate + filter: + placeholder: Filter by name, badge:id + group: Group + inactive: Inactive + name: Name + show_logs: Show logs + status: Status + title: Badges + form: + optional: (voliteľné) + empty: nemôže byť prázdne + invalid: je neplatné + btn_submit: Uložiť + not_found_props: "Požadovaná vlastnosť {{ key }} nebola nájdená." + select: Select + page_review: + review: Preskúmanie + proposed: navrhované + question_edit: Úprava otázky + answer_edit: Úprava odpovede + tag_edit: Úprava značky + edit_summary: Upraviť súhrn + edit_question: Upraviť otázku + edit_answer: Upraviť odpoveď + edit_tag: Upraviť značku + empty: Nezostali žiadne úlohy kontroly. + approve_revision_tip: Do you approve this revision? + approve_flag_tip: Do you approve this flag? + approve_post_tip: Do you approve this post? + approve_user_tip: Do you approve this user? + suggest_edits: Suggested edits + flag_post: Flag post + flag_user: Flag user + queued_post: Queued post + queued_user: Queued user + filter_label: Type + reputation: reputation + flag_post_type: Flagged this post as {{ type }}. + flag_user_type: Flagged this user as {{ type }}. + edit_post: Edit post + list_post: List post + unlist_post: Unlist post + timeline: + undeleted: zrušené zmazanie + deleted: vymazané + downvote: hlasovať proti + upvote: hlasovať za + accept: akceptované + cancelled: zrušené + commented: komentované + rollback: Návrat + edited: zmenené + answered: odpovedané + asked: spýtané + closed: uzavreté + reopened: znovu otvorené + created: vytvorené + pin: pinned + unpin: unpinned + show: listed + hide: unlisted + title: "História pre" + tag_title: "Časová os pre" + show_votes: "Zobraziť hlasy" + n_or_a: N/A + title_for_question: "Časová os pre" + title_for_answer: "Časová os odpovede na {{ title }} od {{ author }}" + title_for_tag: "Časová os pre značku" + datetime: Dátum a čas + type: Typ + by: Od + comment: Komentár + no_data: "Nič sa nám nepodarilo nájsť." + users: + title: Použivatelia + users_with_the_most_reputation: Users with the highest reputation scores this week + users_with_the_most_vote: Users who voted the most this week + staffs: Zamestnanci našej komunity + reputation: reputácia + votes: hlasy + prompt: + leave_page: Ste si istý, že chcete opustiť stránku? + changes_not_save: Vaše zmeny nemusia byť uložené. + draft: + discard_confirm: Naozaj chcete zahodiť svoj koncept? + messages: + post_deleted: Tento príspevok bol odstránený. + post_cancel_deleted: This post has been undeleted. + post_pin: This post has been pinned. + post_unpin: This post has been unpinned. + post_hide_list: This post has been hidden from list. + post_show_list: This post has been shown to list. + post_reopen: This post has been reopened. + post_list: This post has been listed. + post_unlist: This post has been unlisted. + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/sq_AL.yaml b/data/i18n/sq_AL.yaml new file mode 100644 index 000000000..4249c5f03 --- /dev/null +++ b/data/i18n/sq_AL.yaml @@ -0,0 +1,1371 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: "Success." + unknown: + other: "Unknown error." + request_format_error: + other: "Request format is not valid." + unauthorized_error: + other: "Unauthorized." + database_error: + other: "Data server error." + role: + name: + user: + other: "User" + admin: + other: "Admin" + moderator: + other: "Moderator" + description: + user: + other: "Default with no special access." + admin: + other: "Have the full power to access the site." + moderator: + other: "Has access to all posts except admin settings." + email: + other: "Email" + password: + other: "Password" + email_or_password_wrong_error: + other: "Email and password do not match." + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: "Answer do not found." + cannot_deleted: + other: "No permission to delete." + cannot_update: + other: "No permission to update." + comment: + edit_without_permission: + other: "Comment are not allowed to edit." + not_found: + other: "Comment not found." + email: + duplicate: + other: "Email already exists." + need_to_be_verified: + other: "Email should be verified." + verify_url_expired: + other: "Email verified URL has expired, please resend the email." + lang: + not_found: + other: "Language file not found." + object: + captcha_verification_failed: + other: "Captcha wrong." + disallow_follow: + other: "You are not allowed to follow." + disallow_vote: + other: "You are not allowed to vote." + disallow_vote_your_self: + other: "You can't vote for your own post." + not_found: + other: "Object not found." + verification_failed: + other: "Verification failed." + email_or_password_incorrect: + other: "Email and password do not match." + old_password_verification_failed: + other: "The old password verification failed" + new_password_same_as_previous_setting: + other: "The new password is the same as the previous one." + question: + not_found: + other: "Question not found." + cannot_deleted: + other: "No permission to delete." + cannot_close: + other: "No permission to close." + cannot_update: + other: "No permission to update." + rank: + fail_to_meet_the_condition: + other: "Rank fail to meet the condition." + report: + handle_failed: + other: "Report handle failed." + not_found: + other: "Report not found." + tag: + not_found: + other: "Tag not found." + recommend_tag_not_found: + other: "Recommend Tag is not exist." + recommend_tag_enter: + other: "Please enter at least one required tag." + not_contain_synonym_tags: + other: "Should not contain synonym tags." + cannot_update: + other: "No permission to update." + cannot_set_synonym_as_itself: + other: "You cannot set the synonym of the current tag as itself." + smtp: + config_from_name_cannot_be_email: + other: "The From Name cannot be a email address." + theme: + not_found: + other: "Theme not found." + revision: + review_underway: + other: "Can't edit currently, there is a version in the review queue." + no_permission: + other: "No permission to Revision." + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: "User not found." + suspended: + other: "User has been suspended." + username_invalid: + other: "Username is invalid." + username_duplicate: + other: "Username is already in use." + set_avatar: + other: "Avatar set failed." + cannot_update_your_role: + other: "You cannot modify your role." + not_allowed_registration: + other: "Currently the site is not open for registration" + config: + read_config_failed: + other: "Read config failed" + database: + connection_failed: + other: "Database connection failed" + create_table_failed: + other: "Create table failed" + install: + create_config_failed: + other: "Can't create the config.yaml file." + report: + spam: + name: + other: "spam" + desc: + other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." + rude: + name: + other: "rude or abusive" + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + duplicate: + name: + other: "a duplicate" + desc: + other: "This question has been asked before and already has an answer." + not_answer: + name: + other: "not an answer" + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." + not_need: + name: + other: "no longer needed" + desc: + other: "This comment is outdated, conversational or not relevant to this post." + other: + name: + other: "something else" + desc: + other: "This post requires staff attention for another reason not listed above." + question: + close: + duplicate: + name: + other: "spam" + desc: + other: "This question has been asked before and already has an answer." + guideline: + name: + other: "a community-specific reason" + desc: + other: "This question doesn't meet a community guideline." + multiple: + name: + other: "needs details or clarity" + desc: + other: "This question currently includes multiple questions in one. It should focus on one problem only." + other: + name: + other: "something else" + desc: + other: "This post requires another reason not listed above." + operation_type: + asked: + other: "asked" + answered: + other: "answered" + modified: + other: "modified" + notification: + action: + update_question: + other: "updated question" + answer_the_question: + other: "answered question" + update_answer: + other: "updated answer" + accept_answer: + other: "accepted answer" + comment_question: + other: "commented question" + comment_answer: + other: "commented answer" + reply_to_you: + other: "replied to you" + mention_you: + other: "mentioned you" + your_question_is_closed: + other: "Your question has been closed" + your_question_was_deleted: + other: "Your question has been deleted" + your_answer_was_deleted: + other: "Your answer has been deleted" + your_comment_was_deleted: + other: "Your comment has been deleted" +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comment + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to Answer + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name up to 30 characters + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username up to 30 characters + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to Answer + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: "After you've done that, click “Next” button." + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: display_name must be at 2 - 30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8 - 32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/sr_SP.yaml b/data/i18n/sr_SP.yaml new file mode 100644 index 000000000..25c086f11 --- /dev/null +++ b/data/i18n/sr_SP.yaml @@ -0,0 +1,1384 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +#The following fields are used for back-end +backend: + base: + success: + other: Success. + unknown: + other: Unknown error. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + email: + other: Email + password: + other: Password + email_or_password_wrong_error: + other: Email and password do not match. + error: + admin: + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + question: + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + rank: + fail_to_meet_the_condition: + other: Rank fail to meet the condition. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend Tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + smtp: + config_from_name_cannot_be_email: + other: The From Name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to Revision. + user: + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + report: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude: + name: + other: rude or abusive + desc: + other: A reasonable person would find this content inappropriate for respectful discourse. + duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + not_answer: + name: + other: not an answer + desc: + other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. + not_need: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + other: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted +#The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Next + page_title: + question: Question + questions: Questions + tag: Tag + tags: Tags + tag_wiki: tag wiki + edit_tag: Edit Tag + ask_a_question: Add Question + edit_question: Edit Question + edit_answer: Edit Answer + search: Search + posts_containing: Posts containing + settings: Settings + notifications: Notifications + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + notifications: + title: Notifications + inbox: Inbox + achievement: Achievements + all_read: Mark all as read + show_more: Show more + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language (optional) + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal Rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image File + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed 4 MB. + desc: + label: Description (optional) + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description (optional) + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered List + unordered_list: + text: Bulleted List + table: + text: Table + heading: Heading + cell: Cell + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display Name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL Slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description (optional) + btn_cancel: Cancel + btn_submit: Submit + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + content: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + content2: Are you sure you wish to delete? + close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + form: + fields: + revision: + label: Revision + display_name: + label: Display Name + slug_name: + label: URL Slug + info: URL slug up to 35 characters. + desc: + label: Description + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: Show more comments + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + edit_answer: + title: Edit Answer + default_reason: Edit answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + ask: + title: Add Question + edit_title: Edit Question + default_reason: Edit question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: Be specific and imagine you're asking a question to another person + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit Summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: "Describe what your question is about, at least one tag is required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + search: + placeholder: Search + footer: + build_on: >- + Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + login: + page_title: Welcome to {{site_name}} + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + page_title: Welcome to {{site_name}} + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New Email + msg: + empty: Email cannot be empty. + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm New Password + settings: + page_title: Settings + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display Name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile Image + gravatar: Gravatar + gravatar_text: You can change image on <1>gravatar.com + custom: Custom + btn_refresh: Refresh + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About Me (optional) + website: + label: Website (optional) + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location (optional) + placeholder: "City, Country" + notification: + heading: Notifications + email: + label: Email Notifications + radio: "Answers to your questions, comments, and more" + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + password_title: Password + current_pass: + label: Current Password + msg: + empty: Current Password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New Password + pass_confirm: + label: Confirm New Password + interface: + heading: Interface + lang: + label: Interface Language + text: User interface language. It will change when you refresh the page. + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + related_question: + title: Related Questions + btn: Add question + answers: answers + question_detail: + Asked: Asked + asked: asked + update: Modified + edit: edited + Views: Viewed + Follow: Follow + Following: Following + answered: answered + closed_in: Closed in + show_exist: Show existing question. + answers: + title: Answers + score: Score + newest: Newest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + reopen: + title: Reopen this post + content: Are you sure you want to reopen? + success: This post has been reopened + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_question_deleted: This post has been deleted + tip_answer_deleted: This answer has been deleted + btns: + confirm: Confirm + cancel: Cancel + save: Save + delete: Delete + login: Log in + signup: Sign up + logout: Log out + verify: Verify + add_question: Add question + approve: Approve + reject: Reject + skip: Skip + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post + modal_confirm: + title: Error... + account_result: + page_title: Welcome to {{site_name}} + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + invalid: >- + Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + newest: Newest + score: Score + edit_profile: Edit Profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + accepted: Accepted + answered: answered + asked: asked + upvote: upvote + downvote: downvote + mod_short: Mod + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please Choose a Language + db_type: + label: Database Engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database Host + placeholder: "db:3306" + msg: Database Host cannot be empty. + db_name: + label: Database Name + placeholder: answer + msg: Database Name cannot be empty. + db_file: + label: Database File + placeholder: /data/answer.db + msg: Database File cannot be empty. + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site Name + msg: Site Name cannot be empty. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + contact_email: + label: Contact Email + text: Email address of key contact responsible for this site. + msg: + empty: Contact Email cannot be empty. + incorrect: Contact Email incorrect format. + admin_name: + label: Name + msg: Name cannot be empty. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_404: + desc: "Unfortunately, this page doesn't exist." + back_home: Back to homepage + page_50X: + desc: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + css-html: CSS/HTML + login: Login + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site Statistics + questions: "Questions:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + active_users: "Active users:" + flags: "Flags:" + site_health_status: Site Health Status + version: "Version:" + https: "HTTPS:" + uploading_files: "Uploading files:" + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System Info + storage_used: "Storage used:" + uptime: "Uptime:" + answer_links: Answer Links + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + created: Created + action: Action + review: Review + change_modal: + title: Change user status to... + btn_cancel: Cancel + btn_submit: Submit + normal_name: normal + normal_desc: A normal user can ask and answer questions. + suspended_name: suspended + suspended_desc: A suspended user can't log in. + deleted_name: deleted + deleted_desc: "Delete profile, authentication associations." + inactive_name: inactive + inactive_desc: An inactive user must re-validate their email. + confirm_title: Delete this user + confirm_content: Are you sure you want to delete this user? This is permanent! + confirm_btn: Delete + msg: + empty: Please select a reason. + status_modal: + title: "Change {{ type }} status to..." + normal_name: normal + normal_desc: A normal post available to everyone. + closed_name: closed + closed_desc: "A closed question can't answer, but still can edit, vote and comment." + deleted_name: deleted + deleted_desc: All reputation gained and lost will be restored. + btn_cancel: Cancel + btn_submit: Submit + btn_next: Next + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created Time + delete_at: Deleted Time + suspend_at: Suspended Time + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + display_name: + label: Display Name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + questions: + page_title: Questions + normal: Normal + closed: Closed + deleted: Deleted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + normal: Normal + deleted: Deleted + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site Name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short Site Description (optional) + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site Description (optional) + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact Email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + interface: + page_title: Interface + logo: + label: Logo (optional) + msg: Site logo cannot be empty. + text: You can upload your image or <1>reset it to the site title text. + theme: + label: Theme + msg: Theme cannot be empty. + text: Select an existing theme. + language: + label: Interface Language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + smtp: + page_title: SMTP + from_email: + label: From Email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From Name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP Host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + none: None + smtp_port: + label: SMTP Port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP Username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP Password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test Email Recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP Authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo (optional) + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile Logo (optional) + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square Icon (optional) + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon (optional) + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + text: "Please input tag slug above, one tag per line." + required_tag: + title: Required Tag + label: Set recommend tag as required + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved Tags + text: "Reserved tags can only be added to a post by moderator." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + navbar_style: + label: Navbar Style + text: Select an existing theme. + primary_color: + label: Primary Color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: This will insert as + head: + label: Head + text: This will insert before + header: + label: Header + text: This will insert after + footer: + label: Footer + text: This will insert before . + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + form: + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores + users_with_the_most_vote: Users who voted the most + staffs: Our community staff + reputation: reputation + votes: votes diff --git a/data/i18n/sv_SE.yaml b/data/i18n/sv_SE.yaml new file mode 100644 index 000000000..9690e1c66 --- /dev/null +++ b/data/i18n/sv_SE.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Åtgärden lyckades + unknown: + other: Okänt fel. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Access saknas + database_error: + other: Data server error. + forbidden_error: + other: Förbjudet. + duplicate_request_error: + other: Dubblett inlämning. + action: + report: + other: Flagga + edit: + other: Redigera + delete: + other: Radera + close: + other: Stäng + reopen: + other: Öppna igen + forbidden_error: + other: Förbjudet. + pin: + other: Fäst + hide: + other: Göm + unpin: + other: Lossa + show: + other: Lista + invite_someone_to_answer: + other: Redigera + undelete: + other: Återskapa + merge: + other: Sammanfoga + role: + name: + user: + other: Användare + admin: + other: Administratör + moderator: + other: Moderator + description: + user: + other: Normal tillgång + admin: + other: Full kontroll över webbplatsen + moderator: + other: Tillgång till allt utom administratörsinställningar + privilege: + level_1: + description: + other: Nivå 1 + level_2: + description: + other: Nivå 2 + level_3: + description: + other: Nivå 3 + level_custom: + description: + other: Anpassad nivå + rank_question_add_label: + other: Ställ en fråga + rank_answer_add_label: + other: Skriv ett svar + rank_comment_add_label: + other: Skriv en kommentar + rank_report_add_label: + other: Flagga + rank_comment_vote_up_label: + other: Bra kommentar + rank_link_url_limit_label: + other: Mer än 2 länkar samtidigt + rank_question_vote_up_label: + other: Bra fråga + rank_answer_vote_up_label: + other: Bra svar + rank_question_vote_down_label: + other: Dålig fråga + rank_answer_vote_down_label: + other: Dåligt svar + rank_invite_someone_to_answer_label: + other: Bjud in någon att svara + rank_tag_add_label: + other: Skapa ny tagg + rank_tag_edit_label: + other: Beskriv etiketten (behöver granskas) + rank_question_edit_label: + other: Editera annans fråga (behöver granskas) + rank_answer_edit_label: + other: Editera annans svar (behöver granskas) + rank_question_edit_without_review_label: + other: Editera annans fråga utan granskning + rank_answer_edit_without_review_label: + other: Editera annans svar utan granskning + rank_question_audit_label: + other: Granska ändringar av fråga + rank_answer_audit_label: + other: Granska ändringar av svar + rank_tag_audit_label: + other: Granska ändringar av etikett + rank_tag_edit_without_review_label: + other: Ändra etikett-beskrivningen utan granskning + rank_tag_synonym_label: + other: Hantera etikett-synonymer + email: + other: E-post + e_mail: + other: E-post + password: + other: Lösenord + pass: + other: Lösenord + old_pass: + other: Nuvarande lösenord + original_text: + other: Detta inlägg + email_or_password_wrong_error: + other: Fel e-post eller lösenord + error: + common: + invalid_url: + other: Ogiltig URL. + status_invalid: + other: Ogiltig status. + password: + space_invalid: + other: Lösenordet får inte innehålla mellanslag. + admin: + cannot_update_their_password: + other: Du får inte ändra ditt lösenord. + cannot_edit_their_profile: + other: Du får inte ändra din profil. + cannot_modify_self_status: + other: Du får inte ändra din status. + email_or_password_wrong: + other: Fel e-post eller lösenord. + answer: + not_found: + other: Svar hittades inte. + cannot_deleted: + other: Radering tillåts inte. + cannot_update: + other: No permission to update. + question_closed_cannot_add: + other: Questions are closed and cannot be added. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + content_cannot_empty: + other: Kommentarsfältet får inte vara tomt. + email: + duplicate: + other: E-postadressen finns redan. + need_to_be_verified: + other: E-postadressen ska vara verifierad. + verify_url_expired: + other: Länken för att verifiera e-postadressen har gått ut. Vänligen skicka igen. + illegal_email_domain_error: + other: E-post från den domänen tillåts inte. Vänligen använt en annan. + lang: + not_found: + other: Språkfilen hittas inte. + object: + captcha_verification_failed: + other: Fel Captcha. + disallow_follow: + other: Du tillåts inte följa. + disallow_vote: + other: Du tillåts inte rösta. + disallow_vote_your_self: + other: Du får inte rösta på ditt eget inlägg. + not_found: + other: Objektet hittas inte. + verification_failed: + other: Verifiering misslyckades. + email_or_password_incorrect: + other: Fel e-postadress eller lösenord. + old_password_verification_failed: + other: Den gamla verifieringen av lösenordet misslyckades. + new_password_same_as_previous_setting: + other: Det nya lösenordet är samma som det förra. + already_deleted: + other: Det här inlägget har raderats. + meta: + object_not_found: + other: Meta-objekt hittas inte. + question: + already_deleted: + other: Det här inlägget har raderats. + under_review: + other: Ditt inlägg väntar på granskning. Det kommer att publiceras så snart det har blivit godkänt. + not_found: + other: . + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Reputation rank fail to meet the condition. + vote_fail_to_meet_the_condition: + other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. + no_enough_rank_to_operate: + other: You need at least {{.Rank}} reputation to do this. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + already_exist: + other: Tag already exists. + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + is_used_cannot_delete: + other: You cannot delete a tag that is in use. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: The from name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to revise. + user: + external_login_missing_user_id: + other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. + external_login_unbinding_forbidden: + other: Please set a login password for your account before you remove this login. + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration. + not_allowed_login_via_password: + other: Currently the site is not allowed to login via password. + access_denied: + other: Access denied + page_access_denied: + other: You do not have access to this page. + add_bulk_users_format_error: + other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Tabellen kunde inte skapas. + install: + create_config_failed: + other: Filen config.yaml kan inte skapas. + upload: + unsupported_file_format: + other: Filformatet tillåts inte. + site_info: + config_not_found: + other: Webbplats inställningarna hittar inte. + badge: + object_not_found: + other: Badge object not found + reason: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude_or_abusive: + name: + other: rude or abusive + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + a_duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + placeholder: + other: Enter the existing question link + not_a_answer: + name: + other: not an answer + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." + no_longer_needed: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + something: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + placeholder: + other: Let us know specifically what you are concerned about + community_specific: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + not_clarity: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + looks_ok: + name: + other: looks OK + desc: + other: This post is good as-is and not low quality. + needs_edit: + name: + other: needs edit, and I did it + desc: + other: Improve and correct problems with this post yourself. + needs_close: + name: + other: needs close + desc: + other: A closed question can't answer, but still can edit, vote and comment. + needs_delete: + name: + other: needs delete + desc: + other: This post will be deleted. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + deleted_title: + other: Deleted question + questions_title: + other: Questions + tag: + tags_title: + other: Tags + no_description: + other: The tag has no description. + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Din fråga har raderats + your_answer_was_deleted: + other: Ditt svar har raderats + your_comment_was_deleted: + other: Din kommentar har raderats + up_voted_question: + other: upvoted question + down_voted_question: + other: downvoted question + up_voted_answer: + other: upvoted answer + down_voted_answer: + other: downvoted answer + up_voted_comment: + other: upvoted comment + invited_you_to_answer: + other: invited you to answer + earned_badge: + other: You've earned the "{{.BadgeName}}" badge + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Bekräfta din nya e-postadress" + body: + other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} answered your question" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_question: + title: + other: "[{{.SiteName}}] Ny fråga: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Password reset" + body: + other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + register: + title: + other: "[{{.SiteName}}] Bekräfta ditt nya konto" + body: + other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + test: + title: + other: "[{{.SiteName}}] Test Email" + body: + other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + action_activity_type: + upvote: + other: upvote + upvoted: + other: upvoted + downvote: + other: downvote + downvoted: + other: downvoted + accept: + other: accept + accepted: + other: accepted + edit: + other: edit + review: + queued_post: + other: Queued post + flagged_post: + other: Flagged post + suggested_post_edit: + other: Suggested edits + reaction: + tooltip: + other: "{{ .Names }} and {{ .Count }} more..." + badge: + default_badges: + autobiographer: + name: + other: Autobiographer + desc: + other: Filled out profile information. + certified: + name: + other: Certified + desc: + other: Completed our new user tutorial. + editor: + name: + other: Editor + desc: + other: First post edit. + first_flag: + name: + other: First Flag + desc: + other: First flagged a post. + first_upvote: + name: + other: First Upvote + desc: + other: First up voted a post. + first_link: + name: + other: First Link + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: First Share + desc: + other: First shared a post. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Leave 5 comments. + new_user_of_the_month: + name: + other: New User of the Month + desc: + other: Outstanding contributions in their first month. + read_guidelines: + name: + other: Read Guidelines + desc: + other: Read the [community guidelines]. + reader: + name: + other: Reader + desc: + other: Read every answers in a topic with more than 10 answers. + welcome: + name: + other: Welcome + desc: + other: Received a up vote. + nice_share: + name: + other: Nice Share + desc: + other: Shared a post with 25 unique visitors. + good_share: + name: + other: Good Share + desc: + other: Shared a post with 300 unique visitors. + great_share: + name: + other: Great Share + desc: + other: Shared a post with 1000 unique visitors. + out_of_love: + name: + other: Out of Love + desc: + other: Used 50 up votes in a day. + higher_love: + name: + other: Higher Love + desc: + other: Used 50 up votes in a day 5 times. + crazy_in_love: + name: + other: Crazy in Love + desc: + other: Used 50 up votes in a day 20 times. + promoter: + name: + other: Promoter + desc: + other: Invited a user. + campaigner: + name: + other: Campaigner + desc: + other: Invited 3 basic users. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: Thank You + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Active member for a year, posted at least once. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Prev + next: Nästa + page_title: + question: Fråga + questions: Frågor + tag: Tagg + tags: Taggar + tag_wiki: tag wiki + create_tag: Create Tag + edit_tag: Edit Tag + ask_a_question: Create Question + edit_question: Redigera fråga + edit_answer: Redigera svar + search: Sök + posts_containing: Posts containing + settings: Inställningar + notifications: Notifications + login: Logga in + sign_up: Registrera dig + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: Account Suspended + admin: Admin + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Användare + oauth_callback: Processing + http_404: HTTP Error 404 + http_50X: HTTP Error 500 + http_403: HTTP Error 403 + logout: Logga ut + posts: Posts + notifications: + title: Notifications + inbox: Inkorg + achievement: Achievements + new_alerts: New alerts + all_read: Markera alla som lästa + show_more: Visa mer + someone: Someone + inbox_type: + all: Alla + posts: Inlägg + invites: Inbjudningar + votes: Röster + answer: Answer + question: Question + badge_award: Badge + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + contact_us: Kontakta oss + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Kod + msg: + empty: Code cannot be empty. + language: + label: Språk + placeholder: Automatic detection + btn_cancel: Avbryt + btn_confirm: Lägg till + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Hjälp + hr: + text: Horizontal rule + image: + text: Bild + add_image: Lägg till bild + tab_image: Ladda upp bild + form_image: + fields: + file: + label: Image file + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed {{size}} MB. + desc: + label: Beskrivning + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Beskrivning + btn_cancel: Avbryt + btn_confirm: Lägg till + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Beskrivning + btn_cancel: Avbryt + btn_confirm: Lägg till + ordered_list: + text: Numbered list + unordered_list: + text: Bulleted list + table: + text: Tabell + heading: Heading + cell: Cell + file: + text: Attach files + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: I am closing this post as... + btn_cancel: Avbryt + btn_submit: Skicka + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Avbryt + btn_submit: Skicka + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + not_a_url: URL format is incorrect. + url_not_match: URL origin does not match the current website. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Visningsnamn + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Beskrivning + revision: + label: Revision + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_cancel: Avbryt + btn_submit: Skicka + btn_post: Post new tag + tag_info: + created_at: Skapad + edited_at: Edited + history: Historik + synonyms: + title: Synonymer + text: The following tags will be remapped to + empty: Inga synonymer hittades. + btn_add: Lägg till en synonym + btn_edit: Redigera + btn_save: Spara + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + tip_with_posts: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + tip_with_synonyms: >- +

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        + tip: Are you sure you wish to delete? + close: Stäng + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + default_first_reason: Lägg till tagg + btn_save_edits: Save edits + btn_cancel: Avbryt + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: nu + x_seconds_ago: "{{count}} s sedan" + x_minutes_ago: "{{count}} m sedan" + x_hours_ago: "{{count}} t sedan" + hour: timme + day: dag + hours: timmar + days: dagar + month: month + months: months + year: year + reaction: + heart: heart + smile: smile + frown: frown + btn_label: add or remove reactions + undo_emoji: undo {{ emoji }} reaction + react_emoji: react with {{ emoji }} + unreact_emoji: unreact with {{ emoji }} + comment: + btn_add_comment: Lägg till kommentar + reply_to: Reply to + btn_reply: Svara + btn_edit: Redigera + btn_delete: Radera + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Avbryt + show_more: "{{count}} more comments" + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + tip_vote: It adds something useful to the post + edit_answer: + title: Edit Answer + default_reason: Edit answer + default_first_reason: Add answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Avbryt + tags: + title: Tags + sort_buttons: + popular: Popular + name: Namn + newest: Newest + button_follow: Följ + button_following: Följer + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + wiki: Wiki + ask: + title: Create Question + edit_title: Edit Question + default_reason: Edit question + default_first_reason: Create question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: What's your topic? Be specific. + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Användare + badges: Badges + profile: Profil + setting: Inställningar + logout: Logga ut + admin: Admin + review: Review + bookmark: Bokmärken + moderation: Moderation + search: + placeholder: Sök + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Ändra + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + resend_email: + url_label: Are you sure you want to resend the activation email? + url_text: You can also give the activation link above to the user. + login: + login_to_continue: Logga in för att fortsätta + info_sign: Har du inget konto? <1>Registrera dig + info_login: Har du redan ett konto? <1>Logga in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Glömt lösenord? + name: + label: Namn + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: E-postadress + msg: + empty: Email cannot be empty. + password: + label: Lösenord + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Glömt ditt lösenord + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: E-postadress + msg: + empty: Email cannot be empty. + change_email: + btn_cancel: Avbryt + btn_update: Uppdatera e-postadress + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Ny e-postadress + msg: + empty: Email cannot be empty. + oauth: + connect: Connect with {{ auth_name }} + remove: Remove {{ auth_name }} + oauth_bind_email: + subtitle: Add a recovery email to your account. + btn_update: Uppdatera e-postadress + email: + label: Email + msg: + empty: Email cannot be empty. + modal_title: Email already existes. + modal_content: This email address already registered. Are you sure you want to connect to the existing account? + modal_cancel: Change email + modal_confirm: Connect to the existing account + password_reset: + page_title: Password Reset + btn_name: Återställ mitt lösenord + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Lösenord + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Bekräfta nytt lösenord + settings: + page_title: Inställningar + goto_modify: Go to modify + nav: + profile: Profil + notification: Notifications + account: Konto + interface: Interface + profile: + heading: Profil + btn_name: Spara + display_name: + label: Visningsnamn + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Användarnamn + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profilbild + gravatar: Gravatar + gravatar_text: You can change image on + custom: Custom + custom_text: Du kan ladda upp din bild. + default: System + msg: Please upload an avatar + bio: + label: Om mig + website: + label: Webbplats + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location + placeholder: "Stad, Land" + notification: + heading: Email Notifications + turn_on: Turn on + inbox: + label: Inbox notifications + description: Answers to your questions, comments, invites, and more. + all_new_question: + label: All new questions + description: Get notified of all new questions. Up to 50 questions per week. + all_new_question_for_following_tags: + label: All new questions for following tags + description: Get notified of new questions for following tags. + account: + heading: Konto + change_email_btn: Change email + change_pass_btn: Ändra lösenord + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Ny e-postadress + new_email: + label: New email + msg: New email cannot be empty. + pass: + label: Nuvarande lösenord + msg: Password cannot be empty. + password_title: Lösenord + current_pass: + label: Nuvarande lösenord + msg: + empty: Current password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: Nytt lösenord + pass_confirm: + label: Bekräfta nytt lösenord + interface: + heading: Interface + lang: + label: Interface language + text: User interface language. It will change when you refresh the page. + my_logins: + title: My logins + label: Log in or sign up on this site using these accounts. + modal_title: Remove login + modal_content: Are you sure you want to remove this login from your account? + modal_confirm_btn: Remove + remove_success: Removed successfully + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + sent_success: Sent successfully + related_question: + title: Related + answers: answers + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: People Asked + desc: Bjud in personer som du tror kan svara. + invite: Invite to answer + add: Add people + search: Search people + question_detail: + action: Action + created: Created + Asked: Asked + asked: asked + update: Modified + Edited: Edited + edit: edited + commented: commented + Views: Viewed + Follow: Follow + Following: Following + follow_tip: Follow this question to receive notifications + answered: answered + closed_in: Closed in + show_exist: Show existing question. + useful: Useful + question_useful: It is useful and clear + question_un_useful: It is unclear or not useful + question_bookmark: Bookmark this question + answer_useful: It is useful + answer_un_useful: It is not useful + answers: + title: Answers + score: Score + newest: Newest + oldest: Oldest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Ditt svar + edit_answer: Edit my existing answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Fortsätt + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + tips: + header_1: Thanks for your answer + li1_1: Please be sure to answer the question. Provide details and share your research. + li1_2: Back up any statements you make with references or personal experience. + header_2: But avoid ... + li2_1: Asking for help, seeking clarification, or responding to other answers. + reopen: + confirm_btn: Reopen + title: Reopen this post + content: Are you sure you want to reopen? + list: + confirm_btn: List + title: List this post + content: Are you sure you want to list? + unlist: + confirm_btn: Unlist + title: Unlist this post + content: Are you sure you want to unlist? + pin: + title: Pin this post + content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. + confirm_btn: Fäst + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Är du säker på att du vill radera? + tip_answer_deleted: This answer has been deleted + undelete_title: Undelete this post + undelete_desc: Are you sure you wish to undelete? + btns: + confirm: Bekräfta + cancel: Avbryt + edit: Redigera + save: Spara + delete: Radera + undelete: Undelete + list: List + unlist: Unlist + unlisted: Unlisted + login: Logga in + signup: Registrera dig + logout: Logga ut + verify: Verify + create: Create + approve: Approve + reject: Reject + skip: Hoppa över + discard_draft: Discard draft + pinned: Pinned + all: All + question: Question + answer: Answer + comment: Comment + refresh: Uppdatera + resend: Resend + deactivate: Deactivate + active: Active + suspend: Suspend + unsuspend: Unsuspend + close: Stäng + reopen: Reopen + ok: OK + light: Ljust + dark: Mörkt + system_setting: System setting + default: Standard + reset: Återställ + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignorera + submit: Skicka + normal: Normal + closed: Closed + deleted: Deleted + deleted_permanently: Deleted permanently + pending: Pending + more: More + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Sökresultat + keywords: Keywords + options: Alternativ + follow: Follow + following: Following + counts: "{{count}} resultat" + counts_loading: "... Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Dela + copy: Kopiera länk + via: Dela inlägg via... + copied: Copied + facebook: Dela på Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post. + modal_confirm: + title: Error... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: Din e-postadress har uppdaterats. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Redigera + save: Spara + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} frågor" + x_answers: "{{ count }} svar" + x_posts: "{{ count }} Posts" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + frequent: Frequent + recommend: Recommend + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bokmärken + reputation: Reputation + comments: Kommentarer + votes: Röster + badges: Badges + newest: Newest + score: Score + edit_profile: Redigera profil + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + comma: "," + last_login: Seen + about_me: Om mig + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + content_empty: No posts found. + accepted: Accepted + answered: answered + asked: asked + downvoted: downvoted + mod_short: MOD + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + recent_badges: Recent Badges + install: + title: Installation + next: Nästa + done: Klar + config_yaml_error: Can't create the config.yaml file. + lang: + label: Välj ett språk + db_type: + label: Database engine + db_username: + label: Användarnamn + placeholder: root + msg: Username cannot be empty. + db_password: + label: Lösenord + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database host + placeholder: "db:3306" + msg: Database host cannot be empty. + db_name: + label: Databasnamn + placeholder: answer + msg: Database name cannot be empty. + db_file: + label: Database file + placeholder: /data/answer.db + msg: Database file cannot be empty. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Skapa config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site name + msg: Site name cannot be empty. + msg_max_length: Site name must be at maximum 30 characters in length. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + max_length: Site URL must be at maximum 512 characters in length. + contact_email: + label: Contact email + text: Email address of key contact responsible for this site. + msg: + empty: Contact email cannot be empty. + incorrect: Contact email incorrect format. + login_required: + label: Privat + switch: Login required + text: Only logged in users can access this community. + admin_name: + label: Namn + msg: Name cannot be empty. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Lösenord + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + msg_min_length: Password must be at least 8 characters in length. + msg_max_length: Password must be at maximum 32 characters in length. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Varning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_error: + http_error: HTTP Error {{ code }} + desc_403: You don't have permission to access this page. + desc_404: Unfortunately, this page doesn't exist. + desc_50X: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Användare + badges: Badges + flags: Flags + settings: Inställningar + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + terms: Terms + tos: Användarvillkor + privacy: Privacy + seo: SEO + customize: Anpassa + themes: Teman + login: Logga in + privileges: Privileges + plugins: Plugins + installed_plugins: Installed Plugins + apperance: Appearance + website_welcome: Välkommen till {{site_name}} + user_center: + login: Login + qrcode_login_tip: Använd {{ agentName }} för att skanna QR-koden och logga in. + login_failed_email_tip: Login failed, please allow this app to access your email information before try again. + badges: + modal: + title: Grattis + content: You've earned a new badge. + close: Stäng + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site statistics + questions: "Frågor:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "Svar:" + comments: "Kommentarer:" + votes: "Röster:" + users: "Användare:" + flags: "Flags:" + reviews: "Reviews:" + site_health: Site health + version: "Version:" + https: "HTTPS:" + upload_folder: "Upload folder:" + run_mode: "Running mode:" + private: Privat + public: Public + smtp: "SMTP:" + timezone: "Tidszon:" + system_info: System info + go_version: "Go version:" + database: "Databas:" + database_size: "Database size:" + storage_used: "Storage used:" + uptime: "Uptime:" + links: Länkar + plugins: Plugins + github: GitHub + blog: Blogg + contact: Kontakt + forum: Forum + documents: Dokument + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Ja" + "no": "Nej" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + writable: Writable + not_writable: Not writable + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + flagged_type: Flagged {{ type }} + created: Created + action: Action + review: Review + user_role_modal: + title: Ändra användarroll till... + btn_cancel: Avbryt + btn_submit: Skicka + new_password_modal: + title: Set new password + form: + fields: + password: + label: Lösenord + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Avbryt + btn_submit: Skicka + edit_profile_modal: + title: Redigera profil + form: + fields: + display_name: + label: Visningsnamn + msg_range: Display name must be 2-30 characters in length. + username: + label: Användarnamn + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Ogiltig e-postadress. + edit_success: Edited successfully + btn_cancel: Avbryt + btn_submit: Skicka + user_modal: + title: Lägg till ny användare + form: + fields: + users: + label: Bulk add user + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separera "namn, e-postadress, lösenord" med kommatecken. En användare per rad. + msg: "Please enter the user's email, one per line." + display_name: + label: Visningsnamn + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Lösenord + msg: Password must be at 8-32 characters in length. + btn_cancel: Avbryt + btn_submit: Skicka + users: + title: Användare + name: Namn + email: Email + reputation: Reputation + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Status + role: Roll + action: Action + change: Ändra + all: Alla + staff: Staff + more: More + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: Användare + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + edit_profile: Edit profile + change_status: Ändra status + change_role: Ändra roll + show_logs: Visa loggar + add_user: Lägg till användare + deactivate_user: + title: Deactivate user + content: An inactive user must re-validate their email. + delete_user: + title: Delete this user + content: Are you sure you want to delete this user? This is permanent! + remove: Remove their content + label: Remove all questions, answers, comments, etc. + text: Don’t check this if you wish to only delete the user’s account. + suspend_user: + title: Suspend this user + content: A suspended user can't log in. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Questions + unlisted: Unlisted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Ändra + pending: Pending + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Ändra + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Ange en giltig URL. + text: The address of your site. + short_desc: + label: Short site description + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site description + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + check_update: + label: Software updates + text: Automatically check for updates + interface: + page_title: Interface + language: + label: Interface language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Tidszon + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: From email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Kryptering + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + tls: TLS + none: Ingen + smtp_port: + label: SMTP port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test email recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Aktivera autentisering + title: SMTP authentication + msg: SMTP authentication cannot be empty. + "yes": "Ja" + "no": "Nej" + branding: + page_title: Branding + logo: + label: Logo + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile logo + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square icon + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Användarvillkor + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Integritetspolicy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Write + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Each user can only write one answer for each question + text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Recommend tags + text: "Recommend tags will show in the dropdown list by default." + msg: + contain_reserved: "recommended tags cannot contain reserved tags" + required_tag: + title: Set required tags + label: Set “Recommend tags” as required tags + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved tags + text: "Reserved tags can only be used by moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: SEO + permalink: + label: Permalänk + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Teman + themes: + label: Teman + text: Select an existing theme. + color_scheme: + label: Färgschema + navbar_style: + label: Navbar background style + primary_color: + label: Primary color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS och HTML + custom_css: + label: Anpassad CSS + text: > + + head: + label: Head + text: > + + header: + label: Header + text: > + + footer: + label: Footer + text: This will insert before </body>. + sidebar: + label: Sidebar + text: This will insert in sidebar. + login: + page_title: Login + membership: + title: Medlemskap + label: Tillåt nya registreringar + text: Turn off to prevent anyone from creating a new account. + email_registration: + title: Email registration + label: Allow email registration + text: Turn off to prevent anyone creating new account through email. + allowed_email_domains: + title: Allowed email domains + text: Email domains that users must register accounts with. One domain per line. Ignored when empty. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + password_login: + title: Password login + label: Allow email and password login + text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." + installed_plugins: + title: Installed Plugins + plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + filter: + all: Alla + active: Aktiv + inactive: Inaktiv + outdated: Outdated + plugins: + label: Plugins + text: Select an existing plugin. + name: Namn + version: Version + status: Status + action: Action + deactivate: Deactivate + activate: Aktivera + settings: Inställningar + settings_users: + title: Användare + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + profile_editable: + title: Profile editable + allow_update_display_name: + label: Tillåt användare att ändra sitt visningsnamn + allow_update_username: + label: Tillåt användare att ändra sitt användarnamn + allow_update_avatar: + label: Tillåt användare att ändra sin profilbild + allow_update_bio: + label: Allow users to change their about me + allow_update_website: + label: Allow users to change their website + allow_update_location: + label: Allow users to change their location + privilege: + title: Privileges + level: + label: Reputation required level + text: Choose the reputation required for the privileges + msg: + should_be_number: the input should be number + number_larger_1: number should be equal or larger than 1 + badges: + action: Action + active: Aktiv + activate: Aktivera + all: Alla + awards: Awards + deactivate: Inaktivera + filter: + placeholder: Filter by name, badge:id + group: Grupp + inactive: Inaktiv + name: Namn + show_logs: Visa loggar + status: Status + title: Badges + form: + optional: (optional) + empty: cannot be empty + invalid: is invalid + btn_submit: Spara + not_found_props: "Required property {{ key }} not found." + select: Select + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Redigera tagg + empty: No review tasks left. + approve_revision_tip: Do you approve this revision? + approve_flag_tip: Do you approve this flag? + approve_post_tip: Do you approve this post? + approve_user_tip: Do you approve this user? + suggest_edits: Suggested edits + flag_post: Flag post + flag_user: Flag user + queued_post: Queued post + queued_user: Queued user + filter_label: Type + reputation: reputation + flag_post_type: Flagged this post as {{ type }}. + flag_user_type: Flagged this user as {{ type }}. + edit_post: Edit post + list_post: List post + unlist_post: Unlist post + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + pin: pinned + unpin: unpinned + show: listed + hide: unlisted + title: "History for" + tag_title: "Timeline for" + show_votes: "Visa röster" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Användare + users_with_the_most_reputation: Users with the highest reputation scores this week + users_with_the_most_vote: Users who voted the most this week + staffs: Our community staff + reputation: reputation + votes: röster + prompt: + leave_page: Are you sure you want to leave the page? + changes_not_save: Dina ändringar kanske inte sparas. + draft: + discard_confirm: Are you sure you want to discard your draft? + messages: + post_deleted: This post has been deleted. + post_cancel_deleted: This post has been undeleted. + post_pin: This post has been pinned. + post_unpin: This post has been unpinned. + post_hide_list: This post has been hidden from list. + post_show_list: This post has been shown to list. + post_reopen: This post has been reopened. + post_list: This post has been listed. + post_unlist: This post has been unlisted. + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/te_IN.yaml b/data/i18n/te_IN.yaml new file mode 100644 index 000000000..22c24a93c --- /dev/null +++ b/data/i18n/te_IN.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: విజయవంతమైంది. + unknown: + other: తెలియని సమస్య. + request_format_error: + other: Request format is not valid. + unauthorized_error: + other: Unauthorized. + database_error: + other: Data server error. + forbidden_error: + other: Forbidden. + duplicate_request_error: + other: Duplicate submission. + action: + report: + other: Flag + edit: + other: Edit + delete: + other: Delete + close: + other: Close + reopen: + other: Reopen + forbidden_error: + other: Forbidden. + pin: + other: Pin + hide: + other: Unlist + unpin: + other: Unpin + show: + other: List + invite_someone_to_answer: + other: Edit + undelete: + other: Undelete + merge: + other: Merge + role: + name: + user: + other: User + admin: + other: Admin + moderator: + other: Moderator + description: + user: + other: Default with no special access. + admin: + other: Have the full power to access the site. + moderator: + other: Has access to all posts except admin settings. + privilege: + level_1: + description: + other: Level 1 (less reputation required for private team, group) + level_2: + description: + other: Level 2 (low reputation required for startup community) + level_3: + description: + other: Level 3 (high reputation required for mature community) + level_custom: + description: + other: Custom Level + rank_question_add_label: + other: Ask question + rank_answer_add_label: + other: Write answer + rank_comment_add_label: + other: Write comment + rank_report_add_label: + other: Flag + rank_comment_vote_up_label: + other: Upvote comment + rank_link_url_limit_label: + other: Post more than 2 links at a time + rank_question_vote_up_label: + other: Upvote question + rank_answer_vote_up_label: + other: Upvote answer + rank_question_vote_down_label: + other: Downvote question + rank_answer_vote_down_label: + other: Downvote answer + rank_invite_someone_to_answer_label: + other: Invite someone to answer + rank_tag_add_label: + other: Create new tag + rank_tag_edit_label: + other: Edit tag description (need to review) + rank_question_edit_label: + other: Edit other's question (need to review) + rank_answer_edit_label: + other: Edit other's answer (need to review) + rank_question_edit_without_review_label: + other: Edit other's question without review + rank_answer_edit_without_review_label: + other: Edit other's answer without review + rank_question_audit_label: + other: Review question edits + rank_answer_audit_label: + other: Review answer edits + rank_tag_audit_label: + other: Review tag edits + rank_tag_edit_without_review_label: + other: Edit tag description without review + rank_tag_synonym_label: + other: Manage tag synonyms + email: + other: Email + e_mail: + other: Email + password: + other: Password + pass: + other: Password + old_pass: + other: Current password + original_text: + other: This post + email_or_password_wrong_error: + other: Email and password do not match. + error: + common: + invalid_url: + other: Invalid URL. + status_invalid: + other: Invalid status. + password: + space_invalid: + other: Password cannot contain spaces. + admin: + cannot_update_their_password: + other: You cannot modify your password. + cannot_edit_their_profile: + other: You cannot modify your profile. + cannot_modify_self_status: + other: You cannot modify your status. + email_or_password_wrong: + other: Email and password do not match. + answer: + not_found: + other: Answer do not found. + cannot_deleted: + other: No permission to delete. + cannot_update: + other: No permission to update. + question_closed_cannot_add: + other: Questions are closed and cannot be added. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Comment are not allowed to edit. + not_found: + other: Comment not found. + cannot_edit_after_deadline: + other: The comment time has been too long to modify. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: Email already exists. + need_to_be_verified: + other: Email should be verified. + verify_url_expired: + other: Email verified URL has expired, please resend the email. + illegal_email_domain_error: + other: Email is not allowed from that email domain. Please use another one. + lang: + not_found: + other: Language file not found. + object: + captcha_verification_failed: + other: Captcha wrong. + disallow_follow: + other: You are not allowed to follow. + disallow_vote: + other: You are not allowed to vote. + disallow_vote_your_self: + other: You can't vote for your own post. + not_found: + other: Object not found. + verification_failed: + other: Verification failed. + email_or_password_incorrect: + other: Email and password do not match. + old_password_verification_failed: + other: The old password verification failed + new_password_same_as_previous_setting: + other: The new password is the same as the previous one. + already_deleted: + other: This post has been deleted. + meta: + object_not_found: + other: Meta object not found + question: + already_deleted: + other: This post has been deleted. + under_review: + other: Your post is awaiting review. It will be visible after it has been approved. + not_found: + other: Question not found. + cannot_deleted: + other: No permission to delete. + cannot_close: + other: No permission to close. + cannot_update: + other: No permission to update. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Reputation rank fail to meet the condition. + vote_fail_to_meet_the_condition: + other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. + no_enough_rank_to_operate: + other: You need at least {{.Rank}} reputation to do this. + report: + handle_failed: + other: Report handle failed. + not_found: + other: Report not found. + tag: + already_exist: + other: Tag already exists. + not_found: + other: Tag not found. + recommend_tag_not_found: + other: Recommend tag is not exist. + recommend_tag_enter: + other: Please enter at least one required tag. + not_contain_synonym_tags: + other: Should not contain synonym tags. + cannot_update: + other: No permission to update. + is_used_cannot_delete: + other: You cannot delete a tag that is in use. + cannot_set_synonym_as_itself: + other: You cannot set the synonym of the current tag as itself. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: The from name cannot be a email address. + theme: + not_found: + other: Theme not found. + revision: + review_underway: + other: Can't edit currently, there is a version in the review queue. + no_permission: + other: No permission to revise. + user: + external_login_missing_user_id: + other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. + external_login_unbinding_forbidden: + other: Please set a login password for your account before you remove this login. + email_or_password_wrong: + other: + other: Email and password do not match. + not_found: + other: User not found. + suspended: + other: User has been suspended. + username_invalid: + other: Username is invalid. + username_duplicate: + other: Username is already in use. + set_avatar: + other: Avatar set failed. + cannot_update_your_role: + other: You cannot modify your role. + not_allowed_registration: + other: Currently the site is not open for registration. + not_allowed_login_via_password: + other: Currently the site is not allowed to login via password. + access_denied: + other: Access denied + page_access_denied: + other: You do not have access to this page. + add_bulk_users_format_error: + other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Read config failed + database: + connection_failed: + other: Database connection failed + create_table_failed: + other: Create table failed + install: + create_config_failed: + other: Can't create the config.yaml file. + upload: + unsupported_file_format: + other: Unsupported file format. + site_info: + config_not_found: + other: Site config not found. + badge: + object_not_found: + other: Badge object not found + reason: + spam: + name: + other: spam + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude_or_abusive: + name: + other: rude or abusive + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + a_duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + placeholder: + other: Enter the existing question link + not_a_answer: + name: + other: not an answer + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." + no_longer_needed: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + something: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + placeholder: + other: Let us know specifically what you are concerned about + community_specific: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + not_clarity: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + looks_ok: + name: + other: looks OK + desc: + other: This post is good as-is and not low quality. + needs_edit: + name: + other: needs edit, and I did it + desc: + other: Improve and correct problems with this post yourself. + needs_close: + name: + other: needs close + desc: + other: A closed question can't answer, but still can edit, vote and comment. + needs_delete: + name: + other: needs delete + desc: + other: This post will be deleted. + question: + close: + duplicate: + name: + other: spam + desc: + other: This question has been asked before and already has an answer. + guideline: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + multiple: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: something else + desc: + other: This post requires another reason not listed above. + operation_type: + asked: + other: asked + answered: + other: answered + modified: + other: modified + deleted_title: + other: Deleted question + questions_title: + other: Questions + tag: + tags_title: + other: Tags + no_description: + other: The tag has no description. + notification: + action: + update_question: + other: updated question + answer_the_question: + other: answered question + update_answer: + other: updated answer + accept_answer: + other: accepted answer + comment_question: + other: commented question + comment_answer: + other: commented answer + reply_to_you: + other: replied to you + mention_you: + other: mentioned you + your_question_is_closed: + other: Your question has been closed + your_question_was_deleted: + other: Your question has been deleted + your_answer_was_deleted: + other: Your answer has been deleted + your_comment_was_deleted: + other: Your comment has been deleted + up_voted_question: + other: upvoted question + down_voted_question: + other: downvoted question + up_voted_answer: + other: upvoted answer + down_voted_answer: + other: downvoted answer + up_voted_comment: + other: upvoted comment + invited_you_to_answer: + other: invited you to answer + earned_badge: + other: You've earned the "{{.BadgeName}}" badge + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Confirm your new email address" + body: + other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} answered your question" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_question: + title: + other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Password reset" + body: + other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + register: + title: + other: "[{{.SiteName}}] Confirm your new account" + body: + other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + test: + title: + other: "[{{.SiteName}}] Test Email" + body: + other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + action_activity_type: + upvote: + other: upvote + upvoted: + other: upvoted + downvote: + other: downvote + downvoted: + other: downvoted + accept: + other: accept + accepted: + other: accepted + edit: + other: edit + review: + queued_post: + other: Queued post + flagged_post: + other: Flagged post + suggested_post_edit: + other: Suggested edits + reaction: + tooltip: + other: "{{ .Names }} and {{ .Count }} more..." + badge: + default_badges: + autobiographer: + name: + other: Autobiographer + desc: + other: Filled out profile information. + certified: + name: + other: Certified + desc: + other: Completed our new user tutorial. + editor: + name: + other: Editor + desc: + other: First post edit. + first_flag: + name: + other: First Flag + desc: + other: First flagged a post. + first_upvote: + name: + other: First Upvote + desc: + other: First up voted a post. + first_link: + name: + other: First Link + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: First Share + desc: + other: First shared a post. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Leave 5 comments. + new_user_of_the_month: + name: + other: New User of the Month + desc: + other: Outstanding contributions in their first month. + read_guidelines: + name: + other: Read Guidelines + desc: + other: Read the [community guidelines]. + reader: + name: + other: Reader + desc: + other: Read every answers in a topic with more than 10 answers. + welcome: + name: + other: Welcome + desc: + other: Received a up vote. + nice_share: + name: + other: Nice Share + desc: + other: Shared a post with 25 unique visitors. + good_share: + name: + other: Good Share + desc: + other: Shared a post with 300 unique visitors. + great_share: + name: + other: Great Share + desc: + other: Shared a post with 1000 unique visitors. + out_of_love: + name: + other: Out of Love + desc: + other: Used 50 up votes in a day. + higher_love: + name: + other: Higher Love + desc: + other: Used 50 up votes in a day 5 times. + crazy_in_love: + name: + other: Crazy in Love + desc: + other: Used 50 up votes in a day 20 times. + promoter: + name: + other: Promoter + desc: + other: Invited a user. + campaigner: + name: + other: Campaigner + desc: + other: Invited 3 basic users. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: Thank You + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Active member for a year, posted at least once. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: How to Format + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: మునుపటి + next: Next + page_title: + question: ప్రశ్న + questions: ప్రశ్నలు + tag: ట్యాగ్ + tags: టాగ్లు + tag_wiki: tag wiki + create_tag: ట్యాగ్‌ని సృష్టించండి + edit_tag: ట్యాగ్‌ని సవరించండి + ask_a_question: Create Question + edit_question: ప్రశ్నను సవరించండి + edit_answer: సమాధానాన్ని సవరించండి + search: Search + posts_containing: కలిగి ఉన్న పోస్ట్‌లు + settings: Settings + notifications: నోటిఫికేషన్‌లు + login: Log In + sign_up: Sign Up + account_recovery: Account Recovery + account_activation: Account Activation + confirm_email: Confirm Email + account_suspended: ఖాతా నిలిపివేయబడింది + admin: అడ్మిన్ + change_email: Modify Email + install: Answer Installation + upgrade: Answer Upgrade + maintenance: Website Maintenance + users: Users + oauth_callback: Processing + http_404: HTTP Error 404 + http_50X: HTTP Error 500 + http_403: HTTP Error 403 + logout: Log Out + posts: Posts + notifications: + title: నోటిఫికేషన్లు + inbox: ఇన్‌బాక్స్ + achievement: విజయాలు + new_alerts: New alerts + all_read: Mark all as read + show_more: Show more + someone: Someone + inbox_type: + all: All + posts: Posts + invites: Invites + votes: Votes + answer: Answer + question: Question + badge_award: Badge + suspended: + title: Your Account has been Suspended + until_time: "Your account was suspended until {{ time }}." + forever: This user was suspended forever. + end: You don't meet a community guideline. + contact_us: Contact us + editor: + blockquote: + text: Blockquote + bold: + text: Strong + chart: + text: Chart + flow_chart: Flow chart + sequence_diagram: Sequence diagram + class_diagram: Class diagram + state_diagram: State diagram + entity_relationship_diagram: Entity relationship diagram + user_defined_diagram: User defined diagram + gantt_chart: Gantt chart + pie_chart: Pie chart + code: + text: Code Sample + add_code: Add code sample + form: + fields: + code: + label: Code + msg: + empty: Code cannot be empty. + language: + label: Language + placeholder: Automatic detection + btn_cancel: Cancel + btn_confirm: Add + formula: + text: Formula + options: + inline: Inline formula + block: Block formula + heading: + text: Heading + options: + h1: Heading 1 + h2: Heading 2 + h3: Heading 3 + h4: Heading 4 + h5: Heading 5 + h6: Heading 6 + help: + text: Help + hr: + text: Horizontal rule + image: + text: Image + add_image: Add image + tab_image: Upload image + form_image: + fields: + file: + label: Image file + btn: Select image + msg: + empty: File cannot be empty. + only_image: Only image files are allowed. + max_size: File size cannot exceed {{size}} MB. + desc: + label: Description + tab_url: Image URL + form_url: + fields: + url: + label: Image URL + msg: + empty: Image URL cannot be empty. + name: + label: Description + btn_cancel: Cancel + btn_confirm: Add + uploading: Uploading + indent: + text: Indent + outdent: + text: Outdent + italic: + text: Emphasis + link: + text: Hyperlink + add_link: Add hyperlink + form: + fields: + url: + label: URL + msg: + empty: URL cannot be empty. + name: + label: Description + btn_cancel: Cancel + btn_confirm: Add + ordered_list: + text: Numbered list + unordered_list: + text: Bulleted list + table: + text: Table + heading: Heading + cell: Cell + file: + text: Attach files + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: I am closing this post as... + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + report_modal: + flag_title: I am flagging to report this post as... + close_title: I am closing this post as... + review_question_title: Review question + review_answer_title: Review answer + review_comment_title: Review comment + btn_cancel: Cancel + btn_submit: Submit + remark: + empty: Cannot be empty. + msg: + empty: Please select a reason. + not_a_url: URL format is incorrect. + url_not_match: URL origin does not match the current website. + tag_modal: + title: Create new tag + form: + fields: + display_name: + label: Display name + msg: + empty: Display name cannot be empty. + range: Display name up to 35 characters. + slug_name: + label: URL slug + desc: URL slug up to 35 characters. + msg: + empty: URL slug cannot be empty. + range: URL slug up to 35 characters. + character: URL slug contains unallowed character set. + desc: + label: Description + revision: + label: Revision + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_cancel: Cancel + btn_submit: Submit + btn_post: Post new tag + tag_info: + created_at: Created + edited_at: Edited + history: History + synonyms: + title: Synonyms + text: The following tags will be remapped to + empty: No synonyms found. + btn_add: Add a synonym + btn_edit: Edit + btn_save: Save + synonyms_text: The following tags will be remapped to + delete: + title: Delete this tag + tip_with_posts: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + tip_with_synonyms: >- +

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        + tip: Are you sure you wish to delete? + close: Close + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Edit Tag + default_reason: Edit tag + default_first_reason: Add tag + btn_save_edits: Save edits + btn_cancel: Cancel + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: now + x_seconds_ago: "{{count}}s ago" + x_minutes_ago: "{{count}}m ago" + x_hours_ago: "{{count}}h ago" + hour: hour + day: day + hours: hours + days: days + month: month + months: months + year: year + reaction: + heart: heart + smile: smile + frown: frown + btn_label: add or remove reactions + undo_emoji: undo {{ emoji }} reaction + react_emoji: react with {{ emoji }} + unreact_emoji: unreact with {{ emoji }} + comment: + btn_add_comment: Add comment + reply_to: Reply to + btn_reply: Reply + btn_edit: Edit + btn_delete: Delete + btn_flag: Flag + btn_save_edits: Save edits + btn_cancel: Cancel + show_more: "{{count}} more comments" + tip_question: >- + Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. + tip_answer: >- + Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + tip_vote: It adds something useful to the post + edit_answer: + title: Edit Answer + default_reason: Edit answer + default_first_reason: Add answer + form: + fields: + revision: + label: Revision + answer: + label: Answer + feedback: + characters: content must be at least 6 characters in length. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_save_edits: Save edits + btn_cancel: Cancel + tags: + title: Tags + sort_buttons: + popular: Popular + name: Name + newest: Newest + button_follow: Follow + button_following: Following + tag_label: questions + search_placeholder: Filter by tag name + no_desc: The tag has no description. + more: More + wiki: Wiki + ask: + title: Create Question + edit_title: Edit Question + default_reason: Edit question + default_first_reason: Create question + similar_questions: Similar questions + form: + fields: + revision: + label: Revision + title: + label: Title + placeholder: What's your topic? Be specific. + msg: + empty: Title cannot be empty. + range: Title up to 150 characters + body: + label: Body + msg: + empty: Body cannot be empty. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Tags + msg: + empty: Tags cannot be empty. + answer: + label: Answer + msg: + empty: Answer cannot be empty. + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_post_question: Post your question + btn_save_edits: Save edits + answer_question: Answer your own question + post_question&answer: Post your question and answer + tag_selector: + add_btn: Add tag + create_btn: Create new tag + search_tag: Search tag + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: No tags matched + tag_required_text: Required tag (at least one) + header: + nav: + question: Questions + tag: Tags + user: Users + badges: Badges + profile: Profile + setting: Settings + logout: Log out + admin: Admin + review: Review + bookmark: Bookmarks + moderation: Moderation + search: + placeholder: Search + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Change + loading: loading... + pic_auth_code: + title: Captcha + placeholder: Type the text above + msg: + empty: Captcha cannot be empty. + inactive: + first: >- + You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. + info: "If it doesn't arrive, check your spam folder." + another: >- + We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. + btn_name: Resend activation email + change_btn_name: Change email + msg: + empty: Cannot be empty. + resend_email: + url_label: Are you sure you want to resend the activation email? + url_text: You can also give the activation link above to the user. + login: + login_to_continue: Log in to continue + info_sign: Don't have an account? <1>Sign up + info_login: Already have an account? <1>Log in + agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. + forgot_pass: Forgot password? + name: + label: Name + msg: + empty: Name cannot be empty. + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email cannot be empty. + password: + label: Password + msg: + empty: Password cannot be empty. + different: The passwords entered on both sides are inconsistent + account_forgot: + page_title: Forgot Your Password + btn_name: Send me recovery email + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: Email + msg: + empty: Email cannot be empty. + change_email: + btn_cancel: Cancel + btn_update: Update email address + send_success: >- + If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. + email: + label: New email + msg: + empty: Email cannot be empty. + oauth: + connect: Connect with {{ auth_name }} + remove: Remove {{ auth_name }} + oauth_bind_email: + subtitle: Add a recovery email to your account. + btn_update: Update email address + email: + label: Email + msg: + empty: Email cannot be empty. + modal_title: Email already existes. + modal_content: This email address already registered. Are you sure you want to connect to the existing account? + modal_cancel: Change email + modal_confirm: Connect to the existing account + password_reset: + page_title: Password Reset + btn_name: Reset my password + reset_success: >- + You successfully changed your password; you will be redirected to the log in page. + link_invalid: >- + Sorry, this password reset link is no longer valid. Perhaps your password is already reset? + to_login: Continue to log in page + password: + label: Password + msg: + empty: Password cannot be empty. + length: The length needs to be between 8 and 32 + different: The passwords entered on both sides are inconsistent + password_confirm: + label: Confirm new password + settings: + page_title: Settings + goto_modify: Go to modify + nav: + profile: Profile + notification: Notifications + account: Account + interface: Interface + profile: + heading: Profile + btn_name: Save + display_name: + label: Display name + msg: Display name cannot be empty. + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + caption: People can mention you as "@username". + msg: Username cannot be empty. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile image + gravatar: Gravatar + gravatar_text: You can change image on + custom: Custom + custom_text: You can upload your image. + default: System + msg: Please upload an avatar + bio: + label: About me + website: + label: Website + placeholder: "https://example.com" + msg: Website incorrect format + location: + label: Location + placeholder: "City, Country" + notification: + heading: Email Notifications + turn_on: Turn on + inbox: + label: Inbox notifications + description: Answers to your questions, comments, invites, and more. + all_new_question: + label: All new questions + description: Get notified of all new questions. Up to 50 questions per week. + all_new_question_for_following_tags: + label: All new questions for following tags + description: Get notified of new questions for following tags. + account: + heading: Account + change_email_btn: Change email + change_pass_btn: Change password + change_email_info: >- + We've sent an email to that address. Please follow the confirmation instructions. + email: + label: Email + new_email: + label: New email + msg: New email cannot be empty. + pass: + label: Current password + msg: Password cannot be empty. + password_title: Password + current_pass: + label: Current password + msg: + empty: Current password cannot be empty. + length: The length needs to be between 8 and 32. + different: The two entered passwords do not match. + new_pass: + label: New password + pass_confirm: + label: Confirm new password + interface: + heading: Interface + lang: + label: Interface language + text: User interface language. It will change when you refresh the page. + my_logins: + title: My logins + label: Log in or sign up on this site using these accounts. + modal_title: Remove login + modal_content: Are you sure you want to remove this login from your account? + modal_confirm_btn: Remove + remove_success: Removed successfully + toast: + update: update success + update_password: Password changed successfully. + flag_success: Thanks for flagging. + forbidden_operate_self: Forbidden to operate on yourself + review: Your revision will show after review. + sent_success: Sent successfully + related_question: + title: Related + answers: answers + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: People Asked + desc: Select people who you think might know the answer. + invite: Invite to answer + add: Add people + search: Search people + question_detail: + action: Action + created: Created + Asked: Asked + asked: asked + update: Modified + Edited: Edited + edit: edited + commented: commented + Views: Viewed + Follow: Follow + Following: Following + follow_tip: Follow this question to receive notifications + answered: answered + closed_in: Closed in + show_exist: Show existing question. + useful: Useful + question_useful: It is useful and clear + question_un_useful: It is unclear or not useful + question_bookmark: Bookmark this question + answer_useful: It is useful + answer_un_useful: It is not useful + answers: + title: Answers + score: Score + newest: Newest + oldest: Oldest + btn_accept: Accept + btn_accepted: Accepted + write_answer: + title: Your Answer + edit_answer: Edit my existing answer + btn_name: Post your answer + add_another_answer: Add another answer + confirm_title: Continue to answer + continue: Continue + confirm_info: >- +

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        + empty: Answer cannot be empty. + characters: content must be at least 6 characters in length. + tips: + header_1: Thanks for your answer + li1_1: Please be sure to answer the question. Provide details and share your research. + li1_2: Back up any statements you make with references or personal experience. + header_2: But avoid ... + li2_1: Asking for help, seeking clarification, or responding to other answers. + reopen: + confirm_btn: Reopen + title: Reopen this post + content: Are you sure you want to reopen? + list: + confirm_btn: List + title: List this post + content: Are you sure you want to list? + unlist: + confirm_btn: Unlist + title: Unlist this post + content: Are you sure you want to unlist? + pin: + title: Pin this post + content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. + confirm_btn: Pin + delete: + title: Delete this post + question: >- + We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? + answer_accepted: >- +

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? + other: Are you sure you wish to delete? + tip_answer_deleted: This answer has been deleted + undelete_title: Undelete this post + undelete_desc: Are you sure you wish to undelete? + btns: + confirm: Confirm + cancel: Cancel + edit: Edit + save: Save + delete: Delete + undelete: Undelete + list: List + unlist: Unlist + unlisted: Unlisted + login: Log in + signup: Sign up + logout: Log out + verify: Verify + create: Create + approve: Approve + reject: Reject + skip: Skip + discard_draft: Discard draft + pinned: Pinned + all: All + question: Question + answer: Answer + comment: Comment + refresh: Refresh + resend: Resend + deactivate: Deactivate + active: Active + suspend: Suspend + unsuspend: Unsuspend + close: Close + reopen: Reopen + ok: OK + light: Light + dark: Dark + system_setting: System setting + default: Default + reset: Reset + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignore + submit: Submit + normal: Normal + closed: Closed + deleted: Deleted + deleted_permanently: Deleted permanently + pending: Pending + more: More + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Search Results + keywords: Keywords + options: Options + follow: Follow + following: Following + counts: "{{count}} Results" + counts_loading: "... Results" + more: More + sort_btns: + relevance: Relevance + newest: Newest + active: Active + score: Score + more: More + tips: + title: Advanced Search Tips + tag: "<1>[tag] search with a tag" + user: "<1>user:username search by author" + answer: "<1>answers:0 unanswered questions" + score: "<1>score:3 posts with a 3+ score" + question: "<1>is:question search questions" + is_answer: "<1>is:answer search answers" + empty: We couldn't find anything.
        Try different or less specific keywords. + share: + name: Share + copy: Copy link + via: Share post via... + copied: Copied + facebook: Share to Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post. + modal_confirm: + title: Error... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Your new account is confirmed; you will be redirected to the home page. + link: Continue to homepage + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: Your email has been updated. + confirm_new_email_invalid: >- + Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? + unsubscribe: + page_title: Unsubscribe + success_title: Unsubscribe Successful + success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. + link: Change settings + question: + following_tags: Following Tags + edit: Edit + save: Save + follow_tag_tip: Follow tags to curate your list of questions. + hot_questions: Hot Questions + all_questions: All Questions + x_questions: "{{ count }} Questions" + x_answers: "{{ count }} answers" + x_posts: "{{ count }} Posts" + questions: Questions + answers: Answers + newest: Newest + active: Active + hot: Hot + frequent: Frequent + recommend: Recommend + score: Score + unanswered: Unanswered + modified: modified + answered: answered + asked: asked + closed: closed + follow_a_tag: Follow a tag + more: More + personal: + overview: Overview + answers: Answers + answer: answer + questions: Questions + question: question + bookmarks: Bookmarks + reputation: Reputation + comments: Comments + votes: Votes + badges: Badges + newest: Newest + score: Score + edit_profile: Edit profile + visited_x_days: "Visited {{ count }} days" + viewed: Viewed + joined: Joined + comma: "," + last_login: Seen + about_me: About Me + about_me_empty: "// Hello, World !" + top_answers: Top Answers + top_questions: Top Questions + stats: Stats + list_empty: No posts found.
        Perhaps you'd like to select a different tab? + content_empty: No posts found. + accepted: Accepted + answered: answered + asked: asked + downvoted: downvoted + mod_short: MOD + mod_long: Moderators + x_reputation: reputation + x_votes: votes received + x_answers: answers + x_questions: questions + recent_badges: Recent Badges + install: + title: Installation + next: Next + done: Done + config_yaml_error: Can't create the config.yaml file. + lang: + label: Please choose a language + db_type: + label: Database engine + db_username: + label: Username + placeholder: root + msg: Username cannot be empty. + db_password: + label: Password + placeholder: root + msg: Password cannot be empty. + db_host: + label: Database host + placeholder: "db:3306" + msg: Database host cannot be empty. + db_name: + label: Database name + placeholder: answer + msg: Database name cannot be empty. + db_file: + label: Database file + placeholder: /data/answer.db + msg: Database file cannot be empty. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Create config.yaml + label: The config.yaml file created. + desc: >- + You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. + info: After you've done that, click "Next" button. + site_information: Site Information + admin_account: Admin Account + site_name: + label: Site name + msg: Site name cannot be empty. + msg_max_length: Site name must be at maximum 30 characters in length. + site_url: + label: Site URL + text: The address of your site. + msg: + empty: Site URL cannot be empty. + incorrect: Site URL incorrect format. + max_length: Site URL must be at maximum 512 characters in length. + contact_email: + label: Contact email + text: Email address of key contact responsible for this site. + msg: + empty: Contact email cannot be empty. + incorrect: Contact email incorrect format. + login_required: + label: Private + switch: Login required + text: Only logged in users can access this community. + admin_name: + label: Name + msg: Name cannot be empty. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Password + text: >- + You will need this password to log in. Please store it in a secure location. + msg: Password cannot be empty. + msg_min_length: Password must be at least 8 characters in length. + msg_max_length: Password must be at maximum 32 characters in length. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: Email + text: You will need this email to log in. + msg: + empty: Email cannot be empty. + incorrect: Email incorrect format. + ready_title: Your site is ready + ready_desc: >- + If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. + good_luck: "Have fun, and good luck!" + warn_title: Warning + warn_desc: >- + The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. + install_now: You may try <1>installing now. + installed: Already installed + installed_desc: >- + You appear to have already installed. To reinstall please clear your old database tables first. + db_failed: Database connection failed + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: views + votes: votes + answers: answers + accepted: Accepted + page_error: + http_error: HTTP Error {{ code }} + desc_403: You don't have permission to access this page. + desc_404: Unfortunately, this page doesn't exist. + desc_50X: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "We are under maintenance, we'll be back soon." + nav_menus: + dashboard: Dashboard + contents: Contents + questions: Questions + answers: Answers + users: Users + badges: Badges + flags: Flags + settings: Settings + general: General + interface: Interface + smtp: SMTP + branding: Branding + legal: Legal + write: Write + terms: Terms + tos: Terms of Service + privacy: Privacy + seo: SEO + customize: Customize + themes: Themes + login: Login + privileges: Privileges + plugins: Plugins + installed_plugins: Installed Plugins + apperance: Appearance + website_welcome: Welcome to {{site_name}} + user_center: + login: Login + qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. + login_failed_email_tip: Login failed, please allow this app to access your email information before try again. + badges: + modal: + title: Congratulations + content: You've earned a new badge. + close: Close + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + admin: + admin_header: + title: Admin + dashboard: + title: Dashboard + welcome: Welcome to Admin! + site_statistics: Site statistics + questions: "Questions:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "Answers:" + comments: "Comments:" + votes: "Votes:" + users: "Users:" + flags: "Flags:" + reviews: "Reviews:" + site_health: Site health + version: "Version:" + https: "HTTPS:" + upload_folder: "Upload folder:" + run_mode: "Running mode:" + private: Private + public: Public + smtp: "SMTP:" + timezone: "Timezone:" + system_info: System info + go_version: "Go version:" + database: "Database:" + database_size: "Database size:" + storage_used: "Storage used:" + uptime: "Uptime:" + links: Links + plugins: Plugins + github: GitHub + blog: Blog + contact: Contact + forum: Forum + documents: Documents + feedback: Feedback + support: Support + review: Review + config: Config + update_to: Update to + latest: Latest + check_failed: Check failed + "yes": "Yes" + "no": "No" + not_allowed: Not allowed + allowed: Allowed + enabled: Enabled + disabled: Disabled + writable: Writable + not_writable: Not writable + flags: + title: Flags + pending: Pending + completed: Completed + flagged: Flagged + flagged_type: Flagged {{ type }} + created: Created + action: Action + review: Review + user_role_modal: + title: Change user role to... + btn_cancel: Cancel + btn_submit: Submit + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + edit_profile_modal: + title: Edit profile + form: + fields: + display_name: + label: Display name + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Invalid Email Address. + edit_success: Edited successfully + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + users: + label: Bulk add user + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separate “name, email, password” with commas. One user per line. + msg: "Please enter the user's email, one per line." + display_name: + label: Display name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + users: + title: Users + name: Name + email: Email + reputation: Reputation + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Status + role: Role + action: Action + change: Change + all: All + staff: Staff + more: More + inactive: Inactive + suspended: Suspended + deleted: Deleted + normal: Normal + Moderator: Moderator + Admin: Admin + User: User + filter: + placeholder: "Filter by name, user:id" + set_new_password: Set new password + edit_profile: Edit profile + change_status: Change status + change_role: Change role + show_logs: Show logs + add_user: Add user + deactivate_user: + title: Deactivate user + content: An inactive user must re-validate their email. + delete_user: + title: Delete this user + content: Are you sure you want to delete this user? This is permanent! + remove: Remove their content + label: Remove all questions, answers, comments, etc. + text: Don’t check this if you wish to only delete the user’s account. + suspend_user: + title: Suspend this user + content: A suspended user can't log in. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Questions + unlisted: Unlisted + post: Post + votes: Votes + answers: Answers + created: Created + status: Status + action: Action + change: Change + pending: Pending + filter: + placeholder: "Filter by title, question:id" + answers: + page_title: Answers + post: Post + votes: Votes + created: Created + status: Status + action: Action + change: Change + filter: + placeholder: "Filter by title, answer:id" + general: + page_title: General + name: + label: Site name + msg: Site name cannot be empty. + text: "The name of this site, as used in the title tag." + site_url: + label: Site URL + msg: Site url cannot be empty. + validate: Please enter a valid URL. + text: The address of your site. + short_desc: + label: Short site description + msg: Short site description cannot be empty. + text: "Short description, as used in the title tag on homepage." + desc: + label: Site description + msg: Site description cannot be empty. + text: "Describe this site in one sentence, as used in the meta description tag." + contact_email: + label: Contact email + msg: Contact email cannot be empty. + validate: Contact email is not valid. + text: Email address of key contact responsible for this site. + check_update: + label: Software updates + text: Automatically check for updates + interface: + page_title: Interface + language: + label: Interface language + msg: Interface language cannot be empty. + text: User interface language. It will change when you refresh the page. + time_zone: + label: Timezone + msg: Timezone cannot be empty. + text: Choose a city in the same timezone as you. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: From email + msg: From email cannot be empty. + text: The email address which emails are sent from. + from_name: + label: From name + msg: From name cannot be empty. + text: The name which emails are sent from. + smtp_host: + label: SMTP host + msg: SMTP host cannot be empty. + text: Your mail server. + encryption: + label: Encryption + msg: Encryption cannot be empty. + text: For most servers SSL is the recommended option. + ssl: SSL + tls: TLS + none: None + smtp_port: + label: SMTP port + msg: SMTP port must be number 1 ~ 65535. + text: The port to your mail server. + smtp_username: + label: SMTP username + msg: SMTP username cannot be empty. + smtp_password: + label: SMTP password + msg: SMTP password cannot be empty. + test_email_recipient: + label: Test email recipients + text: Provide email address that will receive test sends. + msg: Test email recipients is invalid + smtp_authentication: + label: Enable authentication + title: SMTP authentication + msg: SMTP authentication cannot be empty. + "yes": "Yes" + "no": "No" + branding: + page_title: Branding + logo: + label: Logo + msg: Logo cannot be empty. + text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. + mobile_logo: + label: Mobile logo + text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. + square_icon: + label: Square icon + msg: Square icon cannot be empty. + text: Image used as the base for metadata icons. Should ideally be larger than 512x512. + favicon: + label: Favicon + text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of service + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy policy + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Write + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Each user can only write one answer for each question + text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Recommend tags + text: "Recommend tags will show in the dropdown list by default." + msg: + contain_reserved: "recommended tags cannot contain reserved tags" + required_tag: + title: Set required tags + label: Set “Recommend tags” as required tags + text: "Every new question must have at least one recommend tag." + reserved_tags: + label: Reserved tags + text: "Reserved tags can only be used by moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: SEO + permalink: + label: Permalink + text: Custom URL structures can improve the usability, and forward-compatibility of your links. + robots: + label: robots.txt + text: This will permanently override any related site settings. + themes: + page_title: Themes + themes: + label: Themes + text: Select an existing theme. + color_scheme: + label: Color scheme + navbar_style: + label: Navbar background style + primary_color: + label: Primary color + text: Modify the colors used by your themes + css_and_html: + page_title: CSS and HTML + custom_css: + label: Custom CSS + text: > + + head: + label: Head + text: > + + header: + label: Header + text: > + + footer: + label: Footer + text: This will insert before </body>. + sidebar: + label: Sidebar + text: This will insert in sidebar. + login: + page_title: Login + membership: + title: Membership + label: Allow new registrations + text: Turn off to prevent anyone from creating a new account. + email_registration: + title: Email registration + label: Allow email registration + text: Turn off to prevent anyone creating new account through email. + allowed_email_domains: + title: Allowed email domains + text: Email domains that users must register accounts with. One domain per line. Ignored when empty. + private: + title: Private + label: Login required + text: Only logged in users can access this community. + password_login: + title: Password login + label: Allow email and password login + text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." + installed_plugins: + title: Installed Plugins + plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + filter: + all: All + active: Active + inactive: Inactive + outdated: Outdated + plugins: + label: Plugins + text: Select an existing plugin. + name: Name + version: Version + status: Status + action: Action + deactivate: Deactivate + activate: Activate + settings: Settings + settings_users: + title: Users + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + profile_editable: + title: Profile editable + allow_update_display_name: + label: Allow users to change their display name + allow_update_username: + label: Allow users to change their username + allow_update_avatar: + label: Allow users to change their profile image + allow_update_bio: + label: Allow users to change their about me + allow_update_website: + label: Allow users to change their website + allow_update_location: + label: Allow users to change their location + privilege: + title: Privileges + level: + label: Reputation required level + text: Choose the reputation required for the privileges + msg: + should_be_number: the input should be number + number_larger_1: number should be equal or larger than 1 + badges: + action: Action + active: Active + activate: Activate + all: All + awards: Awards + deactivate: Deactivate + filter: + placeholder: Filter by name, badge:id + group: Group + inactive: Inactive + name: Name + show_logs: Show logs + status: Status + title: Badges + form: + optional: (optional) + empty: cannot be empty + invalid: is invalid + btn_submit: Save + not_found_props: "Required property {{ key }} not found." + select: Select + page_review: + review: Review + proposed: proposed + question_edit: Question edit + answer_edit: Answer edit + tag_edit: Tag edit + edit_summary: Edit summary + edit_question: Edit question + edit_answer: Edit answer + edit_tag: Edit tag + empty: No review tasks left. + approve_revision_tip: Do you approve this revision? + approve_flag_tip: Do you approve this flag? + approve_post_tip: Do you approve this post? + approve_user_tip: Do you approve this user? + suggest_edits: Suggested edits + flag_post: Flag post + flag_user: Flag user + queued_post: Queued post + queued_user: Queued user + filter_label: Type + reputation: reputation + flag_post_type: Flagged this post as {{ type }}. + flag_user_type: Flagged this user as {{ type }}. + edit_post: Edit post + list_post: List post + unlist_post: Unlist post + timeline: + undeleted: undeleted + deleted: deleted + downvote: downvote + upvote: upvote + accept: accept + cancelled: cancelled + commented: commented + rollback: rollback + edited: edited + answered: answered + asked: asked + closed: closed + reopened: reopened + created: created + pin: pinned + unpin: unpinned + show: listed + hide: unlisted + title: "History for" + tag_title: "Timeline for" + show_votes: "Show votes" + n_or_a: N/A + title_for_question: "Timeline for" + title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" + title_for_tag: "Timeline for tag" + datetime: Datetime + type: Type + by: By + comment: Comment + no_data: "We couldn't find anything." + users: + title: Users + users_with_the_most_reputation: Users with the highest reputation scores this week + users_with_the_most_vote: Users who voted the most this week + staffs: Our community staff + reputation: reputation + votes: votes + prompt: + leave_page: Are you sure you want to leave the page? + changes_not_save: Your changes may not be saved. + draft: + discard_confirm: Are you sure you want to discard your draft? + messages: + post_deleted: This post has been deleted. + post_cancel_deleted: This post has been undeleted. + post_pin: This post has been pinned. + post_unpin: This post has been unpinned. + post_hide_list: This post has been hidden from list. + post_show_list: This post has been shown to list. + post_reopen: This post has been reopened. + post_list: This post has been listed. + post_unlist: This post has been unlisted. + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/tr_TR.yaml b/data/i18n/tr_TR.yaml new file mode 100644 index 000000000..802a81f69 --- /dev/null +++ b/data/i18n/tr_TR.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Başarılı. + unknown: + other: Bilinmeyen hata. + request_format_error: + other: İstek formatı geçerli değil. + unauthorized_error: + other: Yetkisiz erişim. + database_error: + other: Veri tabanı sunucu hatası. + forbidden_error: + other: Erişim engellendi. + duplicate_request_error: + other: Yinelenen gönderim. + action: + report: + other: Bildir + edit: + other: Düzenle + delete: + other: Sil + close: + other: Kapat + reopen: + other: Yeniden Aç + forbidden_error: + other: Erişim engellendi. + pin: + other: Sabitle + hide: + other: Listeden Kaldır + unpin: + other: Sabitlemeyi Kaldır + show: + other: Listele + invite_someone_to_answer: + other: Cevaplamaya Davet Et + undelete: + other: Silmeyi Geri Al + merge: + other: Birleştir + role: + name: + user: + other: Kullanıcı + admin: + other: Yönetici + moderator: + other: Moderatör + description: + user: + other: Özel erişimi olmayan varsayılan kullanıcı. + admin: + other: Siteye tam erişim gücüne sahiptir. + moderator: + other: Yönetici ayarları dışında tüm gönderilere erişebilir. + privilege: + level_1: + description: + other: Seviye 1 (özel takım, grup için daha az itibar gerektirir) + level_2: + description: + other: Seviye 2 (başlangıç topluluğu için düşük itibar gerektirir) + level_3: + description: + other: Seviye 3 (gelişmiş topluluk için yüksek itibar gerektirir) + level_custom: + description: + other: Özel Seviye + rank_question_add_label: + other: Soru sor + rank_answer_add_label: + other: Cevap yaz + rank_comment_add_label: + other: Yorum yaz + rank_report_add_label: + other: Bildir + rank_comment_vote_up_label: + other: Yorumu yukarı oyla + rank_link_url_limit_label: + other: Bir seferde 2'den fazla bağlantı paylaş + rank_question_vote_up_label: + other: Soruyu yukarı oyla + rank_answer_vote_up_label: + other: Cevabı yukarı oyla + rank_question_vote_down_label: + other: Soruyu aşağı oyla + rank_answer_vote_down_label: + other: Cevabı aşağı oyla + rank_invite_someone_to_answer_label: + other: Birini cevaplamaya davet et + rank_tag_add_label: + other: Yeni etiket oluştur + rank_tag_edit_label: + other: Etiket açıklamasını düzenle (inceleme gerekli) + rank_question_edit_label: + other: Başkasının sorusunu düzenle (inceleme gerekli) + rank_answer_edit_label: + other: Başkasının cevabını düzenle (inceleme gerekli) + rank_question_edit_without_review_label: + other: Başkasının sorusunu inceleme olmadan düzenle + rank_answer_edit_without_review_label: + other: Başkasının cevabını inceleme olmadan düzenle + rank_question_audit_label: + other: Soru düzenlemelerini incele + rank_answer_audit_label: + other: Cevap düzenlemelerini incele + rank_tag_audit_label: + other: Etiket düzenlemelerini incele + rank_tag_edit_without_review_label: + other: Etiket açıklamasını inceleme olmadan düzenle + rank_tag_synonym_label: + other: Etiket eş anlamlılarını yönet + email: + other: E-posta + e_mail: + other: E-posta + password: + other: Parola + pass: + other: Parola + old_pass: + other: Mevcut parola + original_text: + other: Bu gönderi + email_or_password_wrong_error: + other: E-posta ve parola eşleşmiyor. + error: + common: + invalid_url: + other: Geçersiz URL. + status_invalid: + other: Geçersiz durum. + password: + space_invalid: + other: Parola boşluk içeremez. + admin: + cannot_update_their_password: + other: Parolanızı değiştiremezsiniz. + cannot_edit_their_profile: + other: Profilinizi değiştiremezsiniz. + cannot_modify_self_status: + other: Durumunuzu değiştiremezsiniz. + email_or_password_wrong: + other: E-posta ve parola eşleşmiyor. + answer: + not_found: + other: Cevap bulunamadı. + cannot_deleted: + other: Silme izni yok. + cannot_update: + other: Güncelleme izni yok. + question_closed_cannot_add: + other: Sorular kapatıldı ve cevap eklenemez. + content_cannot_empty: + other: Cevap içeriği boş olamaz. + comment: + edit_without_permission: + other: Yorumları düzenleme izniniz yok. + not_found: + other: Yorum bulunamadı. + cannot_edit_after_deadline: + other: Yorum süresi çok uzun olduğu için artık düzenlenemez. + content_cannot_empty: + other: Yorum içeriği boş olamaz. + email: + duplicate: + other: Bu e-posta adresi zaten kullanılmaktadır. + need_to_be_verified: + other: E-posta doğrulanmalıdır. + verify_url_expired: + other: E-posta doğrulama URL'sinin süresi dolmuş, lütfen e-postayı yeniden gönderin. + illegal_email_domain_error: + other: Bu e-posta alan adına izin verilmiyor. Lütfen başka bir e-posta kullanın. + lang: + not_found: + other: Dil dosyası bulunamadı. + object: + captcha_verification_failed: + other: Captcha yanlış. + disallow_follow: + other: Takip etme izniniz yok. + disallow_vote: + other: Oy verme izniniz yok. + disallow_vote_your_self: + other: Kendi gönderinize oy veremezsiniz. + not_found: + other: Nesne bulunamadı. + verification_failed: + other: Doğrulama başarısız. + email_or_password_incorrect: + other: E-posta ve parola eşleşmiyor. + old_password_verification_failed: + other: Eski parola doğrulaması başarısız oldu. + new_password_same_as_previous_setting: + other: Yeni parola öncekiyle aynı. + already_deleted: + other: Bu gönderi silinmiş. + meta: + object_not_found: + other: Meta nesnesi bulunamadı. + question: + already_deleted: + other: Bu gönderi silinmiş. + under_review: + other: Gönderiniz inceleme bekliyor. Onaylandıktan sonra görünür olacaktır. + not_found: + other: Soru bulunamadı. + cannot_deleted: + other: Silme izni yok. + cannot_close: + other: Kapatma izni yok. + cannot_update: + other: Güncelleme izni yok. + content_cannot_empty: + other: İçerik boş olamaz. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: İtibar seviyesi koşulu karşılamıyor. + vote_fail_to_meet_the_condition: + other: Geri bildiriminiz için teşekkürler. Oy kullanmak için en az {{.Rank}} itibara ihtiyacınız var. + no_enough_rank_to_operate: + other: Bu işlemi yapmak için en az {{.Rank}} itibara ihtiyacınız var. + report: + handle_failed: + other: Rapor işleme başarısız. + not_found: + other: Rapor bulunamadı. + tag: + already_exist: + other: Etiket zaten var. + not_found: + other: Etiket bulunamadı. + recommend_tag_not_found: + other: Önerilen etiket mevcut değil. + recommend_tag_enter: + other: Lütfen en az bir adet gerekli etiket giriniz. + not_contain_synonym_tags: + other: Eş anlamlı etiketler içermemelidir. + cannot_update: + other: Güncelleme izni yok. + is_used_cannot_delete: + other: Kullanımda olan bir etiketi silemezsiniz. + cannot_set_synonym_as_itself: + other: Bir etiketin eş anlamlısını kendisi olarak ayarlayamazsınız. + minimum_count: + other: Yeterli sayıda etiket girilmedi. + smtp: + config_from_name_cannot_be_email: + other: Gönderen adı bir e-posta adresi olamaz. + theme: + not_found: + other: Tema bulunamadı. + revision: + review_underway: + other: Şu anda düzenlenemez, inceleme kuyruğunda bir sürüm var. + no_permission: + other: Düzenleme izniniz yok. + user: + external_login_missing_user_id: + other: Üçüncü taraf platform benzersiz bir Kullanıcı ID'si sağlamıyor, bu nedenle giriş yapamazsınız. Lütfen site yöneticisiyle iletişime geçin. + external_login_unbinding_forbidden: + other: Bu girişi kaldırmadan önce lütfen hesabınız için bir giriş parolası ayarlayın. + email_or_password_wrong: + other: + other: E-posta ve parola eşleşmiyor. + not_found: + other: Kullanıcı bulunamadı. + suspended: + other: Kullanıcı askıya alındı. + username_invalid: + other: Kullanıcı adı geçersiz. + username_duplicate: + other: Kullanıcı adı zaten kullanımda. + set_avatar: + other: Avatar ayarlama başarısız. + cannot_update_your_role: + other: Kendi rolünüzü değiştiremezsiniz. + not_allowed_registration: + other: Şu anda site kayıt için açık değil. + not_allowed_login_via_password: + other: Şu anda site parola ile giriş yapmaya izin vermiyor. + access_denied: + other: Erişim reddedildi. + page_access_denied: + other: Bu sayfaya erişim izniniz yok. + add_bulk_users_format_error: + other: "{{.Line}} satırındaki '{{.Content}}' içeriğinde {{.Field}} biçimi hatası. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "Bir kerede eklediğiniz kullanıcı sayısı 1-{{.MaxAmount}} aralığında olmalıdır." + status_suspended_forever: + other: "Bu kullanıcı süresiz olarak askıya alındı. Bu kullanıcı topluluk kurallarını karşılamıyor." + status_suspended_until: + other: "Bu kullanıcı {{.SuspendedUntil}} tarihine kadar askıya alındı. Bu kullanıcı topluluk kurallarını karşılamıyor." + status_deleted: + other: "Bu kullanıcı silindi." + status_inactive: + other: "Bu kullanıcı aktif değil." + config: + read_config_failed: + other: Yapılandırma okunamadı. + database: + connection_failed: + other: Veritabanı bağlantısı başarısız. + create_table_failed: + other: Tablo oluşturma başarısız. + install: + create_config_failed: + other: config.yaml dosyası oluşturulamıyor. + upload: + unsupported_file_format: + other: Desteklenmeyen dosya formatı. + site_info: + config_not_found: + other: Site yapılandırması bulunamadı. + badge: + object_not_found: + other: Rozet nesnesi bulunamadı. + reason: + spam: + name: + other: spam + desc: + other: Bu gönderi bir reklam veya vandalizm. Mevcut konuyla ilgili veya yararlı değil. + rude_or_abusive: + name: + other: kaba veya taciz edici + desc: + other: "Makul bir kişi bu içeriği saygılı bir iletişim için uygunsuz bulurdu." + a_duplicate: + name: + other: kopya + desc: + other: Bu soru daha önce sorulmuş ve cevaplandırılmış. + placeholder: + other: Mevcut soru bağlantısını girin + not_a_answer: + name: + other: cevap değil + desc: + other: "Bu bir cevap olarak gönderilmiş, ancak soruyu cevaplamaya çalışmıyor. Bir düzenleme, yorum, başka bir soru olabilir veya tamamen silinmesi gerekebilir." + no_longer_needed: + name: + other: artık gerekli değil + desc: + other: Bu yorum güncelliğini yitirmiş, sohbet niteliğinde veya bu gönderiyle ilgili değil. + something: + name: + other: başka bir şey + desc: + other: Bu gönderi, yukarıda listelenmeyen başka bir nedenden dolayı personel ilgisi gerektiriyor. + placeholder: + other: Endişelerinizin ne olduğunu spesifik olarak belirtin + community_specific: + name: + other: topluluk kurallarına aykırı + desc: + other: Bu soru bir topluluk kılavuzuna uymuyor. + not_clarity: + name: + other: detay veya açıklık gerekiyor + desc: + other: Bu soru şu anda tek soruda birden fazla soru içeriyor. Sadece tek bir soruna odaklanmalı. + looks_ok: + name: + other: iyi görünüyor + desc: + other: Bu gönderi olduğu gibi iyi ve düşük kaliteli değil. + needs_edit: + name: + other: düzenleme gerektiriyor ve ben yaptım + desc: + other: Bu gönderideki sorunları kendiniz düzeltin ve iyileştirin. + needs_close: + name: + other: kapatılması gerekiyor + desc: + other: Kapatılmış bir soru cevaplanamaz, ancak düzenlenebilir, oylanabilir ve yorum yapılabilir. + needs_delete: + name: + other: silinmesi gerekiyor + desc: + other: Bu gönderi silinecek. + question: + close: + duplicate: + name: + other: kopya + desc: + other: Bu soru daha önce sorulmuş ve cevaplandırılmış. + guideline: + name: + other: topluluk kurallarına aykırı + desc: + other: Bu soru bir topluluk kılavuzuna uymuyor. + multiple: + name: + other: detay veya açıklık gerekiyor + desc: + other: Bu soru şu anda tek soruda birden fazla soru içeriyor. Sadece tek bir soruna odaklanmalı. + other: + name: + other: başka bir şey + desc: + other: Bu gönderi yukarıda listelenmeyen başka bir neden gerektiriyor. + operation_type: + asked: + other: soruldu + answered: + other: cevaplandı + modified: + other: değiştirildi + deleted_title: + other: Silinmiş soru + questions_title: + other: Sorular + tag: + tags_title: + other: Etiketler + no_description: + other: Bu etiketin açıklaması yok. + notification: + action: + update_question: + other: soruyu güncelledi + answer_the_question: + other: soruyu cevapladı + update_answer: + other: cevabı güncelledi + accept_answer: + other: cevabı kabul etti + comment_question: + other: soruya yorum yaptı + comment_answer: + other: cevaba yorum yaptı + reply_to_you: + other: size yanıt verdi + mention_you: + other: sizden bahsetti + your_question_is_closed: + other: Sorunuz kapatıldı + your_question_was_deleted: + other: Sorunuz silindi + your_answer_was_deleted: + other: Cevabınız silindi + your_comment_was_deleted: + other: Yorumunuz silindi + up_voted_question: + other: soruyu yukarı oyladı + down_voted_question: + other: soruyu aşağı oyladı + up_voted_answer: + other: cevabı yukarı oyladı + down_voted_answer: + other: cevabı aşağı oyladı + up_voted_comment: + other: yorumu yukarı oyladı + invited_you_to_answer: + other: sizi cevaplamaya davet etti + earned_badge: + other: Rozet kazandınız "{{.BadgeName}}" + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Yeni e-posta adresinizi onaylayın" + body: + other: "{{.SiteName}} için aşağıdaki bağlantıya tıklayarak yeni e-posta adresinizi onaylayın:
        \n{{.ChangeEmailUrl}}

        \n\nEğer bu değişikliği siz talep etmediyseniz, lütfen bu e-postayı dikkate almayın.

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} sorunuzu cevapladı" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \n{{.SiteName}} üzerinde görüntüle

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir.

        \n\nAbonelikten çık" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} sizi cevaplamaya davet etti" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Cevabı biliyor olabileceğinizi düşünüyorum.

        \n{{.SiteName}} üzerinde görüntüle

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir.

        \n\nAbonelikten çık" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} gönderinize yorum yaptı" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \n{{.SiteName}} üzerinde görüntüle

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir.

        \n\nAbonelikten çık" + new_question: + title: + other: "[{{.SiteName}}] Yeni soru: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir.

        \n\nAbonelikten çık" + pass_reset: + title: + other: "[{{.SiteName }}] Parola sıfırlama" + body: + other: "Birisi {{.SiteName}} üzerindeki parolanızı sıfırlamak istedi.

        \n\nEğer bu siz değilseniz, bu e-postayı güvenle görmezden gelebilirsiniz.

        \n\nYeni bir parola seçmek için aşağıdaki bağlantıya tıklayın:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir." + register: + title: + other: "[{{.SiteName}}] Yeni hesabınızı onaylayın" + body: + other: "{{.SiteName}} sitesine hoş geldiniz!

        \n\nYeni hesabınızı onaylamak ve etkinleştirmek için aşağıdaki bağlantıya tıklayın:
        \n{{.RegisterUrl}}

        \n\nYukarıdaki bağlantı tıklanabilir değilse, web tarayıcınızın adres çubuğuna kopyalayıp yapıştırmayı deneyin.\n

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir." + test: + title: + other: "[{{.SiteName}}] Test E-postası" + body: + other: "Bu bir test e-postasıdır.\n

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir." + action_activity_type: + upvote: + other: yukarı oyla + upvoted: + other: yukarı oyladı + downvote: + other: aşağı oyla + downvoted: + other: aşağı oyladı + accept: + other: kabul et + accepted: + other: kabul edildi + edit: + other: düzenle + review: + queued_post: + other: Sıradaki gönderi + flagged_post: + other: Bildirilen gönderi + suggested_post_edit: + other: Önerilen düzenlemeler + reaction: + tooltip: + other: "{{ .Names }} ve {{ .Count }} kişi daha..." + badge: + default_badges: + autobiographer: + name: + other: Otobiyografi Yazarı + desc: + other: Profil bilgilerini doldurdu. + certified: + name: + other: Sertifikalı + desc: + other: Yeni kullanıcı eğitimimizi tamamladı. + editor: + name: + other: Editör + desc: + other: İlk gönderi düzenlemesi. + first_flag: + name: + other: İlk Bildirim + desc: + other: İlk kez bir gönderiyi bildirdi. + first_upvote: + name: + other: İlk Yukarı Oylama + desc: + other: İlk kez bir gönderiyi yukarı oyladı. + first_link: + name: + other: İlk Bağlantı + desc: + other: İlk kez başka bir gönderiye bağlantı ekledi. + first_reaction: + name: + other: İlk Tepki + desc: + other: İlk kez bir gönderiye tepki verdi. + first_share: + name: + other: İlk Paylaşım + desc: + other: İlk kez bir gönderi paylaştı. + scholar: + name: + other: Bilim İnsanı + desc: + other: Bir soru sordu ve bir cevabı kabul etti. + commentator: + name: + other: Yorumcu + desc: + other: 5 yorum bıraktı. + new_user_of_the_month: + name: + other: Ayın Yeni Kullanıcısı + desc: + other: İlk aylarında üstün katkılarda bulundu. + read_guidelines: + name: + other: Kuralları Okuyan + desc: + other: '[Topluluk kurallarını] oku.' + reader: + name: + other: Okuyucu + desc: + other: 10'dan fazla cevap içeren bir konudaki tüm cevapları okudu. + welcome: + name: + other: Hoş Geldin + desc: + other: Bir yukarı oy aldı. + nice_share: + name: + other: Güzel Paylaşım + desc: + other: 25 farklı ziyaretçi tarafından görüntülenen bir gönderi paylaştı. + good_share: + name: + other: İyi Paylaşım + desc: + other: 300 farklı ziyaretçi tarafından görüntülenen bir gönderi paylaştı. + great_share: + name: + other: Harika Paylaşım + desc: + other: 1000 farklı ziyaretçi tarafından görüntülenen bir gönderi paylaştı. + out_of_love: + name: + other: Sevgiden + desc: + other: Bir günde 50 yukarı oy kullandı. + higher_love: + name: + other: Yüksek Sevgi + desc: + other: Bir günde 50 yukarı oyu 5 kez kullandı. + crazy_in_love: + name: + other: Çılgınca Aşık + desc: + other: Bir günde 50 yukarı oyu 20 kez kullandı. + promoter: + name: + other: Destekçi + desc: + other: Bir kullanıcıyı davet etti. + campaigner: + name: + other: Kampanyacı + desc: + other: 3 temel kullanıcıyı davet etti. + champion: + name: + other: Şampiyon + desc: + other: 5 üye davet etti. + thank_you: + name: + other: Teşekkürler + desc: + other: 20 yukarı oy aldı ve 10 yukarı oy verdi. + gives_back: + name: + other: Karşılık Veren + desc: + other: 100 yukarı oy aldı ve 100 yukarı oy verdi. + empathetic: + name: + other: Empatik + desc: + other: 500 yukarı oy aldı ve 1000 yukarı oy verdi. + enthusiast: + name: + other: Hevesli + desc: + other: 10 gün üst üste ziyaret etti. + aficionado: + name: + other: Meraklı + desc: + other: 100 gün üst üste ziyaret etti. + devotee: + name: + other: Hayran + desc: + other: 365 gün üst üste ziyaret etti. + anniversary: + name: + other: Yıldönümü + desc: + other: Bir yıl boyunca aktif üye, en az bir gönderi paylaştı. + appreciated: + name: + other: Takdir Edilen + desc: + other: 20 gönderisinde 1 yukarı oy aldı. + respected: + name: + other: Saygın + desc: + other: 100 gönderisinde 2 yukarı oy aldı. + admired: + name: + other: Hayranlık Uyandıran + desc: + other: 300 gönderisinde 5 yukarı oy aldı. + solved: + name: + other: Çözüldü + desc: + other: Bir cevabı kabul edildi. + guidance_counsellor: + name: + other: Rehber Danışman + desc: + other: 10 cevabı kabul edildi. + know_it_all: + name: + other: Her Şeyi Bilen + desc: + other: 50 cevabı kabul edildi. + solution_institution: + name: + other: Çözüm Kurumu + desc: + other: 150 cevabı kabul edildi. + nice_answer: + name: + other: Güzel Cevap + desc: + other: 10 veya daha fazla cevap puanı. + good_answer: + name: + other: İyi Cevap + desc: + other: 25 veya daha fazla cevap puanı. + great_answer: + name: + other: Harika Cevap + desc: + other: 50 veya daha fazla cevap puanı. + nice_question: + name: + other: Güzel Soru + desc: + other: 10 veya daha fazla soru puanı. + good_question: + name: + other: İyi Soru + desc: + other: 25 veya daha fazla soru puanı. + great_question: + name: + other: Harika Soru + desc: + other: 50 veya daha fazla soru puanı. + popular_question: + name: + other: Popüler Soru + desc: + other: 500 görüntülenme alan soru. + notable_question: + name: + other: Dikkat Çeken Soru + desc: + other: 1.000 görüntülenme alan soru. + famous_question: + name: + other: Ünlü Soru + desc: + other: 5.000 görüntülenme alan soru. + popular_link: + name: + other: Popüler Bağlantı + desc: + other: 50 tıklama alan harici bir bağlantı paylaştı. + hot_link: + name: + other: Sıcak Bağlantı + desc: + other: 300 tıklama alan harici bir bağlantı paylaştı. + famous_link: + name: + other: Ünlü Bağlantı + desc: + other: 100 tıklama alan harici bir bağlantı paylaştı. + default_badge_groups: + getting_started: + name: + other: Başlangıç + community: + name: + other: Topluluk + posting: + name: + other: Gönderi Yazmak +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Nasıl Biçimlendirilir + desc: >- +
        • bir gönderiden bahsetmek için: #post_id

        • bağlantı oluşturmak için

          <https://url.com>

          [Başlık](https://url.com)
        • paragraflar arasında boşluk bırakın

        • _italik_ veya **kalın**

        • kodu 4 boşlukla girintileyin

        • satırın başına > koyarak alıntı yapın

        • ters tırnak işaretleriyle kaçış yapın `_böyle_`

        • ters tırnak işaretleriyle ` kod blokları oluşturun

          ```
          kod buraya
          ```
        + pagination: + prev: Önceki + next: Sonraki + page_title: + question: Soru + questions: Sorular + tag: Etiket + tags: Etiketler + tag_wiki: etiket wikisi + create_tag: Etiket Oluştur + edit_tag: Etiketi Düzenle + ask_a_question: Soru Oluştur + edit_question: Soruyu Düzenle + edit_answer: Cevabı Düzenle + search: Ara + posts_containing: İçeren gönderiler + settings: Ayarlar + notifications: Bildirimler + login: Giriş Yap + sign_up: Kayıt Ol + account_recovery: Hesap Kurtarma + account_activation: Hesap Aktivasyonu + confirm_email: E-posta Onayı + account_suspended: Hesap Askıya Alındı + admin: Yönetici + change_email: E-posta Değiştir + install: Answer Kurulumu + upgrade: Answer Yükseltme + maintenance: Website Bakımı + users: Kullanıcılar + oauth_callback: İşleniyor + http_404: HTTP Hatası 404 + http_50X: HTTP Hatası 500 + http_403: HTTP Hatası 403 + logout: Çıkış Yap + posts: Gönderiler + notifications: + title: Bildirimler + inbox: Gelen Kutusu + achievement: Başarılar + new_alerts: Yeni uyarılar + all_read: Tümünü okundu olarak işaretle + show_more: Daha fazla göster + someone: Birisi + inbox_type: + all: Tümü + posts: Gönderiler + invites: Davetler + votes: Oylar + answer: Cevap + question: Soru + badge_award: Rozet + suspended: + title: Hesabınız Askıya Alındı + until_time: "Hesabınız {{ time }} tarihine kadar askıya alındı." + forever: Bu kullanıcı süresiz olarak askıya alındı. + end: Topluluk kurallarını karşılamıyorsunuz. + contact_us: Bize ulaşın + editor: + blockquote: + text: Alıntı + bold: + text: Kalın + chart: + text: Grafik + flow_chart: Akış şeması + sequence_diagram: Sıralama diyagramı + class_diagram: Sınıf diyagramı + state_diagram: Durum diyagramı + entity_relationship_diagram: Varlık ilişki diyagramı + user_defined_diagram: Kullanıcı tanımlı diyagram + gantt_chart: Gantt şeması + pie_chart: Pasta grafiği + code: + text: Kod Örneği + add_code: Kod örneği ekle + form: + fields: + code: + label: Kod + msg: + empty: Kod boş olamaz. + language: + label: Dil + placeholder: Otomatik algılama + btn_cancel: İptal + btn_confirm: Ekle + formula: + text: Formül + options: + inline: Satır içi formül + block: Blok formül + heading: + text: Başlık + options: + h1: Başlık 1 + h2: Başlık 2 + h3: Başlık 3 + h4: Başlık 4 + h5: Başlık 5 + h6: Başlık 6 + help: + text: Yardım + hr: + text: Yatay çizgi + image: + text: Resim + add_image: Resim ekle + tab_image: Resim Yükle + form_image: + fields: + file: + label: Resim dosyası + btn: Resim seç + msg: + empty: Dosya boş olamaz. + only_image: Sadece resim dosyalarına izin verilir. + max_size: Dosya boyutu {{size}} MB'ı geçemez. + desc: + label: Açıklama + tab_url: Resim URL'si + form_url: + fields: + url: + label: Resim URL'si + msg: + empty: Resim URL'si boş olamaz. + name: + label: Açıklama + btn_cancel: İptal + btn_confirm: Ekle + uploading: Yükleniyor + indent: + text: Girinti + outdent: + text: Girintiyi azalt + italic: + text: İtalik + link: + text: Bağlantı + add_link: Bağlantı ekle + form: + fields: + url: + label: URL + msg: + empty: URL boş olamaz. + name: + label: Açıklama + btn_cancel: İptal + btn_confirm: Ekle + ordered_list: + text: Numaralı liste + unordered_list: + text: Madde işaretli liste + table: + text: Tablo + heading: Başlık + cell: Hücre + file: + text: Dosya ekle + not_supported: "Bu dosya türü desteklenmiyor. {{file_type}} ile tekrar deneyin." + max_size: "Eklenen dosyaların boyutu {{size}} MB'ı geçemez." + close_modal: + title: Bu gönderiyi kapatıyorum çünkü... + btn_cancel: İptal + btn_submit: Gönder + remark: + empty: Boş olamaz. + msg: + empty: Lütfen bir neden seçin. + report_modal: + flag_title: Bu gönderiyi şu nedenle bildiriyorum... + close_title: Bu gönderiyi şu nedenle kapatıyorum... + review_question_title: Soruyu incele + review_answer_title: Cevabı incele + review_comment_title: Yorumu incele + btn_cancel: İptal + btn_submit: Gönder + remark: + empty: Boş olamaz. + msg: + empty: Lütfen bir neden seçin. + not_a_url: URL formatı yanlış. + url_not_match: URL kaynağı mevcut web sitesiyle eşleşmiyor. + tag_modal: + title: Yeni etiket oluştur + form: + fields: + display_name: + label: Görünen ad + msg: + empty: Görünen ad boş olamaz. + range: Görünen ad en fazla 35 karakter olabilir. + slug_name: + label: URL kısaltması + desc: URL kısaltması en fazla 35 karakter olabilir. + msg: + empty: URL kısaltması boş olamaz. + range: URL kısaltması en fazla 35 karakter olabilir. + character: URL kısaltması izin verilmeyen karakter içeriyor. + desc: + label: Açıklama + revision: + label: Revizyon + edit_summary: + label: Düzenleme özeti + placeholder: >- + Değişikliklerinizi kısaca açıklayın (yazım hatası düzeltildi, dilbilgisi düzeltildi, biçimlendirme geliştirildi) + btn_cancel: İptal + btn_submit: Gönder + btn_post: Yeni etiket gönder + tag_info: + created_at: Oluşturuldu + edited_at: Düzenlendi + history: Geçmiş + synonyms: + title: Eş Anlamlılar + text: Aşağıdaki etiketler şuna yeniden eşlenecek + empty: Eş anlamlı bulunamadı. + btn_add: Eş anlamlı ekle + btn_edit: Düzenle + btn_save: Kaydet + synonyms_text: Aşağıdaki etiketler şuna yeniden eşlenecek + delete: + title: Bu etiketi sil + tip_with_posts: >- +

        Gönderileri olan etiketin silinmesine izin vermiyoruz.

        Lütfen önce bu etiketi gönderilerden kaldırın.

        + tip_with_synonyms: >- +

        Eş anlamlıları olan etiketin silinmesine izin vermiyoruz.

        Lütfen önce bu etiketin eş anlamlılarını kaldırın.

        + tip: Silmek istediğinizden emin misiniz? + close: Kapat + merge: + title: Etiket birleştir + source_tag_title: Kaynak etiket + source_tag_description: Kaynak etiket ve ilişkili verileri hedef etikete yeniden eşlenecek. + target_tag_title: Hedef etiket + target_tag_description: Birleştirmeden sonra bu iki etiket arasında bir eş anlamlı ilişkisi oluşturulacak. + no_results: Eşleşen etiket bulunamadı + btn_submit: Gönder + btn_close: Kapat + edit_tag: + title: Etiketi Düzenle + default_reason: Etiketi düzenle + default_first_reason: Etiket ekle + btn_save_edits: Düzenlemeleri kaydet + btn_cancel: İptal + dates: + long_date: D MMM + long_date_with_year: "D MMM, YYYY" + long_date_with_time: "D MMM, YYYY [saat] HH:mm" + now: şimdi + x_seconds_ago: "{{count}} saniye önce" + x_minutes_ago: "{{count}} dakika önce" + x_hours_ago: "{{count}} saat önce" + hour: saat + day: gün + hours: saatler + days: günler + month: ay + months: aylar + year: yıl + reaction: + heart: kalp + smile: gülümseme + frown: üzgün + btn_label: tepki ekle veya kaldır + undo_emoji: '{{emoji}} tepkisini geri al' + react_emoji: '{{emoji}} ile tepki ver' + unreact_emoji: '{{emoji}} tepkisini kaldır' + comment: + btn_add_comment: Yorum ekle + reply_to: Yanıtla + btn_reply: Yanıtla + btn_edit: Düzenle + btn_delete: Sil + btn_flag: Bildir + btn_save_edits: Düzenlemeleri kaydet + btn_cancel: İptal + show_more: "{{count}} daha fazla yorum" + tip_question: >- + Daha fazla bilgi istemek veya iyileştirmeler önermek için yorumları kullanın. Yorumlarda soruları cevaplamaktan kaçının. + tip_answer: >- + Diğer kullanıcılara yanıt vermek veya onları değişikliklerden haberdar etmek için yorumları kullanın. Yeni bilgi ekliyorsanız, yorum yapmak yerine gönderinizi düzenleyin. + tip_vote: Gönderiye faydalı bir şey ekliyor + edit_answer: + title: Cevabı Düzenle + default_reason: Cevabı düzenle + default_first_reason: Cevap ekle + form: + fields: + revision: + label: Revizyon + answer: + label: Cevap + feedback: + characters: içerik en az 6 karakter uzunluğunda olmalıdır. + edit_summary: + label: Düzenleme özeti + placeholder: >- + Yaptığınız değişiklikleri kısaca açıklayın (düzeltilmiş yazım geliştirilmiş biçimlendirme) + btn_save_edits: Düzenlemeleri kaydet + btn_cancel: İptal + tags: + title: Etiketler + sort_buttons: + popular: Popüler + name: İsim + newest: En Yeni + button_follow: Takip Et + button_following: Takip Ediliyor + tag_label: sorular + search_placeholder: Etiket adına göre filtrele + no_desc: Bu etiketin açıklaması yok. + more: Daha Fazla + wiki: Wiki + ask: + title: Soru Oluştur + edit_title: Soruyu Düzenle + default_reason: Soruyu düzenle + default_first_reason: Soru oluştur + similar_questions: Benzer sorular + form: + fields: + revision: + label: Revizyon + title: + label: Başlık + placeholder: Konunuz nedir? Ayrıntılı belirtin. + msg: + empty: Başlık boş olamaz. + range: Başlık en fazla 150 karakter olabilir + body: + label: İçerik + msg: + empty: İçerik boş olamaz. + hint: + optional_body: Sorunun ne hakkında olduğunu açıklayın. + minimum_characters: "Sorunun ne hakkında olduğunu açıklayın, en az {{min_content_length}} karakter gereklidir." + tags: + label: Etiketler + msg: + empty: Etiketler boş olamaz. + answer: + label: Cevap + msg: + empty: Cevap boş olamaz. + edit_summary: + label: Düzenleme özeti + placeholder: >- + Değişikliklerinizi kısaca açıklayın (yazım hatası düzeltildi, dilbilgisi düzeltildi, biçimlendirme geliştirildi) + btn_post_question: Sorunuzu gönderin + btn_save_edits: Düzenlemeleri kaydet + answer_question: Kendi sorunuzu cevaplayın + post_question&answer: Sorunuzu ve cevabınızı gönderin + tag_selector: + add_btn: Etiket ekle + create_btn: Yeni etiket oluştur + search_tag: Etiket ara + hint: İçeriğinizin ne hakkında olduğunu açıklayın, en az bir etiket gereklidir. + hint_zero_tags: İçeriğinizin ne hakkında olduğunu açıklayın. + hint_more_than_one_tag: "İçeriğinizin ne hakkında olduğunu açıklayın, en az {{min_tags_number}} etiket gereklidir." + no_result: Eşleşen etiket bulunamadı + tag_required_text: Gerekli etiket (en az bir tane) + header: + nav: + question: Sorular + tag: Etiketler + user: Kullanıcılar + badges: Rozetler + profile: Profil + setting: Ayarlar + logout: Çıkış yap + admin: Yönetici + review: İnceleme + bookmark: Yer İşaretleri + moderation: Moderasyon + search: + placeholder: Ara + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Değiştir + loading: yükleniyor... + pic_auth_code: + title: Captcha + placeholder: Yukarıdaki metni yazın + msg: + empty: Captcha boş olamaz. + inactive: + first: >- + Neredeyse tamamlandı! {{mail}} adresine bir aktivasyon e-postası gönderdik. Hesabınızı etkinleştirmek için lütfen e-postadaki talimatları izleyin. + info: "E-posta gelmezse, spam klasörünüzü kontrol edin." + another: >- + {{mail}} adresine başka bir aktivasyon e-postası gönderdik. Gelmesi birkaç dakika sürebilir; spam klasörünüzü kontrol etmeyi unutmayın. + btn_name: Aktivasyon e-postasını yeniden gönder + change_btn_name: E-posta değiştir + msg: + empty: Boş olamaz. + resend_email: + url_label: Aktivasyon e-postasını yeniden göndermek istediğinizden emin misiniz? + url_text: Ayrıca yukarıdaki aktivasyon bağlantısını kullanıcıya verebilirsiniz. + login: + login_to_continue: Devam etmek için giriş yapın + info_sign: Hesabınız yok mu? <1>Kaydolun + info_login: Zaten hesabınız var mı? <1>Giriş yapın + agreements: Kaydolarak <1>gizlilik politikasını ve <3>hizmet şartlarını kabul etmiş olursunuz. + forgot_pass: Parolanızı mı unuttunuz? + name: + label: İsim + msg: + empty: İsim boş olamaz. + range: İsim 2 ile 30 karakter arasında olmalıdır. + character: 'Yalnızca "a-z", "0-9", " - . _" karakterleri kullanılabilir' + email: + label: E-posta + msg: + empty: E-posta boş olamaz. + password: + label: Parola + msg: + empty: Parola boş olamaz. + different: Her iki tarafta girilen parolalar tutarsız + account_forgot: + page_title: Parolanızı mı Unuttunuz + btn_name: Bana kurtarma e-postası gönder + send_success: >- + Eğer bir hesap {{mail}} ile eşleşirse, kısa süre içinde parolanızı nasıl sıfırlayacağınıza dair talimatlar içeren bir e-posta almalısınız. + email: + label: E-posta + msg: + empty: E-posta boş olamaz. + change_email: + btn_cancel: İptal + btn_update: E-posta adresini güncelle + send_success: >- + Eğer bir hesap {{mail}} ile eşleşirse, kısa süre içinde parolanızı nasıl sıfırlayacağınıza dair talimatlar içeren bir e-posta almalısınız. + email: + label: Yeni e-posta + msg: + empty: E-posta boş olamaz. + oauth: + connect: '{{auth_name}} ile bağlan' + remove: '{{auth_name}} kaldır' + oauth_bind_email: + subtitle: Hesabınıza bir kurtarma e-postası ekleyin. + btn_update: E-posta adresini güncelle + email: + label: E-posta + msg: + empty: E-posta boş olamaz. + modal_title: E-posta zaten mevcut. + modal_content: Bu e-posta adresi zaten kayıtlı. Mevcut hesaba bağlanmak istediğinizden emin misiniz? + modal_cancel: E-posta değiştir + modal_confirm: Mevcut hesaba bağlan + password_reset: + page_title: Parola Sıfırlama + btn_name: Parolamı sıfırla + reset_success: >- + Parolanızı başarıyla değiştirdiniz; giriş sayfasına yönlendirileceksiniz. + link_invalid: >- + Üzgünüz, bu parola sıfırlama bağlantısı artık geçerli değil. Belki de parolanız zaten sıfırlanmış? + to_login: Giriş sayfasına devam et + password: + label: Parola + msg: + empty: Parola boş olamaz. + length: Uzunluk 8 ile 32 arasında olmalıdır + different: Her iki tarafta girilen parolalar tutarsız + password_confirm: + label: Yeni parolayı onayla + settings: + page_title: Ayarlar + goto_modify: Değiştirmeye git + nav: + profile: Profil + notification: Bildirimler + account: Hesap + interface: Arayüz + profile: + heading: Profil + btn_name: Kaydet + display_name: + label: Görünen ad + msg: Görünen ad boş olamaz. + msg_range: Görünen ad 2-30 karakter uzunluğunda olmalıdır. + username: + label: Kullanıcı adı + caption: İnsanlar size "@kullaniciadi" şeklinde bahsedebilir. + msg: Kullanıcı adı boş olamaz. + msg_range: Kullanıcı adı 2-30 karakter uzunluğunda olmalıdır. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profil resmi + gravatar: Gravatar + gravatar_text: Resmi şurada değiştirebilirsiniz + custom: Özel + custom_text: Kendi resminizi yükleyebilirsiniz. + default: Sistem + msg: Lütfen bir avatar yükleyin + bio: + label: Hakkımda + website: + label: Website + placeholder: "https://example.com" + msg: Website formatı yanlış + location: + label: Konum + placeholder: "Şehir, Ülke" + notification: + heading: E-posta Bildirimleri + turn_on: Aç + inbox: + label: Gelen kutusu bildirimleri + description: Sorularınıza cevaplar, yorumlar, davetler ve daha fazlası. + all_new_question: + label: Tüm yeni sorular + description: Tüm yeni sorulardan haberdar olun. Haftada en fazla 50 soru. + all_new_question_for_following_tags: + label: Takip edilen etiketler için tüm yeni sorular + description: Takip ettiğiniz etiketlerdeki yeni sorulardan haberdar olun. + account: + heading: Hesap + change_email_btn: E-posta değiştir + change_pass_btn: Parola değiştir + change_email_info: >- + Bu adrese bir e-posta gönderdik. Lütfen onay talimatlarını takip edin. + email: + label: E-posta + new_email: + label: Yeni e-posta + msg: Yeni e-posta boş olamaz. + pass: + label: Mevcut parola + msg: Parola boş olamaz. + password_title: Parola + current_pass: + label: Mevcut parola + msg: + empty: Mevcut parola boş olamaz. + length: Uzunluk 8 ile 32 arasında olmalıdır. + different: Girilen iki parola eşleşmiyor. + new_pass: + label: Yeni parola + pass_confirm: + label: Yeni parolayı onayla + interface: + heading: Arayüz + lang: + label: Arayüz dili + text: Kullanıcı arayüzü dili. Sayfa yenilendiğinde değişecektir. + my_logins: + title: Girişlerim + label: Bu hesapları kullanarak bu sitede giriş yapın veya kaydolun. + modal_title: Girişi kaldır + modal_content: Bu girişi hesabınızdan kaldırmak istediğinizden emin misiniz? + modal_confirm_btn: Kaldır + remove_success: Başarıyla kaldırıldı + toast: + update: güncelleme başarılı + update_password: Parola başarıyla değiştirildi. + flag_success: Bildirdiğiniz için teşekkürler. + forbidden_operate_self: Kendinizle ilgili işlem yapmak yasaktır + review: Revizyonunuz incelendikten sonra görünecek. + sent_success: Başarıyla gönderildi + related_question: + title: İlgili + answers: cevap + linked_question: + title: Bağlantılı + description: Bağlantılı gönderiler + no_linked_question: Bu içerikten bağlantı verilen içerik yok. + invite_to_answer: + title: İnsanları Davet Et + desc: Cevap verebileceğini düşündüğünüz kişileri davet edin. + invite: Cevaplamaya davet et + add: Kişi ekle + search: Kişi ara + question_detail: + action: Eylem + created: Oluşturuldu + Asked: Soruldu + asked: sordu + update: Değiştirildi + Edited: Düzenlendi + edit: düzenledi + commented: yorum yaptı + Views: Görüntülendi + Follow: Takip Et + Following: Takip Ediliyor + follow_tip: Bildirim almak için bu soruyu takip edin + answered: cevapladı + closed_in: Burada kapatıldı + show_exist: Var olan soruyu göster. + useful: Faydalı + question_useful: Faydalı ve açık + question_un_useful: Belirsiz veya faydalı değil + question_bookmark: Bu soruyu yer işaretlerine ekle + answer_useful: Faydalı + answer_un_useful: Faydalı değil + answers: + title: Cevaplar + score: Puan + newest: En Yeni + oldest: En Eski + btn_accept: Kabul Et + btn_accepted: Kabul Edildi + write_answer: + title: Cevabınız + edit_answer: Mevcut cevabımı düzenle + btn_name: Cevabınızı gönderin + add_another_answer: Başka bir cevap ekle + confirm_title: Cevaplamaya devam et + continue: Devam et + confirm_info: >- +

        Başka bir cevap eklemek istediğinizden emin misiniz?

        Bunun yerine mevcut cevabınızı iyileştirmek ve geliştirmek için düzenleme bağlantısını kullanabilirsiniz.

        + empty: Cevap boş olamaz. + characters: içerik en az 6 karakter uzunluğunda olmalıdır. + tips: + header_1: Cevabınız için teşekkürler + li1_1: Lütfen soruyu cevapladığınızdan emin olun. Detaylar verin ve araştırmanızı paylaşın. + li1_2: Yaptığınız ifadeleri referanslar veya kişisel deneyimlerle destekleyin. + header_2: Ancak şunlardan kaçının ... + li2_1: Yardım istemek, açıklama istemek veya diğer cevaplara yanıt vermek. + reopen: + confirm_btn: Yeniden Aç + title: Bu gönderiyi yeniden aç + content: Yeniden açmak istediğinizden emin misiniz? + list: + confirm_btn: Listele + title: Bu gönderiyi listele + content: Listelemek istediğinizden emin misiniz? + unlist: + confirm_btn: Listeden Kaldır + title: Bu gönderiyi listeden kaldır + content: Listeden kaldırmak istediğinizden emin misiniz? + pin: + title: Bu gönderiyi sabitle + content: Küresel olarak sabitlemek istediğinizden emin misiniz? Bu gönderi tüm gönderi listelerinin en üstünde görünecektir. + confirm_btn: Sabitle + delete: + title: Bu gönderiyi sil + question: >- + Cevapları olan soruları silmenizi önermiyoruz çünkü bunu yapmak gelecekteki okuyucuları bu bilgiden mahrum bırakır.

        Cevaplanmış soruları tekrar tekrar silmek, hesabınızın soru sorma yeteneğinin engellenmesine neden olabilir. Silmek istediğinizden emin misiniz? + answer_accepted: >- +

        Kabul edilmiş cevabı silmenizi önermiyoruz çünkü bunu yapmak gelecekteki okuyucuları bu bilgiden mahrum bırakır.

        Kabul edilmiş cevapları tekrar tekrar silmek, hesabınızın cevap verme yeteneğinin engellenmesine neden olabilir. Silmek istediğinizden emin misiniz? + other: Silmek istediğinizden emin misiniz? + tip_answer_deleted: Bu cevap silinmiştir + undelete_title: Bu gönderinin silmesini geri al + undelete_desc: Silmeyi geri almak istediğinizden emin misiniz? + btns: + confirm: Onayla + cancel: İptal + edit: Düzenle + save: Kaydet + delete: Sil + undelete: Silmeyi Geri Al + list: Listele + unlist: Listeden Kaldır + unlisted: Listede Değil + login: Giriş Yap + signup: Kayıt Ol + logout: Çıkış Yap + verify: Doğrula + create: Oluştur + approve: Onayla + reject: Reddet + skip: Atla + discard_draft: Taslağı at + pinned: Sabitlendi + all: Tümü + question: Soru + answer: Cevap + comment: Yorum + refresh: Yenile + resend: Yeniden Gönder + deactivate: Devre Dışı Bırak + active: Aktif + suspend: Askıya Al + unsuspend: Askıyı Kaldır + close: Kapat + reopen: Yeniden Aç + ok: Tamam + light: Açık + dark: Koyu + system_setting: Sistem ayarı + default: Varsayılan + reset: Sıfırla + tag: Etiket + post_lowercase: gönderi + filter: Filtrele + ignore: Yoksay + submit: Gönder + normal: Normal + closed: Kapalı + deleted: Silindi + deleted_permanently: Kalıcı olarak silindi + pending: Beklemede + more: Daha Fazla + view: Görüntüle + card: Kart + compact: Kompakt + display_below: Aşağıda göster + always_display: Her zaman göster + or: veya + back_sites: Sitelere geri dön + search: + title: Arama Sonuçları + keywords: Anahtar Kelimeler + options: Seçenekler + follow: Takip Et + following: Takip Ediliyor + counts: "{{count}} Sonuç" + counts_loading: "... Results" + more: Daha Fazla + sort_btns: + relevance: İlgililik + newest: En Yeni + active: Aktif + score: Puan + more: Daha Fazla + tips: + title: Gelişmiş Arama İpuçları + tag: "<1>[etiket] bir etiketle ara" + user: "<1>user:kullanıcıadı yazara göre ara" + answer: "<1>answers:0 cevaplanmamış sorular" + score: "<1>score:3 3+ puana sahip gönderiler" + question: "<1>is:question soruları ara" + is_answer: "<1>is:answer cevapları ara" + empty: Hiçbir şey bulamadık.
        Farklı veya daha az spesifik anahtar kelimeler deneyin. + share: + name: Paylaş + copy: Bağlantıyı kopyala + via: Gönderiyi şurada paylaş... + copied: Kopyalandı + facebook: Facebook'ta Paylaş + twitter: X'te Paylaş + cannot_vote_for_self: Kendi gönderinize oy veremezsiniz. + modal_confirm: + title: Hata... + delete_permanently: + title: Kalıcı olarak sil + content: Kalıcı olarak silmek istediğinizden emin misiniz? + account_result: + success: Yeni hesabınız onaylandı; ana sayfaya yönlendirileceksiniz. + link: Ana sayfaya devam et + oops: Hay aksi! + invalid: Kullandığınız bağlantı artık çalışmıyor. + confirm_new_email: E-postanız güncellendi. + confirm_new_email_invalid: >- + Üzgünüz, bu onay bağlantısı artık geçerli değil. Belki e-postanız zaten değiştirildi? + unsubscribe: + page_title: Abonelikten Çık + success_title: Abonelikten Çıkma Başarılı + success_desc: Bu abone listesinden başarıyla çıkarıldınız ve bizden başka e-posta almayacaksınız. + link: Ayarları değiştir + question: + following_tags: Takip Edilen Etiketler + edit: Düzenle + save: Kaydet + follow_tag_tip: Soru listenizi oluşturmak için etiketleri takip edin. + hot_questions: Popüler Sorular + all_questions: Tüm Sorular + x_questions: "{{ count }} Soru" + x_answers: "{{ count }} cevap" + x_posts: "{{ count }} Posts" + questions: Sorular + answers: Cevaplar + newest: En Yeni + active: Aktif + hot: Popüler + frequent: Sık Sorulan + recommend: Önerilenler + score: Puan + unanswered: Cevaplanmamış + modified: değiştirildi + answered: cevaplandı + asked: soruldu + closed: kapandı + follow_a_tag: Bir etiketi takip et + more: Daha Fazla + personal: + overview: Genel Bakış + answers: Cevaplar + answer: cevap + questions: Sorular + question: soru + bookmarks: Yer İşaretleri + reputation: İtibar + comments: Yorumlar + votes: Oylar + badges: Rozetler + newest: En Yeni + score: Puan + edit_profile: Profili düzenle + visited_x_days: "{{ count }} gün ziyaret edildi" + viewed: Görüntülendi + joined: Katıldı + comma: "," + last_login: Görüldü + about_me: Hakkımda + about_me_empty: "// Merhaba, Dünya !" + top_answers: En İyi Cevaplar + top_questions: En İyi Sorular + stats: İstatistikler + list_empty: Gönderi bulunamadı.
        Belki farklı bir sekme seçmek istersiniz? + content_empty: Gönderi bulunamadı. + accepted: Kabul Edildi + answered: cevaplandı + asked: sordu + downvoted: negatif oylandı + mod_short: MOD + mod_long: Moderatörler + x_reputation: itibar + x_votes: alınan oy + x_answers: cevap + x_questions: soru + recent_badges: Son Rozetler + install: + title: Kurulum + next: İleri + done: Tamamlandı + config_yaml_error: config.yaml dosyası oluşturulamıyor. + lang: + label: Lütfen bir dil seçin + db_type: + label: Veritabanı motoru + db_username: + label: Kullanıcı adı + placeholder: root + msg: Kullanıcı adı boş olamaz. + db_password: + label: Parola + placeholder: root + msg: Parola boş olamaz. + db_host: + label: Veritabanı sunucusu + placeholder: "db:3306" + msg: Veritabanı sunucusu boş olamaz. + db_name: + label: Veritabanı adı + placeholder: answer + msg: Veritabanı adı boş olamaz. + db_file: + label: Veritabanı dosyası + placeholder: /data/answer.db + msg: Veritabanı dosyası boş olamaz. + ssl_enabled: + label: SSL'i Etkinleştir + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Modu + ssl_root_cert: + placeholder: sslrootcert dosya yolu + msg: sslrootcert dosya yolu boş olamaz + ssl_cert: + placeholder: sslcert dosya yolu + msg: sslcert dosya yolu boş olamaz + ssl_key: + placeholder: sslkey dosya yolu + msg: sslkey dosya yolu boş olamaz + config_yaml: + title: config.yaml Oluştur + label: config.yaml dosyası oluşturuldu. + desc: >- + <1>config.yaml dosyasını <1>/var/wwww/xxx/ dizininde manuel olarak oluşturabilir ve aşağıdaki metni içine yapıştırabilirsiniz. + info: Bunu yaptıktan sonra "İleri" düğmesine tıklayın. + site_information: Site Bilgisi + admin_account: Yönetici Hesabı + site_name: + label: Site adı + msg: Saat dilimi boş olamaz. + msg_max_length: Site adı en fazla 30 karakter uzunluğunda olmalıdır. + site_url: + label: Site URL'si + text: Sitenizin adresi. + msg: + empty: Site URL'si boş olamaz. + incorrect: Site URL'si formatı yanlış. + max_length: Site URL'si en fazla 512 karakter uzunluğunda olmalıdır. + contact_email: + label: İletişim e-postası + text: Bu siteden sorumlu kilit kişinin e-posta adresi. + msg: + empty: İletişim e-postası boş olamaz. + incorrect: İletişim e-postası formatı yanlış. + login_required: + label: Özel + switch: Giriş gerekli + text: Bu topluluğa sadece giriş yapmış kullanıcılar erişebilir. + admin_name: + label: İsim + msg: İsim boş olamaz. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: İsim 2 ile 30 karakter arasında olmalıdır. + admin_password: + label: Parola + text: >- + Giriş yapmak için bu parolaya ihtiyacınız olacak. Lütfen güvenli bir yerde saklayın. + msg: Parola boş olamaz. + msg_min_length: Parola en az 8 karakter uzunluğunda olmalıdır. + msg_max_length: Parola en fazla 32 karakter uzunluğunda olmalıdır. + admin_confirm_password: + label: "Parolayı Onayla" + text: "Lütfen onaylamak için parolanızı tekrar girin." + msg: "Onay parolası eşleşmiyor." + admin_email: + label: E-posta + text: Giriş yapmak için bu e-postaya ihtiyacınız olacak. + msg: + empty: E-posta boş olamaz. + incorrect: E-posta formatı yanlış. + ready_title: Siteniz hazır + ready_desc: >- + Daha fazla ayarı değiştirmek isterseniz, <1>yönetici bölümünü ziyaret edin; site menüsünde bulabilirsiniz. + good_luck: "İyi eğlenceler ve iyi şanslar!" + warn_title: Uyarı + warn_desc: >- + <1>config.yaml dosyası zaten var. Bu dosyadaki herhangi bir yapılandırma öğesini sıfırlamanız gerekiyorsa, lütfen önce dosyayı silin. + install_now: <1>Şimdi kurulum yapmayı deneyebilirsiniz. + installed: Zaten kurulu + installed_desc: >- + Zaten kurulum yapmış görünüyorsunuz. Yeniden kurmak için lütfen önce eski veritabanı tablolarınızı temizleyin. + db_failed: Veritabanı bağlantısı başarısız + db_failed_desc: >- + Bu, <1>config.yaml dosyanızdaki veritabanı bilgilerinin yanlış olduğu veya veritabanı sunucusuyla bağlantı kurulamadığı anlamına gelir. Bu, sunucunuzun veritabanı sunucusunun çalışmadığı anlamına gelebilir. + counts: + views: görüntülenme + votes: oy + answers: cevap + accepted: Kabul Edildi + page_error: + http_error: HTTP Hatası {{ code }} + desc_403: Bu sayfaya erişim izniniz yok. + desc_404: Maalesef, bu sayfa mevcut değil. + desc_50X: Sunucu bir hatayla karşılaştı ve isteğinizi tamamlayamadı. + back_home: Ana sayfaya dön + page_maintenance: + desc: "Bakım altındayız, yakında geri döneceğiz." + nav_menus: + dashboard: Gösterge Paneli + contents: İçerikler + questions: Sorular + answers: Cevaplar + users: Kullanıcılar + badges: Rozetler + flags: Bildirimler + settings: Ayarlar + general: Genel + interface: Arayüz + smtp: SMTP + branding: Marka + legal: Yasal + write: Yaz + terms: Terms + tos: Kullanım Şartları + privacy: Gizlilik + seo: SEO + customize: Özelleştir + themes: Temalar + login: Giriş + privileges: Ayrıcalıklar + plugins: Eklentiler + installed_plugins: Kurulu Eklentiler + apperance: Görünüm + website_welcome: '{{site_name}} sitesine hoş geldiniz' + user_center: + login: Giriş + qrcode_login_tip: Lütfen QR kodu taramak ve giriş yapmak için {{ agentName }} kullanın. + login_failed_email_tip: Giriş başarısız oldu, lütfen tekrar denemeden önce bu uygulamanın e-posta bilgilerinize erişmesine izin verin. + badges: + modal: + title: Tebrikler + content: Yeni bir rozet kazandınız. + close: Kapat + confirm: Rozetleri görüntüle + title: Rozetler + awarded: Kazanıldı + earned_×: '{{ number }} kez kazanıldı' + ×_awarded: "{{ number }} kez verildi" + can_earn_multiple: Bunu birden çok kez kazanabilirsiniz. + earned: Kazanıldı + admin: + admin_header: + title: Yönetici + dashboard: + title: Gösterge Paneli + welcome: Yönetici'ye Hoş Geldiniz! + site_statistics: Site istatistikleri + questions: "Sorular:" + resolved: "Çözülmüş:" + unanswered: "Cevaplanmamış:" + answers: "Cevaplar:" + comments: "Yorumlar:" + votes: "Oylar:" + users: "Kullanıcılar:" + flags: "Bildirimler:" + reviews: "İncelemeler:" + site_health: Site sağlığı + version: "Sürüm:" + https: "HTTPS:" + upload_folder: "Yükleme klasörü:" + run_mode: "Çalışma modu:" + private: Özel + public: Herkese Açık + smtp: "SMTP:" + timezone: "Saat dilimi:" + system_info: Sistem bilgisi + go_version: "Go sürümü:" + database: "Veritabanı:" + database_size: "Veritabanı boyutu:" + storage_used: "Kullanılan depolama:" + uptime: "Çalışma süresi:" + links: Bağlantılar + plugins: Eklentiler + github: GitHub + blog: Blog + contact: İletişim + forum: Forum + documents: Belgeler + feedback: Geribildirim + support: Destek + review: İnceleme + config: Yapılandırma + update_to: Güncelle + latest: En son + check_failed: Kontrol başarısız + "yes": "Evet" + "no": "Hayır" + not_allowed: İzin verilmiyor + allowed: İzin veriliyor + enabled: Etkin + disabled: Devre dışı + writable: Yazılabilir + not_writable: Yazılamaz + flags: + title: Bildirimler + pending: Bekleyen + completed: Tamamlanan + flagged: Bildirilen + flagged_type: Bildirilen {{ type }} + created: Oluşturuldu + action: Eylem + review: İnceleme + user_role_modal: + title: Kullanıcı rolünü şuna değiştir... + btn_cancel: İptal + btn_submit: Gönder + new_password_modal: + title: Yeni parola belirle + form: + fields: + password: + label: Parola + text: Kullanıcının oturumu kapatılacak ve tekrar giriş yapması gerekecek. + msg: Parola 8-32 karakter uzunluğunda olmalıdır. + btn_cancel: İptal + btn_submit: Gönder + edit_profile_modal: + title: Profili düzenle + form: + fields: + display_name: + label: Görünen ad + msg_range: Görünen ad 2-30 karakter uzunluğunda olmalıdır. + username: + label: Kullanıcı adı + msg_range: Kullanıcı adı 2-30 karakter uzunluğunda olmalıdır. + email: + label: E-posta + msg_invalid: Geçersiz E-posta Adresi. + edit_success: Başarıyla düzenlendi + btn_cancel: İptal + btn_submit: Gönder + user_modal: + title: Yeni kullanıcı ekle + form: + fields: + users: + label: Toplu kullanıcı ekle + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: İsim, e-posta, parola bilgilerini virgülle ayırın. Her satırda bir kullanıcı. + msg: "Lütfen kullanıcının e-postasını girin, her satırda bir tane." + display_name: + label: Görünen ad + msg: Görünen ad 2-30 karakter uzunluğunda olmalıdır. + email: + label: E-posta + msg: E-posta geçerli değil. + password: + label: Parola + msg: Parola 8-32 karakter uzunluğunda olmalıdır. + btn_cancel: İptal + btn_submit: Gönder + users: + title: Kullanıcılar + name: İsim + email: E-posta + reputation: İtibar + created_at: Oluşturulma zamanı + delete_at: Silinme zamanı + suspend_at: Askıya Alınma Zamanı + suspend_until: Suspend until + status: Durum + role: Rol + action: Eylem + change: Değiştir + all: Tümü + staff: Ekip + more: Daha Fazla + inactive: Etkin Değil + suspended: Askıya Alınmış + deleted: Silinmiş + normal: Normal + Moderator: Moderatör + Admin: Yönetici + User: Kullanıcı + filter: + placeholder: "İsme göre filtreleme, user:id" + set_new_password: Yeni parola belirle + edit_profile: Profili düzenle + change_status: Durumu değiştir + change_role: Rolü değiştir + show_logs: Kayıtları göster + add_user: Kullanıcı ekle + deactivate_user: + title: Kullanıcıyı devre dışı bırak + content: Etkin olmayan bir kullanıcının e-postasını yeniden doğrulaması gerekir. + delete_user: + title: Bu kullanıcıyı sil + content: Bu kullanıcıyı silmek istediğinizden emin misiniz? Bu kalıcıdır! + remove: İçeriklerini kaldır + label: Tüm soruları, cevapları, yorumları vb. kaldır. + text: Sadece kullanıcının hesabını silmek istiyorsanız bunu işaretlemeyin. + suspend_user: + title: Bu kullanıcıyı askıya al + content: Askıya alınmış bir kullanıcı giriş yapamaz. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Sorular + unlisted: Listelenmemiş + post: Gönderi + votes: Oylar + answers: Cevaplar + created: Oluşturuldu + status: Durum + action: Eylem + change: Değiştir + pending: Beklemede + filter: + placeholder: "Başlığa göre filtreleme, question:id" + answers: + page_title: Cevaplar + post: Gönderi + votes: Oylar + created: Oluşturuldu + status: Durum + action: Eylem + change: Değiştir + filter: + placeholder: "Başlığa göre filtreleme, answer:id" + general: + page_title: Genel + name: + label: Site adı + msg: Site adı boş olamaz. + text: "Başlık etiketinde kullanılan bu sitenin adı." + site_url: + label: Site URL'si + msg: Site url'si boş olamaz. + validate: Lütfen geçerli bir URL girin. + text: Sitenizin adresi. + short_desc: + label: Kısa site açıklaması + msg: Kısa site açıklaması boş olamaz. + text: "Ana sayfadaki başlık etiketinde kullanılan kısa açıklama." + desc: + label: Site açıklaması + msg: Site açıklaması boş olamaz. + text: "Bu siteyi bir cümleyle açıklayın, meta açıklama etiketinde kullanılır." + contact_email: + label: İletişim e-postası + msg: İletişim e-postası boş olamaz. + validate: İletişim e-postası geçerli değil. + text: Bu siteden sorumlu kilit kişinin e-posta adresi. + check_update: + label: Yazılım güncellemeleri + text: Güncellemeleri otomatik olarak kontrol et + interface: + page_title: Arayüz + language: + label: Arayüz dili + msg: Arayüz dili boş olamaz. + text: Kullanıcı arayüzü dili. Sayfa yenilendiğinde değişecektir. + time_zone: + label: Saat dilimi + msg: Saat dilimi boş olamaz. + text: Sizinle aynı saat dilimindeki bir şehri seçin. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: Gönderen e-posta + msg: Gönderen e-posta boş olamaz. + text: E-postaların gönderildiği e-posta adresi. + from_name: + label: Gönderen adı + msg: Gönderen adı boş olamaz. + text: E-postaların gönderildiği isim. + smtp_host: + label: SMTP sunucusu + msg: SMTP sunucusu boş olamaz. + text: Mail sunucunuz. + encryption: + label: Şifreleme + msg: Şifreleme boş olamaz. + text: Çoğu sunucu için SSL önerilen seçenektir. + ssl: SSL + tls: TLS + none: Yok + smtp_port: + label: SMTP portu + msg: SMTP portu 1 ~ 65535 arasında bir sayı olmalıdır. + text: Mail sunucunuzun portu. + smtp_username: + label: SMTP kullanıcı adı + msg: SMTP kullanıcı adı boş olamaz. + smtp_password: + label: SMTP parolası + msg: SMTP parolası boş olamaz. + test_email_recipient: + label: Test e-posta alıcıları + text: Test gönderimlerini alacak e-posta adresini girin. + msg: Test e-posta alıcıları geçersiz + smtp_authentication: + label: Kimlik doğrulamayı etkinleştir + title: SMTP kimlik doğrulaması + msg: SMTP kimlik doğrulaması boş olamaz. + "yes": "Evet" + "no": "Hayır" + branding: + page_title: Marka + logo: + label: Logo + msg: Logo boş olamaz. + text: Sitenizin sol üst köşesindeki logo resmi. 56 yüksekliğinde ve 3:1'den büyük en-boy oranlı geniş dikdörtgen bir resim kullanın. Boş bırakılırsa, site başlık metni gösterilecektir. + mobile_logo: + label: Mobil logo + text: Sitenizin mobil versiyonunda kullanılan logo. 56 yüksekliğinde geniş dikdörtgen bir resim kullanın. Boş bırakılırsa, "logo" ayarındaki resim kullanılacaktır. + square_icon: + label: Kare simge + msg: Kare simge boş olamaz. + text: Meta veri simgeleri için temel olarak kullanılan resim. İdeal olarak 512x512'den büyük olmalıdır. + favicon: + label: Favicon + text: Siteniz için bir favicon. CDN üzerinde düzgün çalışması için png olmalıdır. 32x32 boyutuna yeniden boyutlandırılacaktır. Boş bırakılırsa, "kare simge" kullanılacaktır. + legal: + page_title: Yasal + terms_of_service: + label: Kullanım şartları + text: "Buraya kullanım şartları içeriği ekleyebilirsiniz. Başka bir yerde barındırılan bir belgeniz varsa, tam URL'yi buraya girin." + privacy_policy: + label: Gizlilik politikası + text: "Buraya gizlilik politikası içeriği ekleyebilirsiniz. Başka bir yerde barındırılan bir belgeniz varsa, tam URL'yi buraya girin." + external_content_display: + label: Harici içerik + text: "İçerik, harici web sitelerinden gömülen resimler, videolar ve medyayı içerir." + always_display: Her zaman harici içeriği göster + ask_before_display: Harici içeriği göstermeden önce sor + write: + page_title: Yazma + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Cevap yazma + label: Her kullanıcı aynı soru için sadece bir cevap yazabilir + text: "Kullanıcıların aynı soruya birden fazla cevap yazmasına izin vermek için kapatın, bu cevapların odaktan uzaklaşmasına neden olabilir." + min_tags: + label: "Soru başına minimum etiket" + text: "Bir soruda bulunması gereken minimum etiket sayısı." + recommend_tags: + label: Önerilen etiketler + text: "Önerilen etiketler varsayılan olarak açılır listede gösterilecektir." + msg: + contain_reserved: "önerilen etiketler ayrılmış etiketleri içeremez" + required_tag: + title: Gerekli etiketleri ayarla + label: Önerilen etiketleri gerekli etiketler olarak ayarla + text: "Her yeni soru en az bir önerilen etikete sahip olmalıdır." + reserved_tags: + label: Ayrılmış etiketler + text: "Ayrılmış etiketler sadece moderatör tarafından kullanılabilir." + image_size: + label: Maksimum resim boyutu (MB) + text: "Maksimum resim yükleme boyutu." + attachment_size: + label: Maksimum ek dosya boyutu (MB) + text: "Maksimum ek dosya yükleme boyutu." + image_megapixels: + label: Maksimum resim megapikseli + text: "Bir resim için izin verilen maksimum megapiksel sayısı." + image_extensions: + label: İzin verilen resim uzantıları + text: "Resim gösterimi için izin verilen dosya uzantılarının listesi, virgülle ayırın." + attachment_extensions: + label: İzin verilen ek dosya uzantıları + text: "Yükleme için izin verilen dosya uzantılarının listesi, virgülle ayırın. UYARI: Yüklemelere izin vermek güvenlik sorunlarına neden olabilir." + seo: + page_title: SEO + permalink: + label: Kalıcı bağlantı + text: Özel URL yapıları, bağlantılarınızın kullanılabilirliğini ve ileriye dönük uyumluluğunu iyileştirebilir. + robots: + label: robots.txt + text: Bu, ilgili tüm site ayarlarını kalıcı olarak geçersiz kılacaktır. + themes: + page_title: Temalar + themes: + label: Temalar + text: Mevcut bir tema seçin. + color_scheme: + label: Renk şeması + navbar_style: + label: Gezinme çubuğu arka plan stili + primary_color: + label: Ana renk + text: Temalarınızda kullanılan renkleri değiştirin + css_and_html: + page_title: CSS ve HTML + custom_css: + label: Özel CSS + text: > + Bu <link> olarak eklenecektir + head: + label: Head + text: > + Bu </head> öncesine eklenecektir + header: + label: Header + text: > + Bu <body> sonrasına eklenecektir + footer: + label: Footer + text: Bu </body> öncesine eklenecektir + sidebar: + label: Kenar çubuğu + text: Bu kenar çubuğuna eklenecektir. + login: + page_title: Giriş + membership: + title: Üyelik + label: Yeni kayıtlara izin ver + text: Herhangi birinin yeni hesap oluşturmasını engellemek için kapatın. + email_registration: + title: E-posta kaydı + label: E-posta kaydına izin ver + text: Herhangi birinin e-posta yoluyla yeni hesap oluşturmasını engellemek için kapatın. + allowed_email_domains: + title: İzin verilen e-posta alan adları + text: Kullanıcıların hesap kaydı yapması gereken e-posta alan adları. Her satırda bir alan adı. Boş olduğunda dikkate alınmaz. + private: + title: Özel + label: Giriş gerekli + text: Bu topluluğa sadece giriş yapmış kullanıcılar erişebilir. + password_login: + title: Parola ile giriş + label: E-posta ve parola ile girişe izin ver + text: "UYARI: Kapatırsanız, daha önce başka bir giriş yöntemi yapılandırmadıysanız giriş yapamayabilirsiniz." + installed_plugins: + title: Kurulu Eklentiler + plugin_link: Eklentiler işlevselliği genişletir ve artırır. Eklentileri <1>Eklenti Deposu'nda bulabilirsiniz. + filter: + all: Tümü + active: Aktif + inactive: Pasif + outdated: Güncel değil + plugins: + label: Eklentiler + text: Mevcut bir eklenti seçin. + name: İsim + version: Sürüm + status: Durum + action: Eylem + deactivate: Devre dışı bırak + activate: Etkinleştir + settings: Ayarlar + settings_users: + title: Kullanıcılar + avatar: + label: Varsayılan avatar + text: Kendi özel avatarı olmayan kullanıcılar için. + gravatar_base_url: + label: Gravatar temel URL'si + text: Gravatar sağlayıcısının API temel URL'si. Boş olduğunda dikkate alınmaz. + profile_editable: + title: Profil düzenlenebilir + allow_update_display_name: + label: Kullanıcıların görünen adlarını değiştirmelerine izin ver + allow_update_username: + label: Kullanıcıların kullanıcı adlarını değiştirmelerine izin ver + allow_update_avatar: + label: Kullanıcıların profil resimlerini değiştirmelerine izin ver + allow_update_bio: + label: Kullanıcıların hakkında bilgilerini değiştirmelerine izin ver + allow_update_website: + label: Kullanıcıların web sitelerini değiştirmelerine izin ver + allow_update_location: + label: Kullanıcıların konumlarını değiştirmelerine izin ver + privilege: + title: Ayrıcalıklar + level: + label: Gereken itibar seviyesi + text: Ayrıcalıklar için gereken itibarı seçin + msg: + should_be_number: giriş bir sayı olmalıdır + number_larger_1: sayı 1'e eşit veya daha büyük olmalıdır + badges: + action: Eylem + active: Aktif + activate: Etkinleştir + all: Tümü + awards: Ödüller + deactivate: Devre dışı bırak + filter: + placeholder: İsme göre filtreleme, badge:id + group: Grup + inactive: Pasif + name: İsim + show_logs: Kayıtları göster + status: Durum + title: Rozetler + form: + optional: (isteğe bağlı) + empty: boş olamaz + invalid: geçersiz + btn_submit: Kaydet + not_found_props: "Gerekli {{ key }} özelliği bulunamadı." + select: Seç + page_review: + review: İnceleme + proposed: önerilen + question_edit: Soru düzenleme + answer_edit: Cevap düzenleme + tag_edit: Etiket düzenleme + edit_summary: Düzenleme özeti + edit_question: Soruyu düzenle + edit_answer: Cevabı düzenle + edit_tag: Etiketi düzenle + empty: İncelenecek görev kalmadı. + approve_revision_tip: Bu revizyonu onaylıyor musunuz? + approve_flag_tip: Bu bildirimi onaylıyor musunuz? + approve_post_tip: Bu gönderiyi onaylıyor musunuz? + approve_user_tip: Bu kullanıcıyı onaylıyor musunuz? + suggest_edits: Önerilen düzenlemeler + flag_post: Gönderiyi bildir + flag_user: Kullanıcıyı bildir + queued_post: Sıradaki gönderi + queued_user: Sıradaki kullanıcı + filter_label: Tür + reputation: itibar + flag_post_type: Bu gönderiyi {{ type }} olarak bildirdi. + flag_user_type: Bu kullanıcıyı {{ type }} olarak bildirdi. + edit_post: Gönderiyi düzenle + list_post: Gönderiyi listele + unlist_post: Gönderiyi listeden kaldır + timeline: + undeleted: silme geri alındı + deleted: silindi + downvote: negatif oy + upvote: pozitif oy + accept: kabul et + cancelled: iptal edildi + commented: yorum yapıldı + rollback: geri alındı + edited: düzenlendi + answered: cevaplandı + asked: soruldu + closed: kapatıldı + reopened: yeniden açıldı + created: oluşturuldu + pin: sabitlendi + unpin: sabitlenme kaldırıldı + show: listelendi + hide: listelenmedi + title: "Geçmiş:" + tag_title: "Zaman çizelgesi:" + show_votes: "Oyları göster" + n_or_a: Yok + title_for_question: "Zaman çizelgesi:" + title_for_answer: "{{ author }} tarafından {{ title }} sorusuna verilen cevabın zaman çizelgesi" + title_for_tag: "Etiket için zaman çizelgesi" + datetime: Tarih/Saat + type: Tür + by: Yapan + comment: Yorum + no_data: "Hiçbir şey bulamadık." + users: + title: Kullanıcılar + users_with_the_most_reputation: Bu hafta en yüksek itibar puanına sahip kullanıcılar + users_with_the_most_vote: Bu hafta en çok oy veren kullanıcılar + staffs: Topluluk ekibimiz + reputation: itibar + votes: oy + prompt: + leave_page: Sayfadan ayrılmak istediğinizden emin misiniz? + changes_not_save: Değişiklikleriniz kaydedilmeyebilir. + draft: + discard_confirm: Taslağınızı atmak istediğinizden emin misiniz? + messages: + post_deleted: Bu gönderi silindi. + post_cancel_deleted: Bu gönderinin silme işlemi geri alındı. + post_pin: Bu gönderi sabitlendi. + post_unpin: Bu gönderinin sabitlenmesi kaldırıldı. + post_hide_list: Bu gönderi listede gizlendi. + post_show_list: Bu gönderi listede gösterildi. + post_reopen: Bu gönderi yeniden açıldı. + post_list: Bu gönderi listelendi. + post_unlist: Bu gönderi listeden kaldırıldı. + post_pending: Gönderiniz inceleme bekliyor. Bu bir önizlemedir, onaylandıktan sonra görünür olacaktır. + post_closed: Bu gönderi kapatıldı. + answer_deleted: Bu cevap silindi. + answer_cancel_deleted: Bu cevabın silme işlemi geri alındı. + change_user_role: Bu kullanıcının rolü değiştirildi. + user_inactive: Bu kullanıcı zaten etkin değil. + user_normal: Bu kullanıcı zaten normal durumda. + user_suspended: Bu kullanıcı askıya alındı. + user_deleted: Bu kullanıcı silindi. + badge_activated: Bu rozet etkinleştirildi. + badge_inactivated: Bu rozet devre dışı bırakıldı. + users_deleted: Bu kullanıcılar silindi. + posts_deleted: Bu sorular silindi. + answers_deleted: Bu cevaplar silindi. + copy: Panoya kopyala + copied: Kopyalandı + external_content_warning: Harici resimler/medya gösterilmiyor. + + diff --git a/data/i18n/uk_UA.yaml b/data/i18n/uk_UA.yaml new file mode 100644 index 000000000..a9f6aa32a --- /dev/null +++ b/data/i18n/uk_UA.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Успішно. + unknown: + other: Невідома помилка. + request_format_error: + other: Неприпустимий формат запиту. + unauthorized_error: + other: Не авторизовано. + database_error: + other: Помилка сервера даних. + forbidden_error: + other: Заборонено. + duplicate_request_error: + other: Повторний запит. + action: + report: + other: Відмітити + edit: + other: Редагувати + delete: + other: Видалити + close: + other: Закрити + reopen: + other: Відкрити знову + forbidden_error: + other: Заборонено. + pin: + other: Закріпити + hide: + other: Вилучити зі списку + unpin: + other: Відкріпити + show: + other: Список + invite_someone_to_answer: + other: Редагувати + undelete: + other: Скасувати видалення + merge: + other: Merge + role: + name: + user: + other: Користувач + admin: + other: Адмін + moderator: + other: Модератор + description: + user: + other: За замовчуванням без спеціального доступу. + admin: + other: Має повний доступ до сайту. + moderator: + other: Має доступ до всіх дописів, окрім налаштувань адміністратора. + privilege: + level_1: + description: + other: Рівень 1 (для приватної команди, групи потрібна менша репутація) + level_2: + description: + other: Рівень 2 (низька репутація, необхідна для стартап-спільноти) + level_3: + description: + other: Рівень 3 (висока репутація, необхідна для зрілої спільноти) + level_custom: + description: + other: Користувацький рівень + rank_question_add_label: + other: Задати питання + rank_answer_add_label: + other: Написати відповідь + rank_comment_add_label: + other: Написати коментар + rank_report_add_label: + other: Відмітити + rank_comment_vote_up_label: + other: Проголосувати за коментар + rank_link_url_limit_label: + other: Публікуйте більш ніж 2 посилання одночасно + rank_question_vote_up_label: + other: Проголосувати за питання + rank_answer_vote_up_label: + other: Проголосувати за відповідь + rank_question_vote_down_label: + other: Проголосувати проти питання + rank_answer_vote_down_label: + other: Проголосувати проти відповіді + rank_invite_someone_to_answer_label: + other: Запросити когось відповісти + rank_tag_add_label: + other: Створити новий теґ + rank_tag_edit_label: + other: Редагувати опис теґу (необхідно розглянути) + rank_question_edit_label: + other: Редагувати чуже питання (необхідно розглянути) + rank_answer_edit_label: + other: Редагувати чужу відповідь (необхідно розглянути) + rank_question_edit_without_review_label: + other: Редагувати чуже питання без розгляду + rank_answer_edit_without_review_label: + other: Редагувати чужу відповідь без розгляду + rank_question_audit_label: + other: Переглянути редагування питання + rank_answer_audit_label: + other: Переглянути редагування відповіді + rank_tag_audit_label: + other: Переглянути редагування теґу + rank_tag_edit_without_review_label: + other: Редагувати опис теґу без розгляду + rank_tag_synonym_label: + other: Керування синонімами тегів + email: + other: Електронна пошта + e_mail: + other: Електронна пошта + password: + other: Пароль + pass: + other: Пароль + old_pass: + other: Current password + original_text: + other: Цей допис + email_or_password_wrong_error: + other: Електронна пошта та пароль не збігаються. + error: + common: + invalid_url: + other: Невірна URL. + status_invalid: + other: Неприпустимий статус. + password: + space_invalid: + other: Пароль не може містити пробіли. + admin: + cannot_update_their_password: + other: Ви не можете змінити свій пароль. + cannot_edit_their_profile: + other: Ви не можете змінити свій профіль. + cannot_modify_self_status: + other: Ви не можете змінити свій статус. + email_or_password_wrong: + other: Електронна пошта та пароль не збігаються. + answer: + not_found: + other: Відповідь не знайдено. + cannot_deleted: + other: Немає дозволу на видалення. + cannot_update: + other: Немає дозволу на оновлення. + question_closed_cannot_add: + other: Питання закриті й не можуть бути додані. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Коментарі не можна редагувати. + not_found: + other: Коментар не знайдено. + cannot_edit_after_deadline: + other: Час коментаря був занадто довгим, щоб його можна було змінити. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: Такий E-mail вже існує. + need_to_be_verified: + other: Електронна пошта повинна бути підтверджена. + verify_url_expired: + other: Термін дії підтвердженої URL-адреси закінчився, будь ласка, надішліть листа повторно. + illegal_email_domain_error: + other: З цього поштового домену заборонено надсилати електронну пошту. Будь ласка, використовуйте інший. + lang: + not_found: + other: Мовний файл не знайдено. + object: + captcha_verification_failed: + other: Неправильно введено капчу. + disallow_follow: + other: Вам не дозволено підписатися. + disallow_vote: + other: Вам не дозволено голосувати. + disallow_vote_your_self: + other: Ви не можете проголосувати за власну публікацію. + not_found: + other: Обʼєкт не знайдено. + verification_failed: + other: Не вдалося виконати перевірку. + email_or_password_incorrect: + other: Електронна пошта та пароль не збігаються. + old_password_verification_failed: + other: Не вдалося перевірити старий пароль + new_password_same_as_previous_setting: + other: Новий пароль збігається з попереднім. + already_deleted: + other: Публікацію видалено. + meta: + object_not_found: + other: Мета-об'єкт не знайдено + question: + already_deleted: + other: Публікацію видалено. + under_review: + other: Ваше повідомлення очікує на розгляд. Його буде видно після того, як воно буде схвалено. + not_found: + other: Питання не знайдено. + cannot_deleted: + other: Немає дозволу на видалення. + cannot_close: + other: Немає дозволу на закриття. + cannot_update: + other: Немає дозволу на оновлення. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Ранг репутації не відповідає умові. + vote_fail_to_meet_the_condition: + other: Дякуємо за відгук. Щоб проголосувати, вам потрібна репутація не нижче {{.Rank}}. + no_enough_rank_to_operate: + other: Щоб це зробити, вам потрібна репутація не менше {{.Rank}}. + report: + handle_failed: + other: Не вдалося обробити звіт. + not_found: + other: Звіт не знайдено. + tag: + already_exist: + other: Теґ уже існує. + not_found: + other: Теґ не знайдено. + recommend_tag_not_found: + other: Рекомендований теґ не існує. + recommend_tag_enter: + other: Будь ласка, введіть принаймні один необхідний тег. + not_contain_synonym_tags: + other: Не повинно містити теґи синонімів. + cannot_update: + other: Немає дозволу на оновлення. + is_used_cannot_delete: + other: Ви не можете видалити теґ, який використовується. + cannot_set_synonym_as_itself: + other: Ви не можете встановити синонім поточного тегу як сам тег. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: Ім’я відправника не може бути електронною адресою. + theme: + not_found: + other: Тему не знайдено. + revision: + review_underway: + other: Наразі неможливо редагувати, є версія в черзі перегляду. + no_permission: + other: Немає дозволу на перегляд. + user: + external_login_missing_user_id: + other: Платформа сторонніх розробників не надає унікальний ідентифікатор користувача, тому ви не можете увійти, будь ласка, зв’яжіться з адміністратором вебсайту. + external_login_unbinding_forbidden: + other: Будь ласка, встановіть пароль для входу до свого облікового запису, перш ніж видалити ім'я користувача. + email_or_password_wrong: + other: + other: Електронна пошта та пароль не збігаються. + not_found: + other: Користувач не знайдений. + suspended: + other: Користувач був призупинений. + username_invalid: + other: Ім'я користувача недійсне. + username_duplicate: + other: Це ім'я користувача вже використовується. + set_avatar: + other: Не вдалося встановити аватар. + cannot_update_your_role: + other: Ви не можете змінити вашу роль. + not_allowed_registration: + other: На цей час сайт не відкритий для реєстрації. + not_allowed_login_via_password: + other: Наразі на сайті заборонено вхід за допомогою пароля. + access_denied: + other: Доступ заборонено + page_access_denied: + other: Ви не маєте доступу до цієї сторінки. + add_bulk_users_format_error: + other: "Помилка формату {{.Field}} біля '{{.Content}}' у рядку {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "Кількість користувачів, яких ви додаєте одночасно, має бути в діапазоні 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Не вдалося прочитати конфігурацію + database: + connection_failed: + other: Не вдалося встановити з'єднання з базою даних + create_table_failed: + other: Не вдалося створити таблицю + install: + create_config_failed: + other: Не вдалося створити config.yaml файл. + upload: + unsupported_file_format: + other: Непідтримуваний формат файлу. + site_info: + config_not_found: + other: Конфігурацію сайту не знайдено. + badge: + object_not_found: + other: Об'єкт значка не знайдено + reason: + spam: + name: + other: спам + desc: + other: Це повідомлення є рекламою або вандалізмом. Воно не є корисним або не має відношення до поточної теми. + rude_or_abusive: + name: + other: грубо чи образливо + desc: + other: "Розумна людина вважатиме такий зміст неприйнятним для ввічливого спілкування." + a_duplicate: + name: + other: дублікат + desc: + other: Це питання ставилося раніше, і на нього вже є відповідь. + placeholder: + other: Введіть наявне посилання на питання + not_a_answer: + name: + other: не відповідь + desc: + other: "Це повідомлення було опубліковане як відповідь, але воно не є спробою відповісти на запитання. Можливо, його слід відредагувати, прокоментувати, поставити інше запитання або взагалі видалити." + no_longer_needed: + name: + other: більше не потрібно + desc: + other: Цей коментар є застарілим, розмовним або не стосується цієї публікації. + something: + name: + other: інше + desc: + other: Ця публікація вимагає уваги персоналу з іншої причини, що не вказана вище. + placeholder: + other: Дайте нам знати, що саме вас турбує + community_specific: + name: + other: причина для спільноти + desc: + other: Це запитання не відповідає правилам спільноти. + not_clarity: + name: + other: потребує деталей або ясності + desc: + other: Наразі це запитання містить кілька запитань в одному. Воно має бути зосереджене лише на одній проблемі. + looks_ok: + name: + other: виглядає добре + desc: + other: Цей допис хороший, як є, і не є низької якості. + needs_edit: + name: + other: потребує редагування, і я це зробив + desc: + other: Поліпшіть та виправте проблеми з цією публікацією самостійно. + needs_close: + name: + other: потрібно закрити + desc: + other: Закрите питання не може відповісти, але все ще може редагувати, голосувати і коментувати. + needs_delete: + name: + other: потрібно видалити + desc: + other: Цей допис буде видалено. + question: + close: + duplicate: + name: + other: спам + desc: + other: Це питання ставилося раніше, і на нього вже є відповідь. + guideline: + name: + other: причина для спільноти + desc: + other: Це запитання не відповідає правилам спільноти. + multiple: + name: + other: потребує деталей або ясності + desc: + other: Наразі це питання включає кілька запитань в одному. Воно має зосереджуватися лише на одній проблемі. + other: + name: + other: інше + desc: + other: Для цього допису потрібна інша причина, не зазначена вище. + operation_type: + asked: + other: запитав + answered: + other: відповів + modified: + other: змінено + deleted_title: + other: Видалене питання + questions_title: + other: Питання + tag: + tags_title: + other: Теґи + no_description: + other: Тег не має опису. + notification: + action: + update_question: + other: оновлене питання + answer_the_question: + other: питання з відповіддю + update_answer: + other: оновлена відповідь + accept_answer: + other: прийнята відповідь + comment_question: + other: прокоментоване питання + comment_answer: + other: прокоментована відповідь + reply_to_you: + other: відповів(-ла) вам + mention_you: + other: згадав(-ла) вас + your_question_is_closed: + other: Ваше запитання закрито + your_question_was_deleted: + other: Ваше запитання видалено + your_answer_was_deleted: + other: Вашу відповідь видалено + your_comment_was_deleted: + other: Ваш коментар видалено + up_voted_question: + other: питання, за яке найбільше проголосували + down_voted_question: + other: питання, за яке проголосували менше + up_voted_answer: + other: відповідь, за яку проголосували найбільше + down_voted_answer: + other: downvoted answer + up_voted_comment: + other: коментар, за який проголосували + invited_you_to_answer: + other: запросив(-ла) вас відповісти + earned_badge: + other: Ви заробили бейдж "{{.BadgeName}}" + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Підтвердіть нову адресу електронної пошти" + body: + other: "Підтвердьте свою нову адресу електронної пошти для {{.SiteName}} натиснувши на наступне посилання:
        \n{{.ChangeEmailUrl}}

        \n\nЯкщо ви не запитували цю зміну, будь ласка, ігноруйте цей лист.

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} відповів(-ла) на ваше запитання" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nПереглянути на {{.SiteName}}

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена.

        \n\nВідписатися" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} запросив(-ла) вас відповісти" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Думаю, ви можете знати відповідь.

        \nПереглянути на {{.SiteName}}

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена.

        \n\nВідписатися" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} прокоментували ваш допис" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nПереглянути на {{.SiteName}}

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена.

        \n\nВідписатися" + new_question: + title: + other: "[{{.SiteName}}] Нове питання: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Скидання пароля" + body: + other: "Хтось попросив скинути ваш пароль на {{.SiteName}}.

        \n\nЯкщо це не ви, можете сміливо ігнорувати цей лист.

        \n\nПерейдіть за наступним посиланням, щоб вибрати новий пароль:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена." + register: + title: + other: "[{{.SiteName}}] Підтвердьте свій новий обліковий запис" + body: + other: "Ласкаво просимо до {{.SiteName}}!

        \n\nПерейдіть за наступним посиланням, щоб підтвердити та активувати свій новий обліковий запис:
        \n{{.RegisterUrl}}

        \n\nЯкщо наведене вище посилання не відкривається, спробуйте скопіювати і вставити його в адресний рядок вашого веб-браузера.\n

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена." + test: + title: + other: "[{{.SiteName}}] Тестовий електронний лист" + body: + other: "Це тестовий електронний лист.\n

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена." + action_activity_type: + upvote: + other: підтримати + upvoted: + other: підтримано + downvote: + other: голос "проти" + downvoted: + other: проголосував проти + accept: + other: прийняти + accepted: + other: прийнято + edit: + other: редагувати + review: + queued_post: + other: Допис у черзі + flagged_post: + other: Відмічений пост + suggested_post_edit: + other: Запропоновані зміни + reaction: + tooltip: + other: "{{ .Names }} і {{ .Count }} більше..." + badge: + default_badges: + autobiographer: + name: + other: Автобіограф + desc: + other: Заповнена інформація про профіль. + certified: + name: + other: Підтверджений + desc: + other: Завершено наш новий посібник користувача. + editor: + name: + other: Редактор + desc: + other: Перше редагування посту. + first_flag: + name: + other: Перший прапор + desc: + other: Спочатку позначено допис. + first_upvote: + name: + other: Перший голос за + desc: + other: Першим голосував за допис. + first_link: + name: + other: Перше посилання + desc: + other: First added a link to another post. + first_reaction: + name: + other: Перша реакція + desc: + other: Першим відреагував на допис. + first_share: + name: + other: Перше поширення + desc: + other: Перший поділився публікацією. + scholar: + name: + other: Вчений + desc: + other: Поставив питання і прийняв відповідь. + commentator: + name: + other: Коментатор + desc: + other: Залиште 5 коментарів. + new_user_of_the_month: + name: + other: Новий користувач місяця + desc: + other: Видатні внески за їх перший місяць. + read_guidelines: + name: + other: Прочитайте Інструкцію + desc: + other: Прочитайте [рекомендації для спільноти]. + reader: + name: + other: Читач + desc: + other: Прочитайте кожну відповідь у темі з більш ніж 10 відповідями. + welcome: + name: + other: Ласкаво просимо + desc: + other: Отримав голос. + nice_share: + name: + other: Гарне поширення + desc: + other: Поділилися постом з 25 унікальними відвідувачами. + good_share: + name: + other: Хороше поширення + desc: + other: Поділилися постом з 300 унікальними відвідувачами. + great_share: + name: + other: Відмінне поширення + desc: + other: Поділилися постом з 1000 унікальними відвідувачами. + out_of_love: + name: + other: З любові + desc: + other: Використав 50 голосів «за» за день. + higher_love: + name: + other: Вище кохання + desc: + other: Використав 50 голосів «за» за день 5 разів. + crazy_in_love: + name: + other: Божевільний в любові + desc: + other: Використав 50 голосів «за» за день 20 разів. + promoter: + name: + other: Промоутер + desc: + other: Запросив користувача. + campaigner: + name: + other: Агітатор + desc: + other: Запрошено 3 основних користувачів. + champion: + name: + other: Чемпіон + desc: + other: Запросив 5 учасників. + thank_you: + name: + other: Дякую + desc: + other: Має 20 дописів, за які проголосували, і віддав 10 голосів «за». + gives_back: + name: + other: Дає назад + desc: + other: Має 100 дописів, за які проголосували, і віддав 100 голосів «за». + empathetic: + name: + other: Емпатичний + desc: + other: Має 500 дописів, за які проголосували, і віддав 1000 голосів «за». + enthusiast: + name: + other: Ентузіаст + desc: + other: Відвідано 10 днів поспіль. + aficionado: + name: + other: Шанувальник + desc: + other: Відвідано 100 днів поспіль. + devotee: + name: + other: Відданий + desc: + other: Відвідано 365 днів поспіль. + anniversary: + name: + other: Річниця + desc: + other: Активний учасник на рік, опублікував принаймні один раз. + appreciated: + name: + other: Оцінений + desc: + other: Отримано 1 голос за 20 дописів. + respected: + name: + other: Шанований + desc: + other: Отримано 2 голоси за 100 дописів. + admired: + name: + other: Захоплений + desc: + other: Отримано 5 голосів за 300 дописів. + solved: + name: + other: Вирішено + desc: + other: Нехай відповідь буде прийнята. + guidance_counsellor: + name: + other: Радник супроводу + desc: + other: Прийміть 10 відповідей. + know_it_all: + name: + other: Усезнайко + desc: + other: Було прийнято 50 відповідей. + solution_institution: + name: + other: Інституція рішення + desc: + other: Було прийнято 150 відповідей. + nice_answer: + name: + other: Чудова відповідь + desc: + other: Оцінка відповіді на 10 або більше. + good_answer: + name: + other: Гарна відповідь + desc: + other: Оцінка відповіді на 25 або більше. + great_answer: + name: + other: Чудова відповідь + desc: + other: Оцінка відповіді на 50 або більше. + nice_question: + name: + other: Гарне питання + desc: + other: Оцінка питання на 10 або більше. + good_question: + name: + other: Хороше питання + desc: + other: Оцінка питання на 25 або більше. + great_question: + name: + other: Відмінне питання + desc: + other: Оцінка питання на 50 або більше. + popular_question: + name: + other: Популярне питання + desc: + other: Питання з 500 переглядами. + notable_question: + name: + other: Помітне питання + desc: + other: Питання з 1000 переглядами. + famous_question: + name: + other: Знамените питання + desc: + other: Питання з 5000 переглядами. + popular_link: + name: + other: Популярне посилання + desc: + other: Опубліковано зовнішнє посилання з 50 натисканнями. + hot_link: + name: + other: Гаряче посилання + desc: + other: Опубліковано зовнішнє посилання з 300 натисканнями. + famous_link: + name: + other: Знамените Посилання + desc: + other: Опубліковано зовнішнє посилання зі 100 натисканнями. + default_badge_groups: + getting_started: + name: + other: Початок роботи + community: + name: + other: Спільнота + posting: + name: + other: Публікація +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Як відформатувати + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: Назад + next: Далі + page_title: + question: Запитання + questions: Запитання + tag: Теґ + tags: Теґи + tag_wiki: тег вікі + create_tag: Створити теґ + edit_tag: Редагувати теґ + ask_a_question: Create Question + edit_question: Редагувати запитання + edit_answer: Редагувати відповідь + search: Пошук + posts_containing: Публікації, що містять + settings: Налаштування + notifications: Сповіщення + login: Увійти + sign_up: Зареєструватися + account_recovery: Відновлення облікового запису + account_activation: Активація облікового запису + confirm_email: Підтвердити електронну адресу + account_suspended: Обліковий запис призупинено + admin: Адмін + change_email: Змінити електронну адресу + install: Встановлення Answer + upgrade: Оновлення Answer + maintenance: Технічне обслуговування сайту + users: Користувачі + oauth_callback: Обробка + http_404: Помилка HTTP 404 + http_50X: Помилка HTTP 500 + http_403: Помилка HTTP 403 + logout: Вийти + posts: Posts + notifications: + title: Сповіщення + inbox: Вхідні + achievement: Досягнення + new_alerts: Нові сповіщення + all_read: Позначити все як прочитане + show_more: Показати більше + someone: Хтось + inbox_type: + all: Усі + posts: Публікації + invites: Запрошення + votes: Голоси + answer: Відповідь + question: Запитання + badge_award: Значок + suspended: + title: Ваш обліковий запис було призупинено + until_time: "Ваш обліковий запис призупинено до {{ time }}." + forever: Цього користувача призупинено назавжди. + end: Ви не дотримуєтеся правил спільноти. + contact_us: Зв'яжіться з нами + editor: + blockquote: + text: Блок Цитування + bold: + text: Надійний + chart: + text: Діаграма + flow_chart: Блок-схема + sequence_diagram: Діаграма послідовності + class_diagram: Діаграма класів + state_diagram: Діаграма станів + entity_relationship_diagram: Діаграма зв'язків сутностей + user_defined_diagram: Визначена користувачем діаграма + gantt_chart: Діаграма Ґанта + pie_chart: Кругова діаграма + code: + text: Зразок коду + add_code: Додати зразок коду + form: + fields: + code: + label: Код + msg: + empty: Код не може бути порожнім. + language: + label: Мова + placeholder: Автоматичне визначення + btn_cancel: Скасувати + btn_confirm: Додати + formula: + text: Формула + options: + inline: Вбудована формула + block: Формула блоку + heading: + text: Заголовок + options: + h1: Заголовок 1 + h2: Заголовок 2 + h3: Заголовок 3 + h4: Заголовок 4 + h5: Заголовок 5 + h6: Заголовок 6 + help: + text: Допомога + hr: + text: Горизонтальна лінійка + image: + text: Зображення + add_image: Додати зображення + tab_image: Завантажити зображення + form_image: + fields: + file: + label: Файл зображення + btn: Обрати зображення + msg: + empty: Файл не може бути порожнім. + only_image: Допустимі лише файли зображень. + max_size: Розмір файлу не може перевищувати {{size}} МБ. + desc: + label: Опис + tab_url: URL зображення + form_url: + fields: + url: + label: URL зображення + msg: + empty: URL-адреса зображення не може бути пустою. + name: + label: Опис + btn_cancel: Скасувати + btn_confirm: Додати + uploading: Завантаження + indent: + text: Абзац + outdent: + text: Відступ + italic: + text: Акцент + link: + text: Гіперпосилання + add_link: Додати гіперпосилання + form: + fields: + url: + label: URL + msg: + empty: URL-адреса не може бути пустою. + name: + label: Опис + btn_cancel: Скасувати + btn_confirm: Додати + ordered_list: + text: Нумерований список + unordered_list: + text: Маркований список + table: + text: Таблиця + heading: Заголовок + cell: Клітинка + file: + text: Прикріпити файли + not_supported: "Не підтримується цей тип файлу. Спробуйте ще раз з {{file_type}}." + max_size: "Розмір прикріплених файлів не може перевищувати {{size}} МБ." + close_modal: + title: Я закриваю цей пост, оскільки... + btn_cancel: Скасувати + btn_submit: Надіслати + remark: + empty: Не може бути порожнім. + msg: + empty: Будь ласка, оберіть причину. + report_modal: + flag_title: Я ставлю відмітку, щоб повідомити про цю публікацію як... + close_title: Я закриваю цей пост, оскільки... + review_question_title: Переглянути питання + review_answer_title: Переглянути відповідь + review_comment_title: Переглянути коментар + btn_cancel: Скасувати + btn_submit: Надіслати + remark: + empty: Не може бути порожнім. + msg: + empty: Будь ласка, оберіть причину. + not_a_url: Формат URL неправильний. + url_not_match: Походження URL не збігається з поточним вебсайтом. + tag_modal: + title: Створити новий теґ + form: + fields: + display_name: + label: Ім'я для відображення + msg: + empty: Ім'я для відображення не може бути порожнім. + range: Ім'я для відображення до 35 символів. + slug_name: + label: Скорочена URL-адреса + desc: Скорочення URL до 35 символів. + msg: + empty: Скорочення URL не може бути пустим. + range: Скорочення URL до 35 символів. + character: Скорочення URL містить незадовільний набір символів. + desc: + label: Опис + revision: + label: Редакція + edit_summary: + label: Підсумок редагування + placeholder: >- + Коротко поясніть ваші зміни (виправлена орфографія, виправлена граматика, покращене форматування) + btn_cancel: Скасувати + btn_submit: Надіслати + btn_post: Опублікувати новий теґ + tag_info: + created_at: Створено + edited_at: Відредаговано + history: Історія + synonyms: + title: Синоніми + text: Наступні теги буде змінено на + empty: Синонімів не знайдено. + btn_add: Додати синонім + btn_edit: Редагувати + btn_save: Зберегти + synonyms_text: Наступні теги буде змінено на + delete: + title: Видалити цей теґ + tip_with_posts: >- +

        Ми не дозволяємо видаляти тег з дописами.

        Передусім, будь ласка, вилучіть цей тег з дописів.

        + tip_with_synonyms: >- +

        Ми не дозволяємо видаляти тег із синонімами.

        Передусім, будь ласка, вилучіть синоніми з цього тега.

        + tip: Ви впевнені, що хочете видалити? + close: Закрити + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Редагувати теґ + default_reason: Редагувати теґ + default_first_reason: Додати теґ + btn_save_edits: Зберегти зміни + btn_cancel: Скасувати + dates: + long_date: МММ Д + long_date_with_year: "МММ Д, РРРР" + long_date_with_time: "МММ Д, РРРР [о] ГГ:хв" + now: зараз + x_seconds_ago: "{{count}}сек назад" + x_minutes_ago: "{{count}}хв назад" + x_hours_ago: "{{count}}год назад" + hour: година + day: день + hours: годин + days: дні + month: month + months: months + year: year + reaction: + heart: серце + smile: посмішка + frown: насупився + btn_label: додавати або вилучати реакції + undo_emoji: скасувати реакцію {{ emoji }} + react_emoji: реагувати з {{ emoji }} + unreact_emoji: не реагувати з {{ emoji }} + comment: + btn_add_comment: Додати коментар + reply_to: Відповісти на + btn_reply: Відповісти + btn_edit: Редагувати + btn_delete: Видалити + btn_flag: Відмітити + btn_save_edits: Зберегти зміни + btn_cancel: Скасувати + show_more: "Ще {{count}} коментарів" + tip_question: >- + Використовуйте коментарі, щоб попросити більше інформації або запропонувати покращення. Уникайте відповідей на питання в коментарях. + tip_answer: >- + Використовуйте коментарі, щоб відповідати іншим користувачам або повідомляти їх про зміни. Якщо ви додаєте нову інформацію, відредагуйте свою публікацію, а не коментуйте. + tip_vote: Це додає щось корисне до допису + edit_answer: + title: Редагувати відповідь + default_reason: Редагувати відповідь + default_first_reason: Додати відповідь + form: + fields: + revision: + label: Редакція + answer: + label: Відповідь + feedback: + characters: вміст має бути не менше 6 символів. + edit_summary: + label: Редагувати підсумок + placeholder: >- + Коротко поясніть ваші зміни (виправлена орфографія, виправлена граматика, покращене форматування) + btn_save_edits: Зберегти зміни + btn_cancel: Скасувати + tags: + title: Теґи + sort_buttons: + popular: Популярне + name: Назва + newest: Найновіші + button_follow: Підписатися + button_following: Підписані + tag_label: запитання + search_placeholder: Фільтрувати за назвою теґу + no_desc: Цей теґ не має опису. + more: Більше + wiki: Вікі + ask: + title: Create Question + edit_title: Редагувати питання + default_reason: Редагувати питання + default_first_reason: Create question + similar_questions: Подібні питання + form: + fields: + revision: + label: Редакція + title: + label: Назва + placeholder: What's your topic? Be specific. + msg: + empty: Назва не може бути порожньою. + range: Назва до 150 символів + body: + label: Тіло + msg: + empty: Тіло не може бути порожнім. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Теґи + msg: + empty: Теґи не можуть бути порожніми. + answer: + label: Відповідь + msg: + empty: Відповідь не може бути порожньою. + edit_summary: + label: Редагувати підсумок + placeholder: >- + Коротко поясніть ваші зміни (виправлена орфографія, виправлена граматика, покращене форматування) + btn_post_question: Опублікуйте своє запитання + btn_save_edits: Зберегти зміни + answer_question: Відповісти на власне питання + post_question&answer: Опублікуйте своє запитання і відповідь + tag_selector: + add_btn: Додати теґ + create_btn: Створити новий теґ + search_tag: Шукати теґ + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: Не знайдено тегів + tag_required_text: Обов'язковий тег (принаймні один) + header: + nav: + question: Запитання + tag: Теґи + user: Користувачі + badges: Значки + profile: Профіль + setting: Налаштування + logout: Вийти + admin: Адмін + review: Огляд + bookmark: Закладки + moderation: Модерація + search: + placeholder: Пошук + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Змінити + loading: завантаження... + pic_auth_code: + title: Капча + placeholder: Введіть текст вище + msg: + empty: Капча не може бути порожньою. + inactive: + first: >- + Ви майже закінчили! Ми надіслали лист для активації на {{mail}}. Будь ласка, дотримуйтесь інструкцій, щоб активувати свій обліковий запис. + info: "Якщо він не надійшов, перевірте папку зі спамом." + another: >- + Ми надіслали вам інший електронний лист для активації на {{mail}}. Це може зайняти кілька хвилин, перш ніж він прибуде; обов'язково перевірте теку зі спамом. + btn_name: Повторно надіслати електронний лист для активації + change_btn_name: Змінити електронну пошту + msg: + empty: Не може бути порожнім. + resend_email: + url_label: Ви впевнені, що бажаєте повторно надіслати електронний лист для активації? + url_text: Ви також можете дати користувачеві наведене вище посилання для активації. + login: + login_to_continue: Увійдіть, щоб продовжити + info_sign: Немає облікового запису? <1>Зареєструйтесь + info_login: Вже маєте обліковий запис? <1>Увійдіть + agreements: Реєструючись, ви погоджуєтеся з <1>політикою конфіденційності та <3>умовами використання. + forgot_pass: Забули пароль? + name: + label: Ім’я + msg: + empty: Ім'я не може бути порожнім. + range: Ім'я повинно мати довжину від 2 до 30 символів. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: Електронна пошта + msg: + empty: Поле електронної пошти не може бути пустим. + password: + label: Пароль + msg: + empty: Поле паролю не може бути порожнім. + different: Двічі введені паролі є несумісними + account_forgot: + page_title: Забули свій пароль + btn_name: Надішліть мені електронний лист для відновлення + send_success: >- + Якщо обліковий запис збігається з {{mail}}, незабаром ви отримаєте електронний лист з інструкціями щодо скидання пароля. + email: + label: Електронна пошта + msg: + empty: Поле електронної пошти не може бути пустим. + change_email: + btn_cancel: Скасувати + btn_update: Оновити адресу електронної пошти + send_success: >- + Якщо обліковий запис збігається з {{mail}}, незабаром ви отримаєте електронний лист з інструкціями щодо скидання пароля. + email: + label: Нова електронна пошта + msg: + empty: Поле електронної пошти не може бути пустим. + oauth: + connect: З'єднати з {{ auth_name }} + remove: Видалити {{ auth_name }} + oauth_bind_email: + subtitle: Додайте резервну електронну пошту до свого облікового запису. + btn_update: Оновити адресу електронної пошти + email: + label: Електронна пошта + msg: + empty: Поле електронної пошти не може бути пустим. + modal_title: Електронна адреса вже існує. + modal_content: Ця електронна адреса вже зареєстрована. Ви впевнені, що бажаєте підключитися до існуючого облікового запису? + modal_cancel: Змінити електронну пошту + modal_confirm: Під'єднати до існуючого облікового запису + password_reset: + page_title: Скинути пароль + btn_name: Скинути мій пароль + reset_success: >- + Ви успішно змінили пароль; вас буде перенаправлено на сторінку входу в систему. + link_invalid: >- + На жаль, це посилання для зміни пароля більше недійсне. Можливо, ваш пароль уже скинуто? + to_login: Продовжити вхід на сторінку + password: + label: Пароль + msg: + empty: Поле паролю не може бути порожнім. + length: Довжина повинна бути від 8 до 32 символів + different: Двічі введені паролі є несумісними + password_confirm: + label: Підтвердити новий пароль + settings: + page_title: Налаштування + goto_modify: Перейти до зміни + nav: + profile: Профіль + notification: Сповіщення + account: Обліковий запис + interface: Інтерфейс + profile: + heading: Профіль + btn_name: Зберегти + display_name: + label: Ім'я для відображення + msg: Ім'я для відображення не може бути порожнім. + msg_range: Display name must be 2-30 characters in length. + username: + label: Ім'я користувача + caption: Користувачі можуть згадувати вас як "@username". + msg: Ім’я користувача не може бути порожнім. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Зображення профілю + gravatar: Gravatar + gravatar_text: Ви можете змінити зображення на + custom: Власне + custom_text: Ви можете завантажити своє зображення. + default: Системне + msg: Будь ласка, завантажте аватар + bio: + label: Про мене + website: + label: Вебсайт + placeholder: "https://example.com" + msg: Неправильний формат вебсайту + location: + label: Місцезнаходження + placeholder: "Місто, Країна" + notification: + heading: Сповіщення електронною поштою + turn_on: Увімкнути + inbox: + label: Вхідні сповіщення + description: Відповіді на ваші запитання, коментарі, запрошення тощо. + all_new_question: + label: Усі нові запитання + description: Отримуйте сповіщення про всі нові питання. До 50 питань на тиждень. + all_new_question_for_following_tags: + label: Всі нові запитання з наступними тегами + description: Отримувати сповіщення про нові запитання з наступними тегами. + account: + heading: Обліковий запис + change_email_btn: Змінити електронну пошту + change_pass_btn: Змінити пароль + change_email_info: >- + Ми надіслали електронний лист на цю адресу. Будь ласка, дотримуйтесь інструкцій для підтвердження. + email: + label: Нова електронна пошта + new_email: + label: Нова електронна пошта + msg: Нова електронна пошта не може бути порожньою. + pass: + label: Поточний пароль + msg: Комірка паролю не може бути порожньою. + password_title: Пароль + current_pass: + label: Поточний пароль + msg: + empty: Комірка поточного пароля не може бути порожньою. + length: Довжина повинна бути від 8 до 32 символів. + different: Два введені паролі не збігаються. + new_pass: + label: Новий пароль + pass_confirm: + label: Підтвердити новий пароль + interface: + heading: Інтерфейс + lang: + label: Мова інтерфейсу + text: Мова інтерфейсу користувача. Зміниться, коли ви оновите сторінку. + my_logins: + title: Мої логіни + label: Увійдіть або зареєструйтеся на цьому сайті, використовуючи ці облікові записи. + modal_title: Видалити логін + modal_content: Ви впевнені, що хочете видалити цей логін з облікового запису? + modal_confirm_btn: Видалити + remove_success: Успішно видалено + toast: + update: успішно оновлено + update_password: Пароль успішно змінено. + flag_success: Дякую, що відмітили. + forbidden_operate_self: Заборонено застосовувати на собі + review: Ваша версія з'явиться після перевірки. + sent_success: Успішно відправлено + related_question: + title: Related + answers: відповіді + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Люди запитували + desc: Виберіть людей, які, на вашу думку, можуть знати відповідь. + invite: Запросити відповісти + add: Додати людей + search: Шукати людей + question_detail: + action: Дія + created: Created + Asked: Запитали + asked: запитали + update: Змінено + Edited: Edited + edit: відредаговано + commented: прокоментовано + Views: Переглянуто + Follow: Підписатися + Following: Підписані + follow_tip: Підпишіться на це запитання, щоб отримувати сповіщення + answered: дано відповідь + closed_in: Зачинено в + show_exist: Показати наявне запитання. + useful: Корисне + question_useful: Це корисно і ясно + question_un_useful: Це неясно або некорисно + question_bookmark: Додати в закладки це питання + answer_useful: Це корисно + answer_un_useful: Це некорисно + answers: + title: Відповіді + score: Оцінка + newest: Найновіші + oldest: Найдавніші + btn_accept: Прийняти + btn_accepted: Прийнято + write_answer: + title: Ваша відповідь + edit_answer: Редагувати мою чинну відповідь + btn_name: Опублікувати свою відповідь + add_another_answer: Додати ще одну відповідь + confirm_title: Перейти до відповіді + continue: Продовжити + confirm_info: >- +

        Ви впевнені, що хочете додати ще одну відповідь?

        Натомість ви можете скористатися посиланням редагування, щоб уточнити та покращити вже існуючу відповідь.

        + empty: Відповідь не може бути порожньою. + characters: вміст має бути не менше 6 символів. + tips: + header_1: Дякуємо за відповідь + li1_1: Будь ласка, не забудьте відповісти на запитання. Надайте детальну інформацію та поділіться своїми дослідженнями. + li1_2: Підкріплюйте будь-які ваші твердження посиланнями чи особистим досвідом. + header_2: Але уникайте... + li2_1: Просити про допомогу, шукати роз'яснення або реагувати на інші відповіді. + reopen: + confirm_btn: Відкрити знову + title: Повторно відкрити цей допис + content: Ви впевнені, що хочете повторно відкрити? + list: + confirm_btn: Список + title: Показати цей допис + content: Ви впевнені, що хочете скласти список? + unlist: + confirm_btn: Вилучити зі списку + title: Вилучити допис зі списку + content: Ви впевнені, що хочете вилучити зі списку? + pin: + title: Закріпити цей допис + content: Ви впевнені, що хочете закріпити глобально? Цей допис відображатиметься вгорі всіх списків публікацій. + confirm_btn: Закріпити + delete: + title: Видалити цей допис + question: >- + Ми не рекомендуємо видаляти питання з відповідями, оскільки це позбавляє майбутніх читачів цих знань.

        Повторне видалення запитань із відповідями може призвести до блокування запитів у вашому обліковому записі. Ви впевнені, що хочете видалити? + answer_accepted: >- +

        Ми не рекомендуємо видаляти прийняту відповідь, оскільки це позбавляє майбутніх читачів цих знань.

        Повторне видалення прийнятих відповідей може призвести до того, що ваш обліковий запис буде заблоковано для відповідей. Ви впевнені, що хочете видалити? + other: Ви впевнені, що хочете видалити? + tip_answer_deleted: Ця відповідь була видалена + undelete_title: Скасувати видалення цього допису + undelete_desc: Ви впевнені, що бажаєте скасувати видалення? + btns: + confirm: Підтвердити + cancel: Скасувати + edit: Редагувати + save: Зберегти + delete: Видалити + undelete: Скасувати видалення + list: Список + unlist: Вилучити зі списку + unlisted: Вилучене зі списку + login: Увійти + signup: Зареєструватися + logout: Вийти + verify: Підтвердити + create: Create + approve: Затвердити + reject: Відхилити + skip: Пропустити + discard_draft: Видалити чернетку + pinned: Закріплено + all: Усі + question: Запитання + answer: Відповідь + comment: Коментар + refresh: Оновити + resend: Надіслати повторно + deactivate: Деактивувати + active: Активні + suspend: Призупинити + unsuspend: Відновити + close: Закрити + reopen: Відкрити знову + ok: ОК + light: Світла + dark: Темна + system_setting: Налаштування системи + default: За замовчуванням + reset: Скинути + tag: Тег + post_lowercase: допис + filter: Фільтр + ignore: Ігнорувати + submit: Надіслати + normal: Нормальний + closed: Закриті + deleted: Видалені + deleted_permanently: Deleted permanently + pending: Очікування + more: Більше + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Результати пошуку + keywords: Ключові слова + options: Параметри + follow: Підписатися + following: Підписані + counts: "{{count}} Результатів" + counts_loading: "... Results" + more: Більше + sort_btns: + relevance: Релевантність + newest: Найновіші + active: Активні + score: Оцінка + more: Більше + tips: + title: Підказки щодо розширеного пошуку + tag: "<1>[tag] шукати за тегом" + user: "<1>користувач:ім'я користувача пошук за автором" + answer: "<1>відповіді:0 питання без відповіді" + score: "<1>рахунок: 3 записи із 3+ рахунком" + question: "<1>є:питання пошукові питання" + is_answer: "<1>є:відповідь пошукові відповіді" + empty: Ми не змогли нічого знайти.
        Спробуйте різні або менш конкретні ключові слова. + share: + name: Поділитись + copy: Копіювати посилання + via: Поділитися дописом через... + copied: Скопійовано + facebook: Поділитись на Facebook + twitter: Share to X + cannot_vote_for_self: Ви не можете проголосувати за власну публікацію. + modal_confirm: + title: Помилка... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Ваш новий обліковий запис підтверджено; вас буде перенаправлено на головну сторінку. + link: Перейти на головну сторінку + oops: Йой! + invalid: Посилання, яке ви використовували, більше не працює. + confirm_new_email: Вашу адресу електронної пошти було оновлено. + confirm_new_email_invalid: >- + На жаль, це посилання для підтвердження більше не дійсне. Можливо, ваша електронна пошта вже була змінена? + unsubscribe: + page_title: Відписатися + success_title: Ви успішно відписалися + success_desc: Вас успішно вилучено з цього списку підписників, і ви більше не будете отримувати від нас електронні листи. + link: Змінити налаштування + question: + following_tags: Підписки на теги + edit: Редагувати + save: Зберегти + follow_tag_tip: Підпишіться на теги, щоб упорядкувати свій список запитань. + hot_questions: Гарячі питання + all_questions: Всі питання + x_questions: "{{ count }} Питань" + x_answers: "{{ count }} відповідей" + x_posts: "{{ count }} Posts" + questions: Запитання + answers: Відповіді + newest: Найновіші + active: Активні + hot: Гаряче + frequent: Часто + recommend: Рекомендовано + score: Оцінка + unanswered: Без відповідей + modified: змінено + answered: дано відповідь + asked: запитано + closed: закрито + follow_a_tag: Підписатися на тег + more: Більше + personal: + overview: Загальний огляд + answers: Відповіді + answer: відповідь + questions: Запитання + question: запитання + bookmarks: Закладки + reputation: Репутація + comments: Коментарі + votes: Голоси + badges: Значки + newest: Найновіше + score: Оцінка + edit_profile: Редагувати профіль + visited_x_days: "Відвідано {{ count }} днів" + viewed: Переглянуто + joined: Приєднано + comma: "," + last_login: Переглянуто + about_me: Про мене + about_me_empty: "// Привіт, світ!" + top_answers: Найкращі відповіді + top_questions: Найкращі запитання + stats: Статистика + list_empty: Не знайдено жодного допису.
        Можливо, ви хочете вибрати іншу вкладку? + content_empty: Постів не знайдено. + accepted: Прийнято + answered: дано відповідь + asked: запитано + downvoted: проголосовано проти + mod_short: MOD + mod_long: Модератори + x_reputation: репутація + x_votes: отримані голоси + x_answers: відповіді + x_questions: запитання + recent_badges: Нещодавні значки + install: + title: Встановлення + next: Далі + done: Готово + config_yaml_error: Не вдалося створити config.yaml файл. + lang: + label: Будь ласка, виберіть мову + db_type: + label: Рушій бази даних + db_username: + label: Ім'я користувача + placeholder: корінь + msg: Ім’я користувача не може бути порожнім. + db_password: + label: Пароль + placeholder: корінь + msg: Поле паролю не може бути порожнім. + db_host: + label: Хост бази даних + placeholder: "db:3306" + msg: Хост бази даних не може бути порожнім. + db_name: + label: Назва бази даних + placeholder: відповідь + msg: Назва бази даних не може бути порожня. + db_file: + label: Файл бази даних + placeholder: /data/answer.db + msg: Файл бази даних не може бути порожнім. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Створити config.yaml + label: Файл config.yaml створено. + desc: >- + Ви можете створити файл <1>config.yaml вручну в каталозі <1>/var/www/xxx/ і вставити в нього наступний текст. + info: Після цього натисніть кнопку "Далі". + site_information: Інформація про сайт + admin_account: Обліковий запис адміністратора + site_name: + label: Назва сайту + msg: Назва сайту не може бути порожньою. + msg_max_length: Назва сайту повинна містити не більше 30 символів. + site_url: + label: URL сайту + text: Адреса вашого сайту. + msg: + empty: URL-адреса сайту не може бути пустою. + incorrect: Неправильний формат URL-адреси сайту. + max_length: Максимальна довжина URL-адреси сайту – 512 символів. + contact_email: + label: Контактна електронна адреса + text: Електронна адреса основної контактної особи, відповідальної за цей сайт. + msg: + empty: Контактна електронна адреса не може бути порожньою. + incorrect: Неправильний формат контактної електронної пошти. + login_required: + label: Приватний + switch: Вхід обов'язковий + text: Лише авторизовані користувачі можуть отримати доступ до цієї спільноти. + admin_name: + label: Ім’я + msg: Ім'я не може бути порожнім. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Пароль + text: >- + Вам знадобиться цей пароль для входу. Зберігайте його в надійному місці. + msg: Поле паролю не може бути порожнім. + msg_min_length: Пароль має бути не менше 8 символів. + msg_max_length: Пароль має бути не менше 32 символів. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: Електронна пошта + text: Вам знадобиться ця електронна адреса для входу. + msg: + empty: Поле електронної пошти не може бути пустим. + incorrect: Невірний формат електронної пошти. + ready_title: Ваш сайт готовий + ready_desc: >- + Якщо ви коли-небудь захочете змінити інші налаштування, відвідайте <1>розділ адміністрування; знайдіть його в меню сайту. + good_luck: "Веселіться, і хай щастить!" + warn_title: Попередження + warn_desc: >- + Файл <1>config.yaml вже існує. Якщо вам потрібно скинути будь-який з елементів конфігурації в цьому файлі, будь ласка, спочатку видаліть його. + install_now: Ви можете спробувати <1>встановити зараз. + installed: Уже встановлено + installed_desc: >- + Ви, здається, уже встановили. Щоб перевстановити, спочатку очистіть старі таблиці бази даних. + db_failed: Не вдалося встановити з'єднання з базою даних + db_failed_desc: >- + Це означає, що інформація про базу даних у вашому файлі <1>config.yaml невірна або що не вдалося встановити контакт із сервером бази даних. Це може означати, що сервер бази даних вашого хоста не працює. + counts: + views: перегляди + votes: голоси + answers: відповіді + accepted: Схвалено + page_error: + http_error: Помилка HTTP {{ code }} + desc_403: Ви не маєте дозволу на доступ до цієї сторінки. + desc_404: На жаль, такої сторінки не існує. + desc_50X: Сервер виявив помилку і не зміг виконати ваш запит. + back_home: Повернутися на головну сторінку + page_maintenance: + desc: "Ми технічно обслуговуємось, ми скоро повернемося." + nav_menus: + dashboard: Панель + contents: Зміст + questions: Питання + answers: Відповіді + users: Користувачі + badges: Значки + flags: Відмітки + settings: Налаштування + general: Основне + interface: Інтерфейс + smtp: SMTP + branding: Брендинг + legal: Правила та умови + write: Написати + terms: Terms + tos: Умови використання + privacy: Приватність + seo: SEO + customize: Персоналізувати + themes: Теми + login: Вхід + privileges: Привілеї + plugins: Плагіни + installed_plugins: Встановлені плагіни + apperance: Appearance + website_welcome: Ласкаво просимо до {{site_name}} + user_center: + login: Вхід + qrcode_login_tip: Будь ласка, використовуйте {{ agentName }}, щоб просканувати QR-код і увійти в систему. + login_failed_email_tip: Не вдалося увійти, будь ласка, дозвольте цьому додатку отримати доступ до вашої електронної пошти, перш ніж спробувати ще раз. + badges: + modal: + title: Вітаємо + content: Ти отримав новий значок. + close: Закрити + confirm: Переглянути значки + title: Значки + awarded: Присвоєно + earned_×: Зароблено ×{{ number }} + ×_awarded: "Присвоєно {{ number }}" + can_earn_multiple: Ви можете заробити це багато разів. + earned: Зароблено + admin: + admin_header: + title: Адмін + dashboard: + title: Панель + welcome: Ласкаво просимо до адміністратора! + site_statistics: Статистика сайту + questions: "Запитання:" + resolved: "Вирішено:" + unanswered: "Без відповідей:" + answers: "Відповіді:" + comments: "Коментарі:" + votes: "Голоси:" + users: "Користувачі:" + flags: "Відмітки:" + reviews: "Відгуки:" + site_health: Стан сайту + version: "Версія:" + https: "HTTPS:" + upload_folder: "Завантажити теку:" + run_mode: "Активний режим:" + private: Приватний + public: Публічний + smtp: "SMTP:" + timezone: "Часовий пояс:" + system_info: Інформація про систему + go_version: "Перейти до версії:" + database: "База даних:" + database_size: "Розмір бази даних:" + storage_used: "Використаний обсяг пам’яті:" + uptime: "Час роботи:" + links: Посилання + plugins: Плаґіни + github: GitHub + blog: Блоґ + contact: Контакт + forum: Форум + documents: Документи + feedback: Відгук + support: Підтримка + review: Огляд + config: Конфігурація + update_to: Оновити до + latest: Останній + check_failed: Не вдалося перевірити + "yes": "Так" + "no": "Ні" + not_allowed: Не дозволено + allowed: Дозволено + enabled: Увімкнено + disabled: Вимкнено + writable: Записуваний + not_writable: Не можна записувати + flags: + title: Відмітки + pending: В очікуванні + completed: Завершено + flagged: Відмічено + flagged_type: Відмічено {{ type }} + created: Створені + action: Дія + review: Огляд + user_role_modal: + title: Змінити роль користувача на... + btn_cancel: Скасувати + btn_submit: Надіслати + new_password_modal: + title: Встановити новий пароль + form: + fields: + password: + label: Пароль + text: Користувача буде виведено з системи, і йому потрібно буде увійти знову. + msg: Пароль повинен мати довжину від 8 до 32 символів. + btn_cancel: Скасувати + btn_submit: Надіслати + edit_profile_modal: + title: Редагувати профіль + form: + fields: + display_name: + label: Зображуване ім'я + msg_range: Display name must be 2-30 characters in length. + username: + label: Ім'я користувача + msg_range: Username must be 2-30 characters in length. + email: + label: Електронна пошта + msg_invalid: Невірна адреса електронної пошти. + edit_success: Успішно відредаговано + btn_cancel: Скасувати + btn_submit: Надіслати + user_modal: + title: Додати нового користувача + form: + fields: + users: + label: Масове додавання користувача + placeholder: "Джон Сміт, john@example.com, BUSYopr2\nАліса, alice@example.com, fpDntV8q" + text: '“Ім''я, електронну пошту, пароль” розділити комами. Один користувач у рядку.' + msg: "Будь ласка, введіть електронну пошту користувача, по одній на рядок." + display_name: + label: Ім'я для відображення + msg: Ім'я для показу повинно мати довжину від 2 до 30 символів. + email: + label: Електронна пошта + msg: Електронна пошта недійсна. + password: + label: Пароль + msg: Пароль повинен мати довжину від 8 до 32 символів. + btn_cancel: Скасувати + btn_submit: Надіслати + users: + title: Користувачі + name: Ім’я + email: Електронна пошта + reputation: Репутація + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Статус + role: Роль + action: Дія + change: Зміна + all: Усі + staff: Персонал + more: Більше + inactive: Неактивні + suspended: Призупинено + deleted: Видалено + normal: Нормальний + Moderator: Модератор + Admin: Адмін + User: Користувач + filter: + placeholder: "Фільтр на ім'я, користувач:id" + set_new_password: Встановити новий пароль + edit_profile: Редагувати профіль + change_status: Змінити статус + change_role: Змінити роль + show_logs: Показати записи журналу + add_user: Додати користувача + deactivate_user: + title: Деактивувати користувача + content: Неактивний користувач повинен повторно підтвердити свою електронну адресу. + delete_user: + title: Видалити цього користувача + content: Ви впевнені, що хочете видалити цього користувача? Це назавжди! + remove: Вилучити їх вміст + label: Видалити всі запитання, відповіді, коментарі тощо. + text: Не позначайте цю опцію, якщо ви хочете лише видалити обліковий запис користувача. + suspend_user: + title: Призупинити цього користувача + content: Призупинений користувач не може увійти в систему. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Запитання + unlisted: Вилучене зі списку + post: Опублікувати + votes: Голоси + answers: Відповіді + created: Створені + status: Статус + action: Дія + change: Зміна + pending: Очікування + filter: + placeholder: "Фільтр за назвою, питання:id" + answers: + page_title: Відповіді + post: Допис + votes: Голоси + created: Створено + status: Статус + action: Дія + change: Зміна + filter: + placeholder: "Фільтр за назвою, відповідь:id" + general: + page_title: Основне + name: + label: Назва сайту + msg: Назва сайту не може бути порожньою. + text: "Назва цього сайту як зазначено у заголовку тегу." + site_url: + label: URL сайту + msg: Url сайту не може бути порожньою. + validate: Будь ласка, введіть дійсну URL. + text: Адреса вашого сайту. + short_desc: + label: Короткий опис сайту + msg: Короткий опис сайту не може бути пустим. + text: "Короткий опис, як використовується в заголовку на головній сторінці." + desc: + label: Опис сайту + msg: Опис сайту не може бути порожнім. + text: "Опишіть цей сайт одним реченням, як у тезі метаопису." + contact_email: + label: Контактна електронна пошта + msg: Контактна електронна пошта не може бути порожньою. + validate: Контактна електронна пошта недійсна. + text: Адреса електронної пошти ключової особи, відповідальної за цей сайт. + check_update: + label: Оновлення програмного забезпечення + text: Автоматично перевіряти оновлення + interface: + page_title: Інтерфейс + language: + label: Мова інтерфейсу + msg: Мова інтерфейсу не може бути пустою. + text: Мова інтерфейсу користувача. Зміниться, коли ви оновите сторінку. + time_zone: + label: Часовий пояс + msg: Часовий пояс не може бути пустим. + text: Виберіть місто в тому ж часовому поясі, що й ви. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: З електронної пошти + msg: Поле з електронної пошти не може бути пустим. + text: Адреса електронної пошти, з якої надсилаються листи. + from_name: + label: Від імені + msg: Поле від імені не може бути пустим. + text: Ім'я, з якого надсилаються електронні листи. + smtp_host: + label: SMTP-хост + msg: SMTP хост не може бути порожнім. + text: Ваш поштовий сервер. + encryption: + label: Шифрування + msg: Поле шифрування не може бути пустим. + text: Для більшості серверів SSL є рекомендованим параметром. + ssl: SSL + tls: TLS + none: Нічого + smtp_port: + label: SMTP порт + msg: SMTP порт має бути числом 1 ~ 65535. + text: Порт на ваш поштовий сервер. + smtp_username: + label: Ім'я користувача SMTP + msg: Ім'я користувача SMTP не може бути порожнім. + smtp_password: + label: Пароль SMTP + msg: Пароль до SMTP не може бути порожнім. + test_email_recipient: + label: Тест отримувачів електронної пошти + text: Вкажіть адресу електронної пошти, на яку будуть надходити тестові надсилання. + msg: Тест отримувачів електронної пошти не вірний + smtp_authentication: + label: Увімкнути автентифікацію + title: SMTP аутентифікація + msg: SMTP аутентифікація не може бути порожньою. + "yes": "Так" + "no": "Ні" + branding: + page_title: Брендинг + logo: + label: Логотип + msg: Логотип не може бути порожнім. + text: Зображення логотипу у верхньому лівому кутку вашого сайту. Використовуйте широке прямокутне зображення з висотою 56 і співвідношенням сторін більше 3:1. Якщо залишити це поле порожнім, буде показано текст заголовка сайту. + mobile_logo: + label: Мобільний логотип + text: Логотип, що використовується на мобільній версії вашого сайту. Використовуйте широке прямокутне зображення висотою 56. Якщо залишити поле порожнім, буде використано зображення з налаштування "логотип". + square_icon: + label: Квадратна іконка + msg: Квадратна іконка не може бути пустою. + text: Зображення, що використовується як основа для іконок метаданих. В ідеалі має бути більшим за 512x512. + favicon: + label: Favicon + text: Іконка для вашого сайту. Для коректної роботи через CDN має бути у форматі png. Буде змінено розмір до 32x32. Якщо залишити порожнім, буде використовуватися "квадратна іконка". + legal: + page_title: Правила та умови + terms_of_service: + label: Умови використання + text: "Ви можете додати вміст про умови використання тут. Якщо у вас уже є документ, розміщений деінде, надайте тут повну URL-адресу." + privacy_policy: + label: Політика конфіденційности + text: "Ви можете додати вміст політики конфіденційності тут. Якщо у вас уже є документ, розміщений деінде, надайте тут повну URL-адресу." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Написати + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Відповідь на запис + label: Кожен користувач може написати лише одну відповідь на кожне запитання + text: "Вимкнути, щоб дозволити користувачам писати кілька відповідей на одне і те ж питання, що може призвести до розфокусування відповідей." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Рекомендовані теги + text: "За замовчуванням рекомендовані теги будуть показані у спадному списку." + msg: + contain_reserved: "рекомендовані теги не можуть містити зарезервовані теги" + required_tag: + title: Встановіть необхідні теги + label: Встановіть “Рекомендовані теги” як необхідні теги + text: "Кожне нове питання повинно мати принаймні один рекомендований тег." + reserved_tags: + label: Зарезервовані теги + text: "Зарезервовані теги можуть використовуватися лише модератором." + image_size: + label: Максимальний розмір зображення (МБ) + text: "Максимальний розмір вивантаженого зображення." + attachment_size: + label: Максимальний розмір вкладення (МБ) + text: "Максимальний розмір вкладених файлів для вивантаження." + image_megapixels: + label: Максимальна кількість мегапікселів зображення + text: "Максимальна кількість мегапікселів, дозволена для зображення." + image_extensions: + label: Дозволені розширення зображень + text: "Список розширень файлів, дозволених для показу зображень, через кому." + attachment_extensions: + label: Авторизовані розширення вкладень + text: "Список дозволених для вивантаження розширень файлів, розділених комами. ПОПЕРЕДЖЕННЯ: Дозвіл на вивантаження може спричинити проблеми з безпекою." + seo: + page_title: SEO + permalink: + label: Постійне посилання + text: Користувацькі структури URL можуть покращити уміння та сумісність з надсиланням посилань. + robots: + label: robots.txt + text: Це назавжди замінить будь-які відповідні налаштування сайту. + themes: + page_title: Теми + themes: + label: Теми + text: Виберіть наявну тему. + color_scheme: + label: Схема кольорів + navbar_style: + label: Navbar background style + primary_color: + label: Основний колір + text: Змінюйте кольори, що використовуються у ваших темах + css_and_html: + page_title: CSS та HTML + custom_css: + label: Користувацький CSS + text: > + + head: + label: Головний + text: > + + header: + label: Заголовок + text: > + + footer: + label: Низ + text: Це вставить перед </body>. + sidebar: + label: Бічна панель + text: Це буде вставлено в бічну панель. + login: + page_title: Увійти + membership: + title: Членство + label: Дозволити нові реєстрації + text: Вимкнути, щоб ніхто не міг створити новий обліковий запис. + email_registration: + title: Реєстрація за електронною поштою + label: Дозволити реєстрацію за електронною поштою + text: Вимкніть, щоб запобігти створенню нових облікових записів через електронну пошту. + allowed_email_domains: + title: Дозволені домени електронної пошти + text: Домени електронної пошти, на які користувачі повинні зареєструвати облікові записи. Один домен у рядку. Ігнорується, якщо порожній. + private: + title: Приватний + label: Вхід обов'язковий + text: Доступ до цієї спільноти мають лише зареєстровані користувачі. + password_login: + title: Вхід через пароль + label: Дозволити вхід через електронну пошту і пароль + text: "ПОПЕРЕДЖЕННЯ: Якщо вимкнути, ви не зможете увійти в систему, якщо раніше не налаштували інший метод входу." + installed_plugins: + title: Встановлені плагіни + plugin_link: Плагіни розширюють і поглиблюють функціональність. Ви можете знайти плагіни у <1>Сховищі плагінів. + filter: + all: Усі + active: Активні + inactive: Неактивні + outdated: Застарілі + plugins: + label: Плагіни + text: Виберіть наявний плагін. + name: Ім’я + version: Версія + status: Статус + action: Дія + deactivate: Деактивувати + activate: Активувати + settings: Налаштування + settings_users: + title: Користувачі + avatar: + label: Аватар за замовчуванням + text: Для користувачів без аватара власного. + gravatar_base_url: + label: Основна URL Gravatar + text: URL бази API постачальника Gravatar. Ігнорується, якщо порожній. + profile_editable: + title: Профіль можна редагувати + allow_update_display_name: + label: Дозволити користувачам змінювати ім'я для відображення + allow_update_username: + label: Дозволити користувачам змінювати своє ім'я користувача + allow_update_avatar: + label: Дозволити користувачам змінювати зображення свого профілю + allow_update_bio: + label: Дозволити користувачам змінювати дані про себе + allow_update_website: + label: Дозволити користувачам змінювати свій вебсайт + allow_update_location: + label: Дозволити користувачам змінювати своє місцеперебування + privilege: + title: Привілеї + level: + label: Рівень репутації необхідний + text: Виберіть репутацію, необхідну для привілеїв + msg: + should_be_number: введення має бути числом + number_larger_1: число має бути рівним або більшим за 1 + badges: + action: Дія + active: Активні + activate: Активувати + all: Усі + awards: Нагороди + deactivate: Деактивувати + filter: + placeholder: Фільтрувати за іменем, значок:id + group: Група + inactive: Неактивні + name: Ім’я + show_logs: Показати записи журналу + status: Статус + title: Значки + form: + optional: (необов'язково) + empty: не може бути порожнім + invalid: недійсне + btn_submit: Зберегти + not_found_props: "Необхідний параметр {{ key }} не знайдено." + select: Вибрати + page_review: + review: Огляд + proposed: запропоновано + question_edit: Редагування питання + answer_edit: Редагування відповіді + tag_edit: Редагування тегу + edit_summary: Редагувати звіт + edit_question: Редагувати питання + edit_answer: Редагувати відповідь + edit_tag: Редагувати тег + empty: Не залишилось завдань огляду. + approve_revision_tip: Ви схвалюєте цю редакцію? + approve_flag_tip: Ви схвалюєте цю відмітку? + approve_post_tip: Ви схвалюєте цей допис? + approve_user_tip: Ви схвалюєте цього користувача? + suggest_edits: Запропоновані зміни + flag_post: Відмітити публікацію + flag_user: Відмітити користувача + queued_post: Черговий допис + queued_user: Черговий користувач + filter_label: Тип + reputation: репутація + flag_post_type: Відмічено цей пост як {{ type }}. + flag_user_type: Відмічено цього користувача як {{ type }}. + edit_post: Редагувати допис + list_post: Додати допис до списку + unlist_post: Видалити допис зі списку + timeline: + undeleted: не видалений + deleted: видалений + downvote: голос "проти" + upvote: голос "за" + accept: прийняти + cancelled: скасовано + commented: прокоментовано + rollback: відкат назад + edited: відредаговано + answered: дано відповідь + asked: запитано + closed: закрито + reopened: знову відкрито + created: створено + pin: закріплено + unpin: відкріплено + show: додано до списку + hide: не внесено до списку + title: "Історія для" + tag_title: "Хронологія для" + show_votes: "Показати голоси" + n_or_a: Н/Д + title_for_question: "Хронологія для" + title_for_answer: "Часова шкала для відповіді на {{ title }} від {{ author }}" + title_for_tag: "Часова шкала для тега" + datetime: Дата й час + type: Тип + by: Від + comment: Коментар + no_data: "Ми не змогли нічого знайти." + users: + title: Користувачі + users_with_the_most_reputation: Користувачі з найвищою репутацією на цьому тижні + users_with_the_most_vote: Користувачі, які голосували за найбільше цього тижня + staffs: Персонал нашої спільноти + reputation: репутація + votes: голоси + prompt: + leave_page: Ви дійсно хочете покинути сторінку? + changes_not_save: Ваші зміни можуть не зберегтися. + draft: + discard_confirm: Ви дійсно бажаєте скасувати чернетку? + messages: + post_deleted: Цей допис було видалено. + post_cancel_deleted: Цей допис було не видалено. + post_pin: Цей допис було закріплено. + post_unpin: Цей допис було відкріплено. + post_hide_list: Цей допис було приховано зі списку. + post_show_list: Цей допис було показано у списку. + post_reopen: Цей допис було знову відкрито. + post_list: Цей допис було додано до списку. + post_unlist: Цей допис було приховано. + post_pending: Ваш допис очікує на розгляд. Це попередній перегляд, його буде видно після того, як його буде схвалено. + post_closed: Ця публікація була закрита. + answer_deleted: Ця відповідь була видалена. + answer_cancel_deleted: Ця відповідь була не видалена. + change_user_role: Роль цього користувача було змінено. + user_inactive: Цей користувач вже неактивний. + user_normal: Цей користувач вже нормальний. + user_suspended: Цього користувача було відсторонено. + user_deleted: Цього користувача було видалено. + badge_activated: Цей бейдж було активовано. + badge_inactivated: Цей бейдж було деактивовано. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/vi_VN.yaml b/data/i18n/vi_VN.yaml new file mode 100644 index 000000000..d379c4930 --- /dev/null +++ b/data/i18n/vi_VN.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: Thành công. + unknown: + other: Lỗi không xác định. + request_format_error: + other: Định dạng yêu cầu không hợp lệ. + unauthorized_error: + other: Chưa được cấp quyền. + database_error: + other: Lỗi dữ liệu máy chủ. + forbidden_error: + other: Bị cấm. + duplicate_request_error: + other: Trùng lặp yêu cầu. + action: + report: + other: Gắn nhãn + edit: + other: Chỉnh sửa + delete: + other: Xóa + close: + other: Đóng + reopen: + other: Mở lại + forbidden_error: + other: Bị cấm. + pin: + other: Ghim + hide: + other: Gỡ bỏ khỏi danh sách + unpin: + other: Bỏ ghim + show: + other: Hiển thị + invite_someone_to_answer: + other: Chỉnh sửa + undelete: + other: Khôi phục + merge: + other: Merge + role: + name: + user: + other: Người dùng + admin: + other: Quản trị viên + moderator: + other: Người điều hành + description: + user: + other: Mặc định không có quyền truy cập đặc biệt. + admin: + other: Có toàn quyền truy cập vào trang. + moderator: + other: Có quyền truy cập vào tất cả bài viết trừ cài đặt quản trị. + privilege: + level_1: + description: + other: Cấp độ 1 (yêu cầu danh tiếng thấp cho nhóm riêng, nhóm) + level_2: + description: + other: Cấp độ 2 (yêu cầu danh tiếng cao cho cộng đồng đã phát triển) + level_3: + description: + other: Cấp độ 3 (yêu cầu danh tiếng cao cho cộng đồng đã phát triển) + level_custom: + description: + other: Cấp độ tùy chỉnh + rank_question_add_label: + other: Đặt câu hỏi + rank_answer_add_label: + other: Viết câu trả lời + rank_comment_add_label: + other: Viết bình luận + rank_report_add_label: + other: Gắn Cờ + rank_comment_vote_up_label: + other: Bình chọn lên cho bình luận + rank_link_url_limit_label: + other: Đăng nhiều hơn 2 liên kết cùng một lúc + rank_question_vote_up_label: + other: Bình chọn lên cho câu hỏi + rank_answer_vote_up_label: + other: Bình chọn lên cho câu trả lời + rank_question_vote_down_label: + other: Bình chọn xuống cho câu hỏi + rank_answer_vote_down_label: + other: Bình chọn xuống cho câu trả lời + rank_invite_someone_to_answer_label: + other: Mời ai đó trả lời + rank_tag_add_label: + other: Tạo thẻ mới + rank_tag_edit_label: + other: Chỉnh sửa mô tả thẻ (cần xem xét) + rank_question_edit_label: + other: Chỉnh sửa câu hỏi của người khác (cần xem xét) + rank_answer_edit_label: + other: Chỉnh sửa câu trả lời của người khác (cần xem xét) + rank_question_edit_without_review_label: + other: Chỉnh sửa câu hỏi của người khác không cần xem xét + rank_answer_edit_without_review_label: + other: Chỉnh sửa câu trả lời của người khác không cần xem xét + rank_question_audit_label: + other: Xem xét chỉnh sửa câu hỏi + rank_answer_audit_label: + other: Xem xét chỉnh sửa câu trả lời + rank_tag_audit_label: + other: Xem xét chỉnh sửa thẻ + rank_tag_edit_without_review_label: + other: Chỉnh sửa mô tả thẻ không cần xem xét + rank_tag_synonym_label: + other: Quản lý từ đồng nghĩa của thẻ + email: + other: Email + e_mail: + other: Email + password: + other: Mật khẩu + pass: + other: Mật khẩu + old_pass: + other: Current password + original_text: + other: Bài viết này + email_or_password_wrong_error: + other: Email và mật khẩu không trùng khớp. + error: + common: + invalid_url: + other: URL không tồn tại. + status_invalid: + other: Trạng thái không hợp lệ + password: + space_invalid: + other: Mật khẩu không thể tồn tại khoảng trắng. + admin: + cannot_update_their_password: + other: Bạn không thể thay đổi mật khẩu. + cannot_edit_their_profile: + other: Bạn không thể thay đổi hồ sơ. + cannot_modify_self_status: + other: Bạn không thể thay đổi trạng thái của mình. + email_or_password_wrong: + other: Email và mật khẩu không khớp. + answer: + not_found: + other: Không tìm thấy câu trả lời. + cannot_deleted: + other: Không có quyền xóa. + cannot_update: + other: Không có quyền cập nhật. + question_closed_cannot_add: + other: Câu hỏi đã đóng và không thể thêm. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: Không được phép chỉnh sửa bình luận. + not_found: + other: Không tìm thấy bình luận. + cannot_edit_after_deadline: + other: Thời gian bình luận đã quá lâu để chỉnh sửa. + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: Email đã được dùng. + need_to_be_verified: + other: Email cần được xác minh. + verify_url_expired: + other: URL xác minh email đã hết hạn, vui lòng gửi lại email. + illegal_email_domain_error: + other: Email không được phép từ miền email đó. Vui lòng sử dụng miền khác. + lang: + not_found: + other: Không tìm thấy file ngôn ngữ. + object: + captcha_verification_failed: + other: Xác minh Captcha thất bại. + disallow_follow: + other: Bạn không được phép theo dõi. + disallow_vote: + other: Bạn không được phép bỏ phiếu. + disallow_vote_your_self: + other: Bạn không thể bỏ phiếu cho bài đăng của chính mình. + not_found: + other: Đối tượng không tìm thấy. + verification_failed: + other: Xác thực không thành công. + email_or_password_incorrect: + other: Email và mật khẩu không trùng khớp. + old_password_verification_failed: + other: Xác minh mật khẩu cũ thất bại. + new_password_same_as_previous_setting: + other: Mật khẩu mới giống như cài đặt trước. + already_deleted: + other: Mật khẩu mới giống như cài đặt trước. + meta: + object_not_found: + other: Đối tượng không tìm thấy + question: + already_deleted: + other: Bài đăng này đã bị xóa. + under_review: + other: Bài đăng của bạn đang chờ xem xét. Nó sẽ hiển thị sau khi được phê duyệt. + not_found: + other: Không tìm thấy câu hỏi. + cannot_deleted: + other: Không có quyền xóa. + cannot_close: + other: Không có quyền đóng. + cannot_update: + other: Không có quyền cập nhật. + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Xếp hạng danh tiếng không đạt được điều kiện. + vote_fail_to_meet_the_condition: + other: Cảm ơn phản hồi của bạn. Bạn cần ít nhất {{.Rank}} danh tiếng để bỏ phiếu. + no_enough_rank_to_operate: + other: Bạn cần ít nhất {{.Rank}} danh tiếng để làm điều này. + report: + handle_failed: + other: Xử lý báo cáo thất bại. + not_found: + other: Không tìm thấy báo cáo. + tag: + already_exist: + other: Thẻ đã tồn tại. + not_found: + other: Không tìm thấy thẻ. + recommend_tag_not_found: + other: Thẻ đề xuất không tồn tại. + recommend_tag_enter: + other: Vui lòng nhập ít nhất một thẻ bắt buộc. + not_contain_synonym_tags: + other: Không nên chứa các thẻ đồng nghĩa. + cannot_update: + other: Không có quyền cập nhật. + is_used_cannot_delete: + other: Bạn không thể xóa thẻ đang được sử dụng. + cannot_set_synonym_as_itself: + other: Bạn không thể đặt từ đồng nghĩa của thẻ hiện tại là chính nó. + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: Tên người gửi không thể là địa chỉ email. + theme: + not_found: + other: Chủ đề không tìm thấy. + revision: + review_underway: + other: Không thể chỉnh sửa hiện tại, có một phiên bản đang trong hàng đợi xem xét. + no_permission: + other: Không có quyền sửa đổi. + user: + external_login_missing_user_id: + other: Nền tảng bên thứ ba không cung cấp UserID duy nhất, vì vậy bạn không thể đăng nhập, vui lòng liên hệ với quản trị viên trang web. + external_login_unbinding_forbidden: + other: Vui lòng đặt mật khẩu đăng nhập cho tài khoản của bạn trước khi bạn gỡ bỏ đăng nhập này. + email_or_password_wrong: + other: + other: Email và mật khẩu không khớp. + not_found: + other: Không tìm thấy người dùng. + suspended: + other: Người dùng đã bị đình chỉ. + username_invalid: + other: Tên người dùng không hợp lệ. + username_duplicate: + other: Tên người dùng đã được sử dụng. + set_avatar: + other: Thiết lập hình đại diện thất bại. + cannot_update_your_role: + other: Bạn không thể sửa đổi vai trò của mình. + not_allowed_registration: + other: Hiện tại trang không mở đăng ký. + not_allowed_login_via_password: + other: Hiện tại trang không cho phép đăng nhập qua mật khẩu. + access_denied: + other: Truy cập bị từ chối + page_access_denied: + other: Bạn không có quyền truy cập trang này. + add_bulk_users_format_error: + other: "Lỗi định dạng {{.Field}} gần '{{.Content}}' tại dòng {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "Số lượng người dùng bạn thêm cùng một lúc nên nằm trong khoảng từ 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: Đọc cấu hình thất bại + database: + connection_failed: + other: Kết nối cơ sở dữ liệu thất bại + create_table_failed: + other: Tạo bảng thất bại + install: + create_config_failed: + other: Không thể tạo file config.yaml. + upload: + unsupported_file_format: + other: Định dạng tệp không được hỗ trợ. + site_info: + config_not_found: + other: Không tìm thấy cấu hình trang. + badge: + object_not_found: + other: Đối tượng không tìm thấy + reason: + spam: + name: + other: thư rác + desc: + other: Bài đăng này quảng cáo hoặc phá hoại. Nó không hữu ích hoặc liên quan đến chủ đề hiện tại. + rude_or_abusive: + name: + other: thô lỗ hoặc lạm dụng + desc: + other: "Một người hợp lý sẽ thấy nội dung này không phù hợp để diễn thuyết một cách tôn trọng." + a_duplicate: + name: + other: một bản sao + desc: + other: Câu hỏi này đã được hỏi trước đó, đã có câu trả lời. + placeholder: + other: Nhập liên kết câu hỏi hiện tại + not_a_answer: + name: + other: không phải câu trả lời + desc: + other: "Điều này đã được đăng dưới dạng câu trả lời nhưng nó không cố gắng trả lời câu hỏi. Nó có thể là một bản chỉnh sửa, một nhận xét, một câu hỏi khác hoặc bị xóa hoàn toàn." + no_longer_needed: + name: + other: không còn cần thiết + desc: + other: Bình luận này đã lỗi thời, đối thoại hoặc không liên quan đến bài đăng này. + something: + name: + other: điều gì đó khác + desc: + other: Bài đăng này cần sự chú ý của nhân viên vì một lý do khác không được liệt kê ở trên. + placeholder: + other: Hãy cho chúng tôi biết cụ thể điều gì bạn quan tâm + community_specific: + name: + other: một lý do cụ thể của cộng đồng + desc: + other: Câu hỏi này không đáp ứng hướng dẫn của cộng đồng. + not_clarity: + name: + other: cần chi tiết hoặc rõ ràng + desc: + other: Câu hỏi này hiện bao gồm nhiều câu hỏi trong một. Nó nên tập trung vào một vấn đề duy nhất. + looks_ok: + name: + other: trông ổn + desc: + other: Bài đăng này tốt như vậy và không kém chất lượng. + needs_edit: + name: + other: cần chỉnh sửa, và tôi đã làm điều đó + desc: + other: Cải thiện và sửa các vấn đề với bài đăng này bằng chính bạn. + needs_close: + name: + other: cần đóng + desc: + other: Một câu hỏi đã đóng không thể trả lời, nhưng vẫn có thể chỉnh sửa, bỏ phiếu và bình luận. + needs_delete: + name: + other: cần xóa + desc: + other: Bài đăng này sẽ bị xóa. + question: + close: + duplicate: + name: + other: spam + desc: + other: Câu hỏi này đã được hỏi trước đó và đã có câu trả lời. + guideline: + name: + other: một lý do cụ thể của cộng đồng + desc: + other: Câu hỏi này không đáp ứng hướng dẫn của cộng đồng. + multiple: + name: + other: cần chi tiết hoặc rõ ràng + desc: + other: Câu hỏi này hiện bao gồm nhiều câu hỏi trong một. Nó chỉ nên tập trung vào một vấn đề. + other: + name: + other: điều gì đó khác + desc: + other: Bài đăng này cần một lý do khác không được liệt kê ở trên. + operation_type: + asked: + other: đã hỏi + answered: + other: đã trả lời + modified: + other: đã chỉnh sửa + deleted_title: + other: Câu hỏi đã xóa + questions_title: + other: Các câu hỏi + tag: + tags_title: + other: Thẻ + no_description: + other: Thẻ không có mô tả. + notification: + action: + update_question: + other: câu hỏi đã cập nhật + answer_the_question: + other: đã trả lời câu hỏi + update_answer: + other: câu trả lời đã cập nhật + accept_answer: + other: câu trả lời đã chấp nhận + comment_question: + other: đã bình luận câu hỏi + comment_answer: + other: đã bình luận câu trả lời + reply_to_you: + other: đã trả lời bạn + mention_you: + other: đã nhắc đến bạn + your_question_is_closed: + other: Câu hỏi của bạn đã được đóng + your_question_was_deleted: + other: Câu hỏi của bạn đã bị xóa + your_answer_was_deleted: + other: Câu trả lời của bạn đã bị xóa + your_comment_was_deleted: + other: Bình luận của bạn đã bị xóa + up_voted_question: + other: câu hỏi đã bình chọn lên + down_voted_question: + other: câu hỏi đã bình chọn xuống + up_voted_answer: + other: câu trả lời đã bình chọn lên + down_voted_answer: + other: câu trả lời đã bình chọn xuống + up_voted_comment: + other: bình luận đã bình chọn lên + invited_you_to_answer: + other: đã mời bạn trả lời + earned_badge: + other: Bạn đã nhận được huy hiệu "{{.BadgeName}}" + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Xác nhận địa chỉ email mới của bạn" + body: + other: "Xác nhận địa chỉ email mới của bạn cho {{.SiteName}} bằng cách nhấp vào liên kết sau:
        \n{{.ChangeEmailUrl}}

        \n\nNếu bạn không yêu cầu thay đổi này, vui lòng bỏ qua email này.

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời tin nhắn này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} đã trả lời câu hỏi của bạn" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nXem trên {{.SiteName}}

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời thư này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn.

        \n\nHủy đăng ký" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} mời bạn trả lời" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Tôi nghĩ bạn có thể biết câu trả lời.

        \nXem trên {{.SiteName}}

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời thư này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn.

        \n\nHủy đăng ký" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} đã bình luận về bài đăng của bạn" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nXem trên {{.SiteName}}

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời thư này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn.

        \n\nHủy đăng ký" + new_question: + title: + other: "[{{.SiteName}}] Câu hỏi mới: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName}}] Đặt lại mật khẩu" + body: + other: "Ai đó đã yêu cầu đặt lại mật khẩu của bạn trên {{.SiteName}}.

        \n\nNếu người đó không phải là bạn thì bạn có thể yên tâm bỏ qua email này.

        \n\nNhấp vào liên kết sau để chọn mật khẩu mới:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời tin nhắn này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn." + register: + title: + other: "[{{.SiteName}}] Xác nhận tài khoản mới của bạn" + body: + other: "Chào mừng bạn đến với {{.SiteName}}!

        \n\nNhấp vào liên kết sau để xác nhận và kích hoạt tài khoản mới của bạn:
        \n{{.RegisterUrl}}

        \n\nNếu liên kết trên không nhấp vào được, hãy thử sao chép và dán nó vào thanh địa chỉ trình duyệt web của bạn.\n

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời tin nhắn này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn." + test: + title: + other: "[{{.SiteName}}] Email kiểm tra" + body: + other: "Đây là một email thử nghiệm.\n

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời tin nhắn này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn." + action_activity_type: + upvote: + other: bình chọn lên + upvoted: + other: đã bình chọn lên + downvote: + other: bình chọn xuống + downvoted: + other: đã bình chọn xuống + accept: + other: chấp nhận + accepted: + other: đã chấp nhận + edit: + other: chỉnh sửa + review: + queued_post: + other: Bài đăng trong hàng đợi + flagged_post: + other: Bài đăng được đánh dấu + suggested_post_edit: + other: Đề xuất chỉnh sửa + reaction: + tooltip: + other: "{{ .Names }} và {{ .Count }} thêm..." + badge: + default_badges: + autobiographer: + name: + other: Tác giả tự truyện + desc: + other: Đã điền thông tin hồ sơ. + certified: + name: + other: Đã xác minh + desc: + other: Hoàn thành hướng dẫn cho người dùng mới của chúng tôi. + editor: + name: + other: Trình chỉnh sửa + desc: + other: Chỉnh sửa bài đăng đầu tiên. + first_flag: + name: + other: Cờ đầu tiên + desc: + other: Lần đầu tiên báo cáo một bài viết. + first_upvote: + name: + other: Lượt thích đầu tiên + desc: + other: Lần đầu tiên báo cáo một bài viết. + first_link: + name: + other: Liên kết đầu tiên + desc: + other: First added a link to another post. + first_reaction: + name: + other: Phản ứng đầu tiên + desc: + other: Phản ứng với bài viết đầu tiên. + first_share: + name: + other: Chia sẻ đầu tiên + desc: + other: Lần đầu chia sẻ một bài viết. + scholar: + name: + other: Học giả + desc: + other: Đặt một câu hỏi và chấp nhận một câu trả lời. + commentator: + name: + other: Bình luận viên + desc: + other: Để lại 5 bình luận. + new_user_of_the_month: + name: + other: Người dùng mới của tháng + desc: + other: Đóng góp nổi bật trong tháng đầu tiên của họ. + read_guidelines: + name: + other: Đọc hướng dẫn + desc: + other: Đọc [nguyên tắc cộng đồng]. + reader: + name: + other: Người đọc + desc: + other: Đọc mọi câu trả lời trong một chủ đề có hơn 10 câu trả lời. + welcome: + name: + other: Xin chào + desc: + other: Đã nhận được phiếu tán thành. + nice_share: + name: + other: Chia sẻ hay + desc: + other: Đã chia sẻ một bài đăng với 25 khách truy cập. + good_share: + name: + other: Chia sẻ tốt + desc: + other: Đã chia sẻ một bài đăng với 300 khách truy cập. + great_share: + name: + other: Chia sẻ tuyệt vời + desc: + other: Đã chia sẻ một bài đăng với 1000 khách truy cập. + out_of_love: + name: + other: Hết yêu thích + desc: + other: Đã sử dụng 50 phiếu bầu trong một ngày. + higher_love: + name: + other: Thích cao hơn + desc: + other: Đã sử dụng 50 phiếu bầu trong một ngày. + crazy_in_love: + name: + other: Thích điên cuồng + desc: + other: Đã sử dụng 50 phiếu bầu trong một ngày 20 lần. + promoter: + name: + other: Người quảng bá + desc: + other: Đã mời một người dùng. + campaigner: + name: + other: Chiến dịch + desc: + other: Đã mời 3 người dùng cơ bản. + champion: + name: + other: Vô địch + desc: + other: Mời 5 thành viên. + thank_you: + name: + other: Cảm ơn bạn + desc: + other: Có 20 bài đăng được bình chọn đưa ra 10 phiếu bầu. + gives_back: + name: + other: Trả lại + desc: + other: Có 100 bài đăng được bình chọn và đưa ra 100 phiếu bầu. + empathetic: + name: + other: Đồng cảm + desc: + other: Có 500 bài đăng được bình chọn đưa ra 1000 phiếu bầu. + enthusiast: + name: + other: Người nhiệt thành + desc: + other: Đã truy cập 10 ngày liên tiếp. + aficionado: + name: + other: Người hâm mộ + desc: + other: Đã truy cập 100 ngày liên tiếp. + devotee: + name: + other: Tín đồ + desc: + other: Đã truy cập 365 ngày liên tiếp. + anniversary: + name: + other: Kỉ niệm + desc: + other: Thành viên tích cực trong một năm, đăng ít nhất một lần. + appreciated: + name: + other: Đánh giá cao + desc: + other: Nhận được 1 lượt bình chọn cho 20 bài viết. + respected: + name: + other: Tôn trọng + desc: + other: Nhận được 2 lượt bình chọn cho 100 bài viết. + admired: + name: + other: Ngưỡng mộ + desc: + other: Nhận được 5 lượt bình chọn trên 300 bài đăng. + solved: + name: + other: Đã giải quyết + desc: + other: Có một câu trả lời được chấp nhận. + guidance_counsellor: + name: + other: Cố vấn hướng dẫn + desc: + other: Có 10 câu trả lời được chấp nhận. + know_it_all: + name: + other: Biết tất cả + desc: + other: Có 50 câu trả lời được chấp nhận. + solution_institution: + name: + other: Viện giải pháp + desc: + other: Có 150 câu trả lời được chấp nhận. + nice_answer: + name: + other: Câu trả lời tốt + desc: + other: Điểm trả lời từ 10 trở lên. + good_answer: + name: + other: Câu trả lời của bạn + desc: + other: Điểm trả lời từ 25 trở lên. + great_answer: + name: + other: Câu trả lời tuyệt vời + desc: + other: Điểm trả lời từ 50 trở lên. + nice_question: + name: + other: Câu trả lời tốt + desc: + other: Điểm trả lời từ 10 trở lên. + good_question: + name: + other: Câu trả lời tốt + desc: + other: Điểm trả lời từ 25 trở lên. + great_question: + name: + other: Câu trả lời tốt + desc: + other: Điểm trả lời từ 50 trở lên. + popular_question: + name: + other: Câu hỏi phổ biến + desc: + other: Câu hỏi với 500 lượt xem. + notable_question: + name: + other: Câu hỏi đáng chú ý + desc: + other: Câu hỏi với 1.000 lượt xem. + famous_question: + name: + other: Câu hỏi nổi tiếng + desc: + other: Câu hỏi với 5.000 lượt xem. + popular_link: + name: + other: Liên kết phổ biến + desc: + other: Đã đăng một liên kết bên ngoài với 50 lần nhấp chuột. + hot_link: + name: + other: Liên kết nổi bật + desc: + other: Đã đăng một liên kết bên ngoài với 300 lần nhấp chuột. + famous_link: + name: + other: Liên kết nổi tiếng + desc: + other: Đã đăng một liên kết bên ngoài với 100 lần nhấp chuột. + default_badge_groups: + getting_started: + name: + other: Bắt đầu + community: + name: + other: Cộng đồng + posting: + name: + other: Viết bài thảo luận +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: Cách định dạng + desc: >- +
        • đề cập đến bài đăng: #post_id

        • để tạo liên kết

          <https://url.com>

          [Title](https://url.com)
        • đặt trả về giữa đoạn văn

        • _italic_ hoặc **in đậm**

        • mã thụt lề 4 dấu cách

        • trích dẫn bằng cách đặt > ở đầu dòng

        • backtick thoát `like _this_`

        • tạo hàng rào mã bằng dấu backticks `

          ```
          mã vào đây
          ```
        + pagination: + prev: Trước + next: Tiếp + page_title: + question: Câu hỏi + questions: Các câu hỏi + tag: Thẻ + tags: Các thẻ + tag_wiki: wiki thẻ + create_tag: Tạo thẻ + edit_tag: Chỉnh sửa thẻ + ask_a_question: Create Question + edit_question: Chỉnh sửa câu hỏi + edit_answer: Chỉnh sửa câu + search: Tìm kiếm + posts_containing: Bài đăng chứa + settings: Cài đặt + notifications: Các thông báo + login: Đăng nhập + sign_up: Đăng ký + account_recovery: Khôi phục tài khoản + account_activation: Kích hoạt tài khoản + confirm_email: Xác nhận Email + account_suspended: Tài khoản bị đình chỉ + admin: Quản trị + change_email: Thay đổi Email + install: Cài đặt Answer + upgrade: Nâng cấp Answer + maintenance: Bảo trì trang web + users: Người dùng + oauth_callback: Đang xử lý + http_404: Lỗi HTTP 404 + http_50X: Lỗi HTTP 500 + http_403: Lỗi HTTP 403 + logout: Đăng xuất + posts: Posts + notifications: + title: Các thông báo + inbox: Hộp thư đến + achievement: Thành tích + new_alerts: Cảnh báo mới + all_read: Đánh dấu tất cả đã đọc + show_more: Xem thêm + someone: Ai đó + inbox_type: + all: Tất cả + posts: Bài đăng + invites: Lời mời + votes: Bình chọn + answer: Câu trả lời + question: Câu hỏi + badge_award: Huy hiệu + suspended: + title: Tài khoản của bạn đã bị đình chỉ + until_time: "Tài khoản của bạn đã bị đình chỉ cho đến {{ time }}." + forever: Người dùng này đã bị đình chỉ vĩnh viễn. + end: Bạn không tuân thủ hướng dẫn cộng đồng. + contact_us: Liên hệ với chúng tôi + editor: + blockquote: + text: Trích dẫn + bold: + text: Đậm + chart: + text: Biểu đồ + flow_chart: Biểu đồ luồng + sequence_diagram: Sơ đồ trình tự + class_diagram: Sơ đồ lớp + state_diagram: Sơ đồ trạng thái + entity_relationship_diagram: Sơ đồ quan hệ thực thể + user_defined_diagram: Sơ đồ do người dùng định nghĩa + gantt_chart: Biểu đồ Gantt + pie_chart: Biểu đồ tròn + code: + text: Mẫu code + add_code: Thêm code mẫu + form: + fields: + code: + label: Mã + msg: + empty: Mã không thể trống. + language: + label: Ngôn ngữ + placeholder: Phát hiện tự động + btn_cancel: Hủy + btn_confirm: Thêm + formula: + text: Công thức + options: + inline: Công thức nội dòng + block: Công thức khối + heading: + text: Tiêu đề + options: + h1: Tiêu đề 1 + h2: Tiêu đề 2 + h3: Tiêu đề 3 + h4: Tiêu đề 4 + h5: Tiêu đề 5 + h6: Tiêu đề 6 + help: + text: Trợ giúp + hr: + text: Thước ngang + image: + text: Hình ảnh + add_image: Thêm hình ảnh + tab_image: Tải Ảnh lên + form_image: + fields: + file: + label: Tệp hình ảnh + btn: Chọn hình ảnh + msg: + empty: Tệp không thể trống. + only_image: Chỉ cho phép tệp hình ảnh. + max_size: Kích thước tệp không được vượt quá {{size}} MB. + desc: + label: Mô tả + tab_url: URL hình ảnh + form_url: + fields: + url: + label: URL hình ảnh + msg: + empty: URL hình ảnh không thể trống. + name: + label: Mô tả + btn_cancel: Hủy + btn_confirm: Thêm + uploading: Đang tải lên + indent: + text: Canh lề + outdent: + text: Lùi lề + italic: + text: Nhấn mạnh + link: + text: Liên kết + add_link: Thêm liên kết + form: + fields: + url: + label: Đường link url + msg: + empty: URL không thể trống. + name: + label: Mô tả + btn_cancel: Hủy + btn_confirm: Thêm + ordered_list: + text: Danh sách đánh số + unordered_list: + text: Danh sách gạch đầu dòng + table: + text: Bảng + heading: Tiêu đề + cell: Ô + file: + text: Đính kèm tập tin + not_supported: "Không hỗ trợ loại tệp đó. Hãy thử lại với {{file_type}}." + max_size: "Kích thước tệp đính kèm không được vượt quá {{size}} MB." + close_modal: + title: Tôi đang đóng bài đăng này với lý do... + btn_cancel: Hủy + btn_submit: Gửi + remark: + empty: Không thể trống. + msg: + empty: Vui lòng chọn một lý do. + report_modal: + flag_title: Tôi đang đánh dấu để báo cáo bài đăng này với lý do... + close_title: Tôi đang đóng bài đăng này với lý do... + review_question_title: Xem xét câu hỏi + review_answer_title: Xem xét câu trả lời + review_comment_title: Xem xét bình luận + btn_cancel: Hủy + btn_submit: Gửi + remark: + empty: Không thể trống. + msg: + empty: Vui lòng chọn một lý do. + not_a_url: Định dạng URL không chính xác. + url_not_match: Nguồn gốc URL không khớp với trang web hiện tại. + tag_modal: + title: Tạo thẻ mới + form: + fields: + display_name: + label: Tên hiển thị + msg: + empty: Tên hiển thị không thể trống. + range: Tên hiển thị tối đa 35 ký tự. + slug_name: + label: Đường dẫn URL + desc: Đường dẫn tối đa 35 ký tự. + msg: + empty: Đường dẫn URL không thể trống. + range: Đường dẫn URL tối đa 35 ký tự. + character: Đường dẫn URL chứa bộ ký tự không được phép. + desc: + label: Mô tả + revision: + label: Sửa đổi + edit_summary: + label: Tóm tắt chỉnh sửa + placeholder: >- + Giải thích ngắn gọn các thay đổi của bạn (sửa chính tả, sửa ngữ pháp, cải thiện định dạng) + btn_cancel: Hủy + btn_submit: Gửi + btn_post: Đăng thẻ mới + tag_info: + created_at: Đã tạo + edited_at: Đã chỉnh sửa + history: Lịch sử + synonyms: + title: Từ đồng nghĩa + text: Các thẻ sau sẽ được ánh xạ lại thành + empty: Không tìm thấy từ đồng nghĩa. + btn_add: Thêm từ đồng nghĩa + btn_edit: Chỉnh sửa + btn_save: Lưu + synonyms_text: Các thẻ sau sẽ được ánh xạ lại thành + delete: + title: Xóa thẻ này + tip_with_posts: >- +

        Chúng tôi không cho phép xóa thẻ có bài đăng.

        Vui lòng xóa thẻ này khỏi các bài đăng trước.

        + tip_with_synonyms: >- +

        Chúng tôi không cho phép xóa thẻ có từ đồng nghĩa.

        Vui lòng xóa các từ đồng nghĩa khỏi thẻ này trước.

        + tip: Bạn có chắc chắn muốn xóa không? + close: Đóng + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: Submit + btn_close: Close + edit_tag: + title: Chỉnh sửa Thẻ + default_reason: Chỉnh sửa thẻ + default_first_reason: Thêm thẻ + btn_save_edits: Lưu chỉnh sửa + btn_cancel: Hủy + dates: + long_date: MMM D + long_date_with_year: "MMM D, YYYY" + long_date_with_time: "MMM D, YYYY [at] HH:mm" + now: bây giờ + x_seconds_ago: "{{count}}giây trước" + x_minutes_ago: "{{count}}phút trước" + x_hours_ago: "{{count}}giờ trước" + hour: giờ + day: ngày + hours: giờ + days: ngày + month: month + months: months + year: year + reaction: + heart: trái tim + smile: nụ cười + frown: nhăn mặt + btn_label: thêm hoặc loại bỏ phản ứng + undo_emoji: bỏ dấu {{ emoji }} phản ứng + react_emoji: biểu cảm với {{ emoji }} + unreact_emoji: hủy biểu cảm {{ emoji }} + comment: + btn_add_comment: Thêm bình luận + reply_to: Trả lời cho + btn_reply: Trả lời + btn_edit: Chỉnh sửa + btn_delete: Xóa + btn_flag: Gắn Cờ + btn_save_edits: Lưu chỉnh sửa + btn_cancel: Hủy + show_more: "{{count}} bình luận khác" + tip_question: >- + Sử dụng bình luận để yêu cầu thêm thông tin hoặc đề xuất cải tiến. Tránh trả lời câu hỏi trong bình luận. + tip_answer: >- + Sử dụng bình luận để trả lời cho người dùng khác hoặc thông báo cho họ về các thay đổi. Nếu bạn đang thêm thông tin mới, hãy chỉnh sửa bài đăng của mình thay vì bình luận. + tip_vote: Nó thêm điều gì đó hữu ích cho bài đăng + edit_answer: + title: Chỉnh sửa Câu trả lời + default_reason: Chỉnh sửa câu trả lời + default_first_reason: Thêm câu trả lời + form: + fields: + revision: + label: Sửa đổi + answer: + label: Câu trả lời + feedback: + characters: nội dung phải có ít nhất 6 ký tự. + edit_summary: + label: Tóm tắt chỉnh sửa + placeholder: >- + Giải thích ngắn gọn các thay đổi của bạn (sửa chính tả, sửa ngữ pháp, cải thiện định dạng) + btn_save_edits: Lưu chỉnh sửa + btn_cancel: Hủy + tags: + title: Thẻ + sort_buttons: + popular: Phổ biến + name: Tên + newest: Mới nhất + button_follow: Theo dõi + button_following: Đang theo dõi + tag_label: câu hỏi + search_placeholder: Lọc theo tên thẻ + no_desc: Thẻ không có mô tả. + more: Thêm + wiki: Wiki + ask: + title: Create Question + edit_title: Chỉnh sửa Câu hỏi + default_reason: Chỉnh sửa câu hỏi + default_first_reason: Create question + similar_questions: Câu hỏi tương tự + form: + fields: + revision: + label: Sửa đổi + title: + label: Tiêu đề + placeholder: What's your topic? Be specific. + msg: + empty: Tiêu đề không thể trống. + range: Tiêu đề tối đa 150 ký tự + body: + label: Nội dung + msg: + empty: Nội dung không thể trống. + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: Thẻ + msg: + empty: Thẻ không thể trống. + answer: + label: Câu trả lời + msg: + empty: Câu trả lời không thể trống. + edit_summary: + label: Tóm tắt chỉnh sửa + placeholder: >- + Giải thích ngắn gọn các thay đổi của bạn (sửa chính tả, sửa ngữ pháp, cải thiện định dạng) + btn_post_question: Đăng câu hỏi của bạn + btn_save_edits: Lưu chỉnh sửa + answer_question: Trả lời câu hỏi của chính bạn + post_question&answer: Đăng câu hỏi và câu trả lời của bạn + tag_selector: + add_btn: Thêm thẻ + create_btn: Tạo thẻ mới + search_tag: Tìm kiếm thẻ + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: Không có thẻ phù hợp + tag_required_text: Thẻ bắt buộc (ít nhất một) + header: + nav: + question: Câu hỏi + tag: Thẻ + user: Người dùng + badges: Danh hiệu + profile: Hồ sơ + setting: Cài đặt + logout: Đăng xuất + admin: Quản trị + review: Xem xét + bookmark: Đánh dấu + moderation: Điều hành + search: + placeholder: Tìm kiếm + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: Thay đổi + loading: đang tải... + pic_auth_code: + title: Mã xác minh + placeholder: Nhập văn bản ở trên + msg: + empty: Captcha không thể trống. + inactive: + first: >- + Bạn gần như đã hoàn tất! Chúng tôi đã gửi một email kích hoạt đến {{mail}}. Vui lòng làm theo hướng dẫn trong email để kích hoạt tài khoản của bạn. + info: "Nếu không nhận được, hãy kiểm tra thư mục spam của bạn." + another: >- + Chúng tôi đã gửi một email kích hoạt khác cho bạn tại {{mail}}. Có thể mất vài phút để nó đến; hãy chắc chắn kiểm tra thư mục thư rác của bạn. + btn_name: Gửi lại email kích hoạt + change_btn_name: Thay đổi email + msg: + empty: Không thể để trống mục này. + resend_email: + url_label: Bạn có chắc chắn muốn gửi lại email kích hoạt không? + url_text: Bạn cũng có thể cung cấp liên kết kích hoạt ở trên cho người dùng. + login: + login_to_continue: Đăng nhập để tiếp tục + info_sign: Bạn không có tài khoản? <1>Đăng ký + info_login: Bạn đã có tài khoản? <1>Đăng nhập + agreements: Bằng cách đăng ký, bạn đồng ý với <1>chính sách bảo mật và <3>điều khoản dịch vụ. + forgot_pass: Quên mật khẩu? + name: + label: Tên + msg: + empty: Tên không thể trống. + range: Tên phải có độ dài từ 2 đến 30 ký tự. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: Email + msg: + empty: Email không thể trống. + password: + label: Mật khẩu + msg: + empty: Mật khẩu không thể trống. + different: Mật khẩu nhập vào ở hai bên không nhất quán + account_forgot: + page_title: Quên mật khẩu + btn_name: Gửi email khôi phục cho tôi + send_success: >- + Nếu một tài khoản khớp với {{mail}}, bạn sẽ sớm nhận được một email với hướng dẫn về cách đặt lại mật khẩu của mình. + email: + label: Email + msg: + empty: Email không thể trống. + change_email: + btn_cancel: Hủy + btn_update: Cập nhật địa chỉ email + send_success: >- + Nếu một tài khoản khớp với {{mail}}, bạn sẽ sớm nhận được một email với hướng dẫn về cách đặt lại mật khẩu của mình. + email: + label: Email mới + msg: + empty: Email không thể trống. + oauth: + connect: Kết nối với {{ auth_name }} + remove: Xóa bỏ {{ auth_name }} + oauth_bind_email: + subtitle: Thêm email khôi phục vào tài khoản của bạn. + btn_update: Cập nhật địa chỉ email + email: + label: Email + msg: + empty: Email không thể trống. + modal_title: Email đã tồn tại. + modal_content: Địa chỉ email này đã được đăng ký. Bạn có chắc chắn muốn kết nối với tài khoản hiện tại không? + modal_cancel: Thay đổi email + modal_confirm: Kết nối với tài khoản hiện tại + password_reset: + page_title: Đặt lại mật khẩu + btn_name: Đặt lại mật khẩu của tôi + reset_success: >- + Bạn đã thay đổi mật khẩu thành công; bạn sẽ được chuyển hướng đến trang đăng nhập. + link_invalid: >- + Xin lỗi, liên kết đặt lại mật khẩu này không còn hợp lệ. Có thể mật khẩu của bạn đã được đặt lại? + to_login: Tiếp tục đến trang đăng nhập + password: + label: Mật khẩu + msg: + empty: Mật khẩu không thể trống. + length: Độ dài cần nằm trong khoảng từ 8 đến 32 + different: Mật khẩu nhập vào ở hai bên không nhất quán + password_confirm: + label: Xác nhận mật khẩu mới + settings: + page_title: Cài đặt + goto_modify: Đi đến sửa đổi + nav: + profile: Hồ sơ + notification: Thông báo + account: Tài khoản + interface: Giao diện + profile: + heading: Hồ sơ + btn_name: Lưu + display_name: + label: Tên hiển thị + msg: Tên hiển thị không thể trống. + msg_range: Display name must be 2-30 characters in length. + username: + label: Tên người dùng + caption: Mọi người có thể nhắc đến bạn với "@username". + msg: Tên người dùng không thể trống. + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Hình ảnh hồ sơ + gravatar: Gravatar + gravatar_text: Bạn có thể thay đổi hình ảnh trên + custom: Tùy chỉnh + custom_text: Bạn có thể tải lên hình ảnh của mình. + default: Hệ thống + msg: Vui lòng tải lên một hình đại diện + bio: + label: Giới thiệu về tôi + website: + label: Website + placeholder: "https://example.com" + msg: Định dạng website không chính xác + location: + label: Địa điểm + placeholder: "Thành phố, Quốc gia" + notification: + heading: Thông báo qua Email + turn_on: Bật + inbox: + label: Thông báo hộp thư đến + description: Các câu trả lời cho câu hỏi của bạn, bình luận, lời mời và nhiều hơn nữa. + all_new_question: + label: Tất cả câu hỏi mới + description: Nhận thông báo về tất cả các câu hỏi mới. Tối đa 50 câu hỏi mỗi tuần. + all_new_question_for_following_tags: + label: Tất cả câu hỏi mới cho các thẻ theo dõi + description: Nhận thông báo về các câu hỏi mới cho các thẻ đang theo dõi. + account: + heading: Tài khoản + change_email_btn: Thay đổi email + change_pass_btn: Thay đổi mật khẩu + change_email_info: >- + Chúng tôi đã gửi một email đến địa chỉ đó. Vui lòng làm theo hướng dẫn xác nhận. + email: + label: Email + new_email: + label: Email mới + msg: Email mới không được để trống. + pass: + label: Mật khẩu hiện tại + msg: Mật khẩu không thể trống. + password_title: Mật khẩu + current_pass: + label: Mật khẩu hiện tại + msg: + empty: Mật khẩu hiện tại không thể trống. + length: Độ dài cần nằm trong khoảng từ 8 đến 32. + different: Hai mật khẩu nhập vào không khớp. + new_pass: + label: Mật khẩu mới + pass_confirm: + label: Xác nhận mật khẩu mới + interface: + heading: Giao diện + lang: + label: Ngôn ngữ giao diện + text: Ngôn ngữ giao diện người dùng. Nó sẽ thay đổi khi bạn làm mới trang. + my_logins: + title: Đăng nhập của tôi + label: Đăng nhập hoặc đăng ký trên trang này bằng các tài khoản này. + modal_title: Xóa đăng nhập + modal_content: Bạn có chắc chắn muốn xóa đăng nhập này khỏi tài khoản của bạn không? + modal_confirm_btn: Xóa + remove_success: Đã xóa thành công + toast: + update: cập nhật thành công + update_password: Mật khẩu đã được thay đổi thành công. + flag_success: Cảm ơn bạn đã đánh dấu. + forbidden_operate_self: Không được phép thao tác trên chính mình + review: Sửa đổi của bạn sẽ được hiển thị sau khi được xem xét. + sent_success: Đã gửi thành công + related_question: + title: Related + answers: câu trả lời + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: Mời mọi người + desc: Mời những người bạn nghĩ có thể trả lời. + invite: Mời trả lời + add: Thêm người + search: Tìm kiếm người + question_detail: + action: Hành động + created: Created + Asked: Đã hỏi + asked: đã hỏi + update: Đã chỉnh sửa + Edited: Edited + edit: đã chỉnh sửa + commented: đã bình luận + Views: Lượt xem + Follow: Theo dõi + Following: Đang theo dõi + follow_tip: Theo dõi câu hỏi này để nhận thông báo + answered: đã trả lời + closed_in: Đóng trong + show_exist: Hiển thị câu hỏi hiện tại. + useful: Hữu ích + question_useful: Nó hữu ích và rõ ràng + question_un_useful: Nó không rõ ràng hoặc không hữu ích + question_bookmark: Đánh dấu câu hỏi này + answer_useful: Nó hữu ích + answer_un_useful: Nó không hữu ích + answers: + title: Các câu trả lời + score: Điểm + newest: Mới nhất + oldest: Cũ nhất + btn_accept: Chấp nhận + btn_accepted: Đã chấp nhận + write_answer: + title: Câu trả lời của bạn + edit_answer: Chỉnh sửa câu trả lời hiện tại của tôi + btn_name: Đăng câu trả lời của bạn + add_another_answer: Thêm câu trả lời khác + confirm_title: Tiếp tục trả lời + continue: Tiếp tục + confirm_info: >- +

        Bạn có chắc chắn muốn thêm một câu trả lời khác không?

        Bạn có thể sử dụng liên kết chỉnh sửa để tinh chỉnh và cải thiện câu trả lời hiện tại của mình, thay vì.

        + empty: Câu trả lời không thể trống. + characters: nội dung phải có ít nhất 6 ký tự. + tips: + header_1: Cảm ơn câu trả lời của bạn + li1_1: Vui lòng chắc chắn trả lời câu hỏi. Cung cấp chi tiết và chia sẻ nghiên cứu của bạn. + li1_2: Hỗ trợ bất kỳ tuyên bố nào bạn đưa ra với tài liệu tham khảo hoặc kinh nghiệm cá nhân. + header_2: Nhưng tránh ... + li2_1: Yêu cầu trợ giúp, yêu cầu làm rõ, hoặc trả lời cho các câu trả lời khác. + reopen: + confirm_btn: Mở lại + title: Mở lại bài đăng này + content: Bạn có chắc chắn muốn mở lại không? + list: + confirm_btn: Danh sách + title: Danh sách bài đăng này + content: Bạn có chắc chắn muốn liệt kê không? + unlist: + confirm_btn: Gỡ bỏ khỏi danh sách + title: Gỡ bỏ bài đăng này khỏi danh sách + content: Bạn có chắc chắn muốn gỡ bỏ không? + pin: + title: Ghim bài đăng này + content: Bạn có chắc chắn muốn ghim toàn cầu không? Bài đăng này sẽ xuất hiện ở đầu tất cả các danh sách bài đăng. + confirm_btn: Ghim + delete: + title: Xóa bài đăng này + question: >- + Chúng tôi không khuyến khích xóa câu hỏi có câu trả lời vì làm như vậy sẽ tước đoạt kiến thức của độc giả trong tương lai.

        Việc xóa liên tục các câu hỏi đã được trả lời có thể dẫn đến việc tài khoản của bạn bị chặn không được phép hỏi. Bạn có chắc chắn muốn xóa không? + answer_accepted: >- +

        Chúng tôi không khuyến khích xóa câu trả lời đã được chấp nhận vì làm như vậy sẽ tước đoạt kiến thức của độc giả trong tương lai.

        Việc xóa liên tục các câu trả lời đã được chấp nhận có thể dẫn đến việc tài khoản của bạn bị chặn không được phép trả lời. Bạn có chắc chắn muốn xóa không? + other: Bạn có chắc chắn muốn xóa không? + tip_answer_deleted: Câu trả lời này đã bị xóa + undelete_title: Khôi phục bài đăng này + undelete_desc: Bạn có chắc chắn muốn khôi phục không? + btns: + confirm: Xác nhận + cancel: Hủy + edit: Chỉnh sửa + save: Lưu + delete: Xóa + undelete: Khôi phục + list: Danh sách + unlist: Gỡ bỏ khỏi danh sách + unlisted: Không được liệt kê + login: Đăng nhập + signup: Đăng ký + logout: Đăng xuất + verify: Xác minh + create: Create + approve: Phê duyệt + reject: Từ chối + skip: Bỏ qua + discard_draft: Hủy bản nháp + pinned: Đã ghim + all: Tất cả + question: Câu hỏi + answer: Câu trả lời + comment: Bình luận + refresh: Làm mới + resend: Gửi lại + deactivate: Ngừng kích hoạt + active: Hoạt động + suspend: Tạm ngừng + unsuspend: Bỏ vô hiệu hóa + close: Đóng + reopen: Mở lại + ok: Đồng ý + light: Phông nền sáng + dark: Tối + system_setting: Cài đặt hệ thống + default: Mặc định + reset: Đặt lại + tag: Thẻ + post_lowercase: bài đăng + filter: Lọc + ignore: Bỏ qua + submit: Gửi + normal: Bình thường + closed: Đã đóng + deleted: Đã xóa + deleted_permanently: Deleted permanently + pending: Đang chờ xử lý + more: Thêm + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: Kết quả tìm kiếm + keywords: Từ khóa + options: Tùy chọn + follow: Theo dõi + following: Đang theo dõi + counts: "{{count}} Kết quả" + counts_loading: "... Results" + more: Thêm + sort_btns: + relevance: Liên quan + newest: Mới nhất + active: Hoạt động + score: Điểm + more: Thêm + tips: + title: Mẹo tìm kiếm nâng cao + tag: "<1>[tag] tìm kiếm trong một thẻ" + user: "<1>user:username tìm kiếm theo tác giả" + answer: "<1>answers:0 câu hỏi chưa có câu trả lời" + score: "<1>score:3 bài đăng có điểm 3+" + question: "<1>is:question tìm kiếm câu hỏi" + is_answer: "<1>is:answer tìm kiếm câu trả lời" + empty: Chúng tôi không thể tìm thấy bất cứ thứ gì.
        Thử các từ khóa khác hoặc ít cụ thể hơn. + share: + name: Chia sẻ + copy: Sao chép liên kết + via: Chia sẻ bài đăng qua... + copied: Đã sao chép + facebook: Chia sẻ lên Facebook + twitter: Share to X + cannot_vote_for_self: Bạn không thể bỏ phiếu cho bài đăng của chính mình. + modal_confirm: + title: Lỗi... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: Tài khoản mới của bạn đã được xác nhận; bạn sẽ được chuyển hướng đến trang chủ. + link: Tiếp tục đến trang chủ + oops: Rất tiếc! + invalid: Liên kết bạn đã dùng không còn hoạt động nữa. + confirm_new_email: Email của bạn đã được cập nhật. + confirm_new_email_invalid: >- + Xin lỗi, liên kết xác nhận này không còn hợp lệ. Có thể email của bạn đã được thay đổi? + unsubscribe: + page_title: Hủy đăng ký + success_title: Hủy đăng ký thành công + success_desc: Bạn đã được gỡ bỏ khỏi danh sách người đăng ký này và sẽ không nhận được thêm email từ chúng tôi. + link: Thay đổi cài đặt + question: + following_tags: Thẻ đang theo dõi + edit: Chỉnh sửa + save: Lưu + follow_tag_tip: Theo dõi các thẻ để tùy chỉnh danh sách câu hỏi của bạn. + hot_questions: Câu hỏi nổi bật + all_questions: Tất cả câu hỏi + x_questions: "{{ count }} Câu hỏi" + x_answers: "{{ count }} câu trả lời" + x_posts: "{{ count }} Posts" + questions: Câu hỏi + answers: Câu trả lời + newest: Mới nhất + active: Hoạt động + hot: Được nhiều quan tâm + frequent: Thường xuyên + recommend: Đề xuất + score: Điểm + unanswered: Chưa được trả lời + modified: đã chỉnh sửa + answered: đã trả lời + asked: đã hỏi + closed: đã đóng + follow_a_tag: Theo dõi một thẻ + more: Thêm + personal: + overview: Tổng quan + answers: Câu trả lời + answer: câu trả lời + questions: Câu hỏi + question: câu hỏi + bookmarks: Đánh dấu + reputation: Danh tiếng + comments: Bình luận + votes: Bình chọn + badges: Danh hiệu + newest: Mới nhất + score: Điểm + edit_profile: Chỉnh sửa hồ sơ + visited_x_days: "Đã truy cập {{ count }} ngày" + viewed: Đã xem + joined: Tham gia + comma: "," + last_login: Đã xem + about_me: Về tôi + about_me_empty: "// Xin chào, Thế giới !" + top_answers: Câu trả lời hàng đầu + top_questions: Câu hỏi hàng đầu + stats: Thống kê + list_empty: Không tìm thấy bài đăng.
        Có thể bạn muốn chọn một thẻ khác? + content_empty: Không tìm thấy bài viết nào. + accepted: Đã chấp nhận + answered: đã trả lời + asked: đã hỏi + downvoted: đã bỏ phiếu xuống + mod_short: MOD + mod_long: Người điều hành + x_reputation: danh tiếng + x_votes: phiếu bầu nhận được + x_answers: câu trả lời + x_questions: câu hỏi + recent_badges: Huy hiệu gần đây + install: + title: Cài đặt + next: Tiếp theo + done: Hoàn thành + config_yaml_error: Không thể tạo file config.yaml. + lang: + label: Vui lòng chọn một ngôn ngữ + db_type: + label: Hệ quản trị cơ sở dữ liệu + db_username: + label: Tên người dùng + placeholder: root + msg: Tên người dùng không thể trống. + db_password: + label: Mật khẩu + placeholder: root + msg: Mật khẩu không thể trống. + db_host: + label: Máy chủ cơ sở dữ liệu + placeholder: "db:3306" + msg: Máy chủ cơ sở dữ liệu không thể trống. + db_name: + label: Tên cơ sở dữ liệu + placeholder: câu trả lời + msg: Tên cơ sở dữ liệu không thể trống. + db_file: + label: Tệp tin Database + placeholder: /data/answer.db + msg: Tệp cơ sở dữ liệu không thể trống. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: Tạo config.yaml + label: Tệp config.yaml đã được tạo. + desc: >- + Bạn có thể tạo tệp <1>config.yaml thủ công trong thư mục <1>/var/wwww/xxx/ và dán văn bản sau vào đó. + info: Sau khi bạn đã làm xong, nhấp vào nút "Tiếp theo". + site_information: Thông tin trang + admin_account: Tài khoản quản trị + site_name: + label: Tên trang + msg: Tên trang không thể trống. + msg_max_length: Tên trang phải có tối đa 30 ký tự. + site_url: + label: URL trang + text: Địa chỉ của trang của bạn. + msg: + empty: URL trang không thể trống. + incorrect: Định dạng URL trang không chính xác. + max_length: URL trang phải có tối đa 512 ký tự. + contact_email: + label: Email liên hệ + text: Địa chỉ email của người liên hệ chính phụ trách trang này. + msg: + empty: Email liên hệ không thể trống. + incorrect: Định dạng email liên hệ không chính xác. + login_required: + label: Riêng tư + switch: Yêu cầu đăng nhập + text: Chỉ người dùng đã đăng nhập mới có thể truy cập cộng đồng này. + admin_name: + label: Tên + msg: Tên không thể trống. + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: Mật khẩu + text: >- + Bạn sẽ cần mật khẩu này để đăng nhập. Vui lòng lưu trữ nó ở một nơi an toàn. + msg: Mật khẩu không thể trống. + msg_min_length: Mật khẩu phải có ít nhất 8 ký tự. + msg_max_length: Mật khẩu phải có tối đa 32 ký tự. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: Email + text: Bạn sẽ cần email này để đăng nhập. + msg: + empty: Email không thể trống. + incorrect: Định dạng email không chính xác. + ready_title: Trang web của bạn đã sẵn sàng + ready_desc: >- + Nếu bạn cảm thấy muốn thay đổi thêm cài đặt nào đó, hãy truy cập <1>mục quản trị; tìm nó trong menu trang. + good_luck: "Chúc bạn vui vẻ và may mắn!" + warn_title: Cảnh báo + warn_desc: >- + Tệp <1>config.yaml đã tồn tại. Nếu bạn cần đặt lại bất kỳ mục cấu hình nào trong tệp này, vui lòng xóa nó trước. + install_now: Bạn có thể thử <1>cài đặt ngay bây giờ. + installed: Đã cài đặt + installed_desc: >- + Có vẻ như bạn đã cài đặt rồi. Để cài đặt lại, vui lòng xóa các bảng cơ sở dữ liệu cũ trước. + db_failed: Kết nối cơ sở dữ liệu thất bại + db_failed_desc: >- + Điều này có thể có nghĩa là thông tin cơ sở dữ liệu trong tệp <1>config.yaml của bạn không chính xác hoặc không thể thiết lập liên lạc với máy chủ cơ sở dữ liệu. Điều này có thể có nghĩa là máy chủ cơ sở dữ liệu của máy chủ của bạn đang bị tắt. + counts: + views: lượt xem + votes: bình chọn + answers: câu trả lời + accepted: Đã chấp nhận + page_error: + http_error: Lỗi HTTP {{ code }} + desc_403: Bạn không có quyền truy cập trang này. + desc_404: Thật không may, trang này không tồn tại. + desc_50X: Máy chủ đã gặp sự cố và không thể hoàn thành yêu cầu của bạn. + back_home: Quay lại trang chủ + page_maintenance: + desc: "Chúng tôi đang bảo trì, chúng tôi sẽ trở lại sớm." + nav_menus: + dashboard: Bảng điều khiển + contents: Nội dung + questions: Câu hỏi + answers: Câu trả lời + users: Người dùng + badges: Huy hiệu + flags: Cờ + settings: Cài đặt + general: Chung + interface: Giao diện + smtp: SMTP + branding: Thương hiệu + legal: Pháp lý + write: Viết + terms: Terms + tos: Điều khoản dịch vụ + privacy: Quyền riêng tư + seo: SEO + customize: Tùy chỉnh + themes: Chủ đề + login: Đăng nhập + privileges: Đặc quyền + plugins: Plugins + installed_plugins: Plugin đã cài đặt + apperance: Appearance + website_welcome: Chào mừng bạn đến với {{site_name}} + user_center: + login: Đăng nhập + qrcode_login_tip: Vui lòng sử dụng {{ agentName }} để quét mã QR và đăng nhập. + login_failed_email_tip: Đăng nhập thất bại, vui lòng cho phép ứng dụng này truy cập thông tin email của bạn trước khi thử lại. + badges: + modal: + title: Chúc mừng + content: Bạn đã nhận được huy hiệu mới. + close: Đóng + confirm: Xem huy hiệu + title: Huy hiệu + awarded: Giải Thưởng + earned_×: Nhận được ×{{ number }} + ×_awarded: "{{ number }} được trao tặng" + can_earn_multiple: Bạn có thể kiếm được nhiều lần. + earned: Đã nhận + admin: + admin_header: + title: Quản trị + dashboard: + title: Bảng điều khiển + welcome: Chào mừng bạn đến với Answer Admin! + site_statistics: Thống kê trang + questions: "Câu hỏi:" + resolved: "Đã giải quyết:" + unanswered: "Chưa được trả lời:" + answers: "Câu trả lời:" + comments: "Bình luận:" + votes: "Phiếu bầu:" + users: "Người dùng:" + flags: "Cờ:" + reviews: "Đánh giá:" + site_health: Sức khỏe trang + version: "Phiên bản:" + https: "HTTPS:" + upload_folder: "Thư mục tải lên:" + run_mode: "Chế độ hoạt động:" + private: Riêng tư + public: Công cộng + smtp: "SMTP:" + timezone: "Múi giờ:" + system_info: Thông tin hệ thống + go_version: "Phiên bản Go:" + database: "Database:" + database_size: "Tệp tin Database:" + storage_used: "Bộ nhớ đã sử dụng:" + uptime: "Thời gian hoạt động:" + links: Links + plugins: Plugin + github: GitHub + blog: Blog + contact: Liên hệ + forum: Diễn đàn + documents: Tài liệu + feedback: Phản hồi + support: Hỗ trợ + review: Đánh giá + config: Cấu hình + update_to: Cập nhật lên + latest: Mới nhất + check_failed: Kiểm tra thất bại + "yes": "Có" + "no": "Không" + not_allowed: Không được phép + allowed: Được phép + enabled: Đã bật + disabled: Đã tắt + writable: Có thể chỉnh sửa + not_writable: Không thể ghi + flags: + title: Cờ + pending: Đang chờ xử lý + completed: Hoàn thành + flagged: Đã đánh dấu + flagged_type: Đã đánh dấu {{ type }} + created: Đã tạo + action: Hành động + review: Đánh giá + user_role_modal: + title: Thay đổi vai trò người dùng thành... + btn_cancel: Hủy + btn_submit: Gửi + new_password_modal: + title: Đặt mật khẩu mới + form: + fields: + password: + label: Mật khẩu + text: Người dùng sẽ bị đăng xuất và cần đăng nhập lại. + msg: Mật khẩu phải có độ dài từ 8 đến 32 ký tự. + btn_cancel: Hủy + btn_submit: Gửi + edit_profile_modal: + title: Chỉnh sửa hồ sơ + form: + fields: + display_name: + label: Tên hiển thị + msg_range: Display name must be 2-30 characters in length. + username: + label: Tên người dùng + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Địa chỉ email không hợp lệ. + edit_success: Chỉnh Sửa Thành Công + btn_cancel: Hủy + btn_submit: Gửi + user_modal: + title: Thêm người dùng mới + form: + fields: + users: + label: Thêm người dùng hàng loạt + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Tách "tên, email, mật khẩu" bằng dấu phẩy. Một người dùng mỗi dòng. + msg: "Vui lòng nhập email của người dùng, một dòng mỗi người." + display_name: + label: Tên hiển thị + msg: Tên hiển thị phải dài từ 2-30 ký tự. + email: + label: Email + msg: Email không hợp lệ. + password: + label: Mật khẩu + msg: Mật khẩu phải có từ 8 đến 32 ký tự. + btn_cancel: Hủy + btn_submit: Gửi + users: + title: Người dùng + name: Tên + email: Email + reputation: Danh tiếng + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: Trạng thái + role: Vai trò + action: Hành động + change: Thay đổi + all: Tất cả + staff: Nhân viên + more: Thêm + inactive: Không hoạt động + suspended: Bị tạm ngưng + deleted: Đã xóa + normal: Bình thường + Moderator: Người điều hành + Admin: Quản trị viên + User: Người dùng + filter: + placeholder: "Lọc theo tên, user:id" + set_new_password: Đặt mật khẩu mới + edit_profile: Chỉnh sửa hồ sơ + change_status: Thay đổi trạng thái + change_role: Thay đổi vai trò + show_logs: Hiển thị nhật ký + add_user: Thêm người dùng + deactivate_user: + title: Ngừng kích hoạt người dùng + content: Người dùng không hoạt động phải xác nhận lại email của họ. + delete_user: + title: Xóa người dùng này + content: Bạn có chắc chắn muốn xóa người dùng này không? Điều này là vĩnh viễn! + remove: Xóa nội dung của họ + label: Xóa tất cả các câu hỏi, câu trả lời, bình luận, vv. + text: Không chọn điều này nếu bạn chỉ muốn xóa tài khoản của người dùng. + suspend_user: + title: Đình chỉ người dùng này + content: Người dùng bị đình chỉ không thể đăng nhập. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: Câu hỏi + unlisted: Không được liệt kê + post: Bài đăng + votes: Phiếu bầu + answers: Câu trả lời + created: Đã tạo + status: Trạng thái + action: Hành động + change: Thay đổi + pending: Đang chờ xử lý + filter: + placeholder: "Lọc theo tiêu đề, question:id" + answers: + page_title: Câu trả lời + post: Bài đăng + votes: Phiếu bầu + created: Đã tạo + status: Trạng thái + action: Hành động + change: Thay đổi + filter: + placeholder: "Lọc theo tiêu đề, answer:id" + general: + page_title: Chung + name: + label: Tên trang + msg: Tên trang không thể trống. + text: "Tên của trang này, được sử dụng trong thẻ tiêu đề." + site_url: + label: URL trang + msg: Url trang không thể trống. + validate: Vui lòng nhập URL hợp lệ. + text: Địa chỉ của trang của bạn. + short_desc: + label: Mô tả ngắn của trang + msg: Mô tả ngắn của trang không thể trống. + text: "Mô tả ngắn, được sử dụng trong thẻ tiêu đề trên trang chủ." + desc: + label: Mô tả trang + msg: Mô tả trang không thể trống. + text: "Mô tả trang này trong một câu, được sử dụng trong thẻ mô tả meta." + contact_email: + label: Email liên hệ + msg: Email liên hệ không thể trống. + validate: Định dạng email liên hệ không hợp lệ. + text: Địa chỉ email của người liên hệ chính phụ trách trang này. + check_update: + label: Cập nhật phần mềm + text: Tự động kiểm tra cập nhật + interface: + page_title: Giao diện + language: + label: Ngôn ngữ giao diện + msg: Ngôn ngữ giao diện không thể trống. + text: Ngôn ngữ giao diện người dùng. Nó sẽ thay đổi khi bạn làm mới trang. + time_zone: + label: Múi giờ + msg: Múi giờ không thể trống. + text: Chọn một thành phố cùng múi giờ với bạn. + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: Email gửi từ + msg: Email gửi từ không thể trống. + text: Địa chỉ email mà các email được gửi từ đó. + from_name: + label: Tên gửi từ + msg: Tên gửi từ không thể trống. + text: Tên mà các email được gửi từ đó. + smtp_host: + label: Máy chủ SMTP + msg: Máy chủ SMTP không thể trống. + text: Máy chủ thư của bạn. + encryption: + label: Mã hóa + msg: Mã hóa không thể trống. + text: Đối với hầu hết các máy chủ, SSL là tùy chọn được khuyến nghị. + ssl: SSL + tls: TLS + none: Không + smtp_port: + label: Cổng SMTP + msg: Cổng SMTP phải là số từ 1 đến 65535. + text: Cổng đến máy chủ thư của bạn. + smtp_username: + label: Tên người dùng SMTP + msg: Tên người dùng SMTP không thể trống. + smtp_password: + label: Mật khẩu SMTP + msg: Mật khẩu SMTP không thể trống. + test_email_recipient: + label: Người nhận email kiểm tra + text: Cung cấp địa chỉ email sẽ nhận email kiểm tra. + msg: Người nhận email kiểm tra không hợp lệ + smtp_authentication: + label: Bật xác thực + title: Xác thực SMTP + msg: Xác thực SMTP không thể trống. + "yes": "Có" + "no": "Không" + branding: + page_title: Thương hiệu + logo: + label: Logo + msg: Logo không thể trống. + text: Hình ảnh logo ở góc trên bên trái của trang của bạn. Sử dụng hình ảnh hình chữ nhật rộng với chiều cao 56 và tỷ lệ khung hình lớn hơn 3:1. Nếu để trống, văn bản tiêu đề trang sẽ được hiển thị. + mobile_logo: + label: Logo di động + text: Logo được sử dụng trên phiên bản di động của trang của bạn. Sử dụng hình ảnh hình chữ nhật rộng với chiều cao 56. Nếu để trống, hình ảnh từ cài đặt "logo" sẽ được sử dụng. + square_icon: + label: Biểu tượng vuông + msg: Biểu tượng vuông không thể trống. + text: Hình ảnh được sử dụng làm cơ sở cho các biểu tượng siêu dữ liệu. Nên lớn hơn 512x512. + favicon: + label: Favicon + text: Favicon cho trang của bạn. Để hoạt động chính xác trên một CDN, nó phải là png. Sẽ được thay đổi kích thước thành 32x32. Nếu để trống, "biểu tượng vuông" sẽ được sử dụng. + legal: + page_title: Pháp lý + terms_of_service: + label: Điều khoản dịch vụ + text: "Bạn có thể thêm nội dung điều khoản dịch vụ ở đây. Nếu bạn đã có một tài liệu được lưu trữ ở nơi khác, cung cấp URL đầy đủ ở đây." + privacy_policy: + label: Chính sách bảo mật + text: "Bạn có thể thêm nội dung chính sách bảo mật ở đây. Nếu bạn đã có một tài liệu được lưu trữ ở nơi khác, cung cấp URL đầy đủ ở đây." + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: Viết + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Câu trả lời chỉnh sửa + label: Each user can only write one answer for each question + text: "Tắt để cho phép người dùng viết nhiều câu trả lời cho cùng một câu hỏi, điều này có thể khiến các câu trả lời bị mất trọng tâm." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Thẻ được đề xuất + text: "Các thẻ gợi ý sẽ hiển thị trong danh sách thả xuống theo mặc định." + msg: + contain_reserved: "các thẻ được đề xuất không được chứa thẻ dự bị" + required_tag: + title: Đặt thẻ cần thiết + label: Đặt thẻ được đề xuất là bắt buộc + text: "Mỗi câu hỏi mới phải có ít nhất một thẻ được đề xuất." + reserved_tags: + label: Thẻ dành riêng + text: "Thẻ dành riêng chỉ có thể được thêm vào một bài đăng bởi điều hành viên." + image_size: + label: Kích thước hình ảnh tối đa (MB) + text: "Kích thước tải lên hình ảnh tối đa." + attachment_size: + label: Kích thước tệp đính kèm tối đa (MB) + text: "Kích thước tải lên tệp đính kèm tối đa." + image_megapixels: + label: Megapixel hình ảnh tối đa + text: "Số megapixel tối đa được phép cho một hình ảnh." + image_extensions: + label: Tiện ích mở rộng hình ảnh được ủy quyền + text: "Danh sách đuôi file được phép hiển thị hình ảnh, phân cách bằng dấu phẩy." + attachment_extensions: + label: Các loại tệp đính kèm được phép tải lên + text: "Danh sách các đuôi file được phép tải lên, phân cách bằng dấu phẩy. CẢNH BÁO: Cho phép tải lên có thể gây ra vấn đề bảo mật." + seo: + page_title: SEO + permalink: + label: Liên kết cố định + text: Cấu trúc URL tùy chỉnh có thể cải thiện khả năng sử dụng và khả năng tương thích về sau của liên kết của bạn. + robots: + label: robots.txt + text: Điều này sẽ ghi đè vĩnh viễn bất kỳ cài đặt trang web liên quan nào. + themes: + page_title: Giao diện + themes: + label: Giao diện + text: Chọn một chủ đề hiện có. + color_scheme: + label: Sơ đồ màu + navbar_style: + label: Navbar background style + primary_color: + label: Màu chính + text: Thay đổi các màu sắc được sử dụng bởi chủ đề của bạn + css_and_html: + page_title: CSS và HTML + custom_css: + label: CSS tùy chỉnh + text: > + + head: + label: Đầu + text: > + + header: + label: Đầu trang + text: > + + footer: + label: Cuối trang + text: Điều này sẽ chèn trước </body>. + sidebar: + label: Thanh bên + text: Điều này sẽ chèn vào thanh bên. + login: + page_title: Đăng nhập + membership: + title: Thành viên + label: Cho phép đăng ký mới + text: Tắt để ngăn ai đó tạo tài khoản mới. + email_registration: + title: Đăng ký qua email + label: Cho phép đăng ký qua email + text: Tắt để ngăn ai đó tạo tài khoản mới thông qua email. + allowed_email_domains: + title: Miền email được phép + text: Miền email mà người dùng phải đăng ký tài khoản. Một miền mỗi dòng. Bỏ qua khi trống. + private: + title: Riêng tư + label: Yêu cầu đăng nhập + text: Chỉ người dùng đã đăng nhập mới có thể truy cập cộng đồng này. + password_login: + title: Đăng nhập bằng mật khẩu + label: Cho phép đăng nhập bằng email và mật khẩu + text: "CẢNH BÁO: Nếu tắt, bạn có thể không thể đăng nhập nếu bạn chưa cấu hình phương thức đăng nhập khác trước đó." + installed_plugins: + title: Plugin đã cài đặt + plugin_link: Plugin mở rộng và mở rộng chức năng của trang web. Bạn có thể tìm thấy plugin trong <1>Kho Plugin Answer. + filter: + all: Tất cả + active: Đang hoạt động + inactive: Không hoạt động + outdated: Quá hạn + plugins: + label: Plugin + text: Chọn một plugin hiện có. + name: Tên + version: Phiên bản + status: Trạng thái + action: Hành động + deactivate: Vô hiệu hóa + activate: Kích hoạt + settings: Cài đặt + settings_users: + title: Người dùng + avatar: + label: Hình đại diện mặc định + text: Dành cho người dùng không có hình đại diện tùy chỉnh của riêng họ. + gravatar_base_url: + label: Gravatar Base URL + text: URL của nhà cung cấp API Gravatar. Bỏ qua khi trống. + profile_editable: + title: Hồ sơ có thể chỉnh sửa + allow_update_display_name: + label: Cho phép người dùng thay đổi tên hiển thị của họ + allow_update_username: + label: Cho phép người dùng thay đổi tên người dùng của họ + allow_update_avatar: + label: Cho phép người dùng thay đổi hình ảnh hồ sơ của họ + allow_update_bio: + label: Cho phép người dùng thay đổi giới thiệu về mình + allow_update_website: + label: Cho phép người dùng thay đổi trang web của họ + allow_update_location: + label: Cho phép người dùng thay đổi vị trí của họ + privilege: + title: Đặc quyền + level: + label: Mức độ danh tiếng yêu cầu + text: Chọn mức danh tiếng yêu cầu cho các đặc quyền + msg: + should_be_number: dữ liệu đầu vào phải là kiểu số + number_larger_1: số phải bằng hoặc lớn hơn 1 + badges: + action: Hành động + active: Hoạt động + activate: Kích hoạt + all: Tất cả + awards: Giải Thưởng + deactivate: Ngừng kích hoạt + filter: + placeholder: Lọc theo tên, user:id + group: Nhóm + inactive: Không hoạt động + name: Tên + show_logs: Hiển thị nhật ký + status: Trạng thái + title: Danh hiệu + form: + optional: (tùy chọn) + empty: không thể trống + invalid: không hợp lệ + btn_submit: Lưu + not_found_props: "Không tìm thấy thuộc tính bắt buộc {{ key }}." + select: Chọn + page_review: + review: Xem xét + proposed: đề xuất + question_edit: Chỉnh sửa câu hỏi + answer_edit: Câu trả lời chỉnh sửa + tag_edit: Chỉnh sửa thẻ + edit_summary: Tóm tắt chỉnh sửa + edit_question: Chỉnh sửa câu hỏi + edit_answer: Chỉnh sửa câu trả lời + edit_tag: Chỉnh sửa thẻ + empty: Không còn nhiệm vụ xem xét nào. + approve_revision_tip: Bạn có chấp nhận sửa đổi này không? + approve_flag_tip: Bạn có chấp nhận cờ này không? + approve_post_tip: Bạn có chấp nhận bài đăng này không? + approve_user_tip: Bạn có chấp nhận người dùng này không? + suggest_edits: Đề xuất chỉnh sửa + flag_post: Đánh dấu bài đăng + flag_user: Đánh dấu người dùng + queued_post: Bài đăng trong hàng đợi + queued_user: Người dùng trong hàng đợi + filter_label: Loại + reputation: danh tiếng + flag_post_type: Đánh dấu bài đăng này là {{ type }}. + flag_user_type: Đánh dấu người dùng này là {{ type }}. + edit_post: Chỉnh sửa bài đăng + list_post: Liệt kê bài đăng + unlist_post: Gỡ bỏ bài đăng khỏi danh sách + timeline: + undeleted: đã khôi phục + deleted: đã xóa + downvote: bỏ phiếu xuống + upvote: bỏ phiếu lên + accept: chấp nhận + cancelled: đã hủy + commented: đã bình luận + rollback: quay lại + edited: đã chỉnh sửa + answered: đã trả lời + asked: đã hỏi + closed: đã đóng + reopened: đã mở lại + created: đã tạo + pin: đã ghim + unpin: bỏ ghim + show: được liệt kê + hide: không được liệt kê + title: "Lịch sử cho" + tag_title: "Dòng thời gian cho" + show_votes: "Hiển thị phiếu bầu" + n_or_a: N/A + title_for_question: "Dòng thời gian cho" + title_for_answer: "Dòng thời gian cho câu trả lời của {{ title }} bởi {{ author }}" + title_for_tag: "Dòng thời gian cho thẻ" + datetime: Ngày giờ + type: Loại + by: Bởi + comment: Bình luận + no_data: "Chúng tôi không thể tìm thấy bất cứ thứ gì." + users: + title: Người dùng + users_with_the_most_reputation: Người dùng có điểm danh tiếng cao nhất trong tuần này + users_with_the_most_vote: Người dùng đã bỏ phiếu nhiều nhất trong tuần này + staffs: Nhân viên cộng đồng của chúng tôi + reputation: danh tiếng + votes: phiếu bầu + prompt: + leave_page: Bạn có chắc chắn muốn rời khỏi trang không? + changes_not_save: Các thay đổi của bạn có thể không được lưu. + draft: + discard_confirm: Bạn có chắc chắn muốn hủy bản nháp của mình không? + messages: + post_deleted: Bài đăng này đã bị xóa. + post_cancel_deleted: Bài đăng này đã được phục hồi. + post_pin: Bài đăng này đã được ghim. + post_unpin: Bài đăng này đã bị bỏ ghim. + post_hide_list: Bài đăng này đã được ẩn khỏi danh sách. + post_show_list: Bài đăng này đã được hiển thị trên danh sách. + post_reopen: Bài đăng này đã được mở lại. + post_list: Bài đăng này đã được liệt kê. + post_unlist: Bài đăng này đã được gỡ bỏ khỏi danh sách. + post_pending: Bài đăng của bạn đang chờ xem xét. Đây là bản xem trước, nó sẽ được hiển thị sau khi được phê duyệt. + post_closed: Bài đăng này đã bị đóng. + answer_deleted: Câu trả lời này đã bị xóa. + answer_cancel_deleted: Câu trả lời này đã được phục hồi. + change_user_role: Vai trò của người dùng này đã được thay đổi. + user_inactive: Người dùng này đã không hoạt động. + user_normal: Người dùng này đã bình thường. + user_suspended: Người dùng này đã bị đình chỉ. + user_deleted: Người dùng này đã bị xóa. + badge_activated: Huy hiệu này đã được kích hoạt. + badge_inactivated: Huy hiệu này đã bị vô hiệu hóa. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/data/i18n/zh_CN.yaml b/data/i18n/zh_CN.yaml new file mode 100644 index 000000000..53dca07e3 --- /dev/null +++ b/data/i18n/zh_CN.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: 成功。 + unknown: + other: 未知错误。 + request_format_error: + other: 请求格式错误。 + unauthorized_error: + other: 未授权。 + database_error: + other: 数据服务器错误。 + forbidden_error: + other: 禁止访问。 + duplicate_request_error: + other: 重复提交。 + action: + report: + other: 举报 + edit: + other: 编辑 + delete: + other: 删除 + close: + other: 关闭 + reopen: + other: 重新打开 + forbidden_error: + other: 禁止访问。 + pin: + other: 置顶 + hide: + other: 列表隐藏 + unpin: + other: 取消置顶 + show: + other: 列表显示 + invite_someone_to_answer: + other: 编辑 + undelete: + other: 撤消删除 + merge: + other: 合并 + role: + name: + user: + other: 用户 + admin: + other: 管理员 + moderator: + other: 版主 + description: + user: + other: 默认没有特殊权限。 + admin: + other: 拥有管理网站的全部权限。 + moderator: + other: 拥有除访问后台管理以外的所有权限。 + privilege: + level_1: + description: + other: 级别 1(少量声望要求,适合私有团队、群组) + level_2: + description: + other: 级别 2(低声望要求,适合初启动的社区) + level_3: + description: + other: 级别 3(高声望要求,适合成熟的社区) + level_custom: + description: + other: 自定义等级 + rank_question_add_label: + other: 提问 + rank_answer_add_label: + other: 写答案 + rank_comment_add_label: + other: 写评论 + rank_report_add_label: + other: 举报 + rank_comment_vote_up_label: + other: 点赞评论 + rank_link_url_limit_label: + other: 每次发布超过 2 个链接 + rank_question_vote_up_label: + other: 点赞问题 + rank_answer_vote_up_label: + other: 点赞答案 + rank_question_vote_down_label: + other: 点踩问题 + rank_answer_vote_down_label: + other: 点踩答案 + rank_invite_someone_to_answer_label: + other: 邀请回答 + rank_tag_add_label: + other: 创建新标签 + rank_tag_edit_label: + other: 编辑标签描述(需要审核) + rank_question_edit_label: + other: 编辑别人的问题(需要审核) + rank_answer_edit_label: + other: 编辑别人的答案(需要审核) + rank_question_edit_without_review_label: + other: 编辑别人的问题无需审核 + rank_answer_edit_without_review_label: + other: 编辑别人的答案无需审核 + rank_question_audit_label: + other: 审核问题编辑 + rank_answer_audit_label: + other: 审核回答编辑 + rank_tag_audit_label: + other: 审核标签编辑 + rank_tag_edit_without_review_label: + other: 编辑标签描述无需审核 + rank_tag_synonym_label: + other: 管理标签同义词 + email: + other: 邮箱 + e_mail: + other: 邮箱 + password: + other: 密码 + pass: + other: 密码 + old_pass: + other: 当前密码 + original_text: + other: 本帖 + email_or_password_wrong_error: + other: 邮箱和密码不匹配。 + error: + common: + invalid_url: + other: 无效的 URL。 + status_invalid: + other: 无效状态。 + password: + space_invalid: + other: 密码不得含有空格。 + admin: + cannot_update_their_password: + other: 你无法修改自己的密码。 + cannot_edit_their_profile: + other: 您不能修改您的个人资料。 + cannot_modify_self_status: + other: 你无法修改自己的状态。 + email_or_password_wrong: + other: 邮箱和密码不匹配。 + answer: + not_found: + other: 没有找到答案。 + cannot_deleted: + other: 没有删除权限。 + cannot_update: + other: 没有更新权限。 + question_closed_cannot_add: + other: 问题已关闭,无法添加。 + content_cannot_empty: + other: 回答内容不能为空。 + comment: + edit_without_permission: + other: 不允许编辑评论。 + not_found: + other: 评论未找到。 + cannot_edit_after_deadline: + other: 评论时间太久,无法修改。 + content_cannot_empty: + other: 评论内容不能为空。 + email: + duplicate: + other: 邮箱已存在。 + need_to_be_verified: + other: 邮箱需要验证。 + verify_url_expired: + other: 邮箱验证的网址已过期,请重新发送邮件。 + illegal_email_domain_error: + other: 此邮箱不在允许注册的邮箱域中。请使用其他邮箱尝试。 + lang: + not_found: + other: 语言文件未找到。 + object: + captcha_verification_failed: + other: 验证码错误。 + disallow_follow: + other: 你不能关注。 + disallow_vote: + other: 你不能投票。 + disallow_vote_your_self: + other: 你不能为自己的帖子投票。 + not_found: + other: 对象未找到。 + verification_failed: + other: 验证失败。 + email_or_password_incorrect: + other: 邮箱和密码不匹配。 + old_password_verification_failed: + other: 旧密码验证失败。 + new_password_same_as_previous_setting: + other: 新密码和旧密码相同。 + already_deleted: + other: 该帖子已被删除。 + meta: + object_not_found: + other: Meta 对象未找到 + question: + already_deleted: + other: 该帖子已被删除。 + under_review: + other: 您的帖子正在等待审核。它将在它获得批准后可见。 + not_found: + other: 问题未找到。 + cannot_deleted: + other: 没有删除权限。 + cannot_close: + other: 没有关闭权限。 + cannot_update: + other: 没有更新权限。 + content_cannot_empty: + other: 内容不能为空。 + content_less_than_minimum: + other: 输入的内容不足。 + rank: + fail_to_meet_the_condition: + other: 声望值未达到要求。 + vote_fail_to_meet_the_condition: + other: 感谢投票。你至少需要 {{.Rank}} 声望才能投票。 + no_enough_rank_to_operate: + other: 你至少需要 {{.Rank}} 声望才能执行此操作。 + report: + handle_failed: + other: 报告处理失败。 + not_found: + other: 报告未找到。 + tag: + already_exist: + other: 标签已存在。 + not_found: + other: 标签未找到。 + recommend_tag_not_found: + other: 推荐标签不存在。 + recommend_tag_enter: + other: 请选择至少一个必选标签。 + not_contain_synonym_tags: + other: 不应包含同义词标签。 + cannot_update: + other: 没有更新权限。 + is_used_cannot_delete: + other: 你不能删除这个正在使用的标签。 + cannot_set_synonym_as_itself: + other: 你不能将当前标签设为自己的同义词。 + minimum_count: + other: 没有输入足够的标签。 + smtp: + config_from_name_cannot_be_email: + other: 发件人名称不能是邮箱地址。 + theme: + not_found: + other: 主题未找到。 + revision: + review_underway: + other: 目前无法编辑,有一个版本在审阅队列中。 + no_permission: + other: 无权限修改。 + user: + external_login_missing_user_id: + other: 第三方平台没有提供唯一的 UserID,所以你不能登录,请联系网站管理员。 + external_login_unbinding_forbidden: + other: 请在移除此登录之前为你的账户设置登录密码。 + email_or_password_wrong: + other: + other: 邮箱和密码不匹配。 + not_found: + other: 用户未找到。 + suspended: + other: 用户已被封禁。 + username_invalid: + other: 用户名无效。 + username_duplicate: + other: 用户名已被使用。 + set_avatar: + other: 头像设置错误。 + cannot_update_your_role: + other: 你不能修改自己的角色。 + not_allowed_registration: + other: 该网站暂未开放注册。 + not_allowed_login_via_password: + other: 该网站暂不支持密码登录。 + access_denied: + other: 拒绝访问 + page_access_denied: + other: 您没有权限访问此页面。 + add_bulk_users_format_error: + other: "发生错误,{{.Field}} 格式错误,在 '{{.Content}}' 行数 {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "一次性添加的用户数量应在 1-{{.MaxAmount}} 之间。" + status_suspended_forever: + other: "该用户已被永久封禁。该用户不符合社区准则。" + status_suspended_until: + other: "该用户已被封禁至 {{.SuspendedUntil}}。该用户不符合社区准则。" + status_deleted: + other: "该用户已被删除。" + status_inactive: + other: "该用户未激活。" + config: + read_config_failed: + other: 读取配置失败 + database: + connection_failed: + other: 数据库连接失败 + create_table_failed: + other: 创建表失败 + install: + create_config_failed: + other: 无法创建 config.yaml 文件。 + upload: + unsupported_file_format: + other: 不支持的文件格式。 + site_info: + config_not_found: + other: 未找到网站的该配置信息。 + badge: + object_not_found: + other: 没有找到徽章对象 + reason: + spam: + name: + other: 垃圾信息 + desc: + other: 这个帖子是一个广告,或是破坏性行为。它对当前的主题无帮助或无关。 + rude_or_abusive: + name: + other: 粗鲁或辱骂的 + desc: + other: "一个有理智的人都会认为这种内容不适合进行尊重性的讨论。" + a_duplicate: + name: + other: 重复内容 + desc: + other: 该问题有人问过,而且已经有了答案。 + placeholder: + other: 输入已有的问题链接 + not_a_answer: + name: + other: 不是答案 + desc: + other: "该帖是作为答案发布的,但它并没有试图回答这个问题。总之,它可能应该是个编辑、评论、另一个问题或者需要被删除。" + no_longer_needed: + name: + other: 不再需要 + desc: + other: 该评论已过时,对话性质或与此帖子无关。 + something: + name: + other: 其他原因 + desc: + other: 此帖子需要工作人员注意,因为是上述所列以外的其他理由。 + placeholder: + other: 让我们具体知道你关心的什么 + community_specific: + name: + other: 社区特定原因 + desc: + other: 该问题不符合社区准则。 + not_clarity: + name: + other: 需要细节或澄清 + desc: + other: 该问题目前涵盖多个问题。它应该侧重在一个问题上。 + looks_ok: + name: + other: 看起来没问题 + desc: + other: 这个帖子是好的,不是低质量。 + needs_edit: + name: + other: 需要编辑,我已做了修改。 + desc: + other: 改进和纠正你自己帖子中的问题。 + needs_close: + name: + other: 需要关闭 + desc: + other: 关闭的问题不能回答,但仍然可以编辑、投票和评论。 + needs_delete: + name: + other: 需要删除 + desc: + other: 该帖子将被删除。 + question: + close: + duplicate: + name: + other: 垃圾信息 + desc: + other: 此问题以前就有人问过,而且已经有了答案。 + guideline: + name: + other: 社区特定原因 + desc: + other: 该问题不符合社区准则。 + multiple: + name: + other: 需要细节或澄清 + desc: + other: 该问题目前涵盖多个问题。它应该只集中在一个问题上。 + other: + name: + other: 其他原因 + desc: + other: 该帖子存在上面没有列出的另一个原因。 + operation_type: + asked: + other: 提问于 + answered: + other: 回答于 + modified: + other: 修改于 + deleted_title: + other: 删除的问题 + questions_title: + other: 问题 + tag: + tags_title: + other: 标签 + no_description: + other: 此标签没有描述。 + notification: + action: + update_question: + other: 更新了问题 + answer_the_question: + other: 回答了问题 + update_answer: + other: 更新了答案 + accept_answer: + other: 采纳了答案 + comment_question: + other: 评论了问题 + comment_answer: + other: 评论了答案 + reply_to_you: + other: 回复了你 + mention_you: + other: 提到了你 + your_question_is_closed: + other: 你的问题已被关闭 + your_question_was_deleted: + other: 你的问题已被删除 + your_answer_was_deleted: + other: 你的答案已被删除 + your_comment_was_deleted: + other: 你的评论已被删除 + up_voted_question: + other: 点赞问题 + down_voted_question: + other: 点踩问题 + up_voted_answer: + other: 点赞答案 + down_voted_answer: + other: 点踩回答 + up_voted_comment: + other: 点赞评论 + invited_you_to_answer: + other: 邀请你回答 + earned_badge: + other: 你获得 "{{.BadgeName}}" 徽章 + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] 确认你的新邮箱地址" + body: + other: "请点击以下链接确认你在 {{.SiteName}} 上的新邮箱地址:
        \n{{.ChangeEmailUrl}}

        \n\n如果你没有请求此更改,请忽略此邮件。\n\n--
        \n这是系统自动发送的电子邮件,请勿回复,因为您的回复将不会被看到

        " + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} 回答了你的问题" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \n在 {{.SiteName}} 上查看

        \n\n--
        \n这是系统自动发送的电子邮件,请勿回复,因为您的回复将不会被看到

        \n\n取消订阅" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} 邀请您回答问题" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        我想你可能知道答案。

        \n在 {{.SiteName}} 上查看

        \n\n--
        \n这是系统自动发送的电子邮件,请勿回复,因为您的回复将不会被看到

        \n\n取消订阅" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} 评论了你的帖子" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \n在 {{.SiteName}} 上查看

        \n\n--
        \n这是系统自动发送的电子邮件,请勿回复,因为您的回复将不会被看到

        \n\n取消订阅" + new_question: + title: + other: "[{{.SiteName}}] 新问题: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}

        \n{{.Tags}}

        \n\n--
        \n这是系统自动发送的电子邮件,请勿回复,因为您的回复将不会被看到

        \n\n取消订阅" + pass_reset: + title: + other: "[{{.SiteName }}] 重置密码" + body: + other: "有人要求在 [{{.SiteName}}] 上重置你的密码。

        \n\n如果这不是你的操作,请安心忽略此电子邮件。

        \n\n请点击以下链接设置一个新密码:
        \n{{.PassResetUrl}}\n\n如果你没有请求此更改,请忽略此邮件。\n" + register: + title: + other: "[{{.SiteName}}] 确认你的新账户" + body: + other: "欢迎加入 {{.SiteName}}!

        \n\n请点击以下链接确认并激活你的新账户:
        \n{{.RegisterUrl}}

        \n\n如果上面的链接不能点击,请将其复制并粘贴到你的浏览器地址栏中。\n

        \n\n--
        \n这是系统自动发送的电子邮件,请勿回复,因为您的回复将不会被看到" + test: + title: + other: "[{{.SiteName}}] 测试邮件" + body: + other: "这是测试电子邮件。\n

        \n\n-
        \n注意:这是一个自动的系统电子邮件, 请不要回复此消息,因为您的回复将不会被看到。" + action_activity_type: + upvote: + other: 点赞 + upvoted: + other: 点赞 + downvote: + other: 点踩 + downvoted: + other: 点踩 + accept: + other: 采纳 + accepted: + other: 已采纳 + edit: + other: 编辑 + review: + queued_post: + other: 排队的帖子 + flagged_post: + other: 举报的帖子 + suggested_post_edit: + other: 建议的编辑 + reaction: + tooltip: + other: "{{ .Names }} 以及另外 {{ .Count }} 个..." + badge: + default_badges: + autobiographer: + name: + other: 自传作者 + desc: + other: 填写了 个人资料 信息。 + certified: + name: + other: 已认证 + desc: + other: 完成了我们的新用户教程。 + editor: + name: + other: 编辑者 + desc: + other: 首次帖子编辑。 + first_flag: + name: + other: 第一次举报 + desc: + other: 第一次举报一个帖子 + first_upvote: + name: + other: 第一次投票 + desc: + other: 第一次投票了一个帖子。 + first_link: + name: + other: 第一个链接 + desc: + other: 第一次添加了一个链接到另一个帖子。 + first_reaction: + name: + other: 第一个响应 + desc: + other: 第一次表情回应帖子 + first_share: + name: + other: 首次分享 + desc: + other: 首次分享了一个帖子。 + scholar: + name: + other: 学者 + desc: + other: 问了一个问题并接受了一个答案。 + commentator: + name: + other: 评论员 + desc: + other: 留下5条评论。 + new_user_of_the_month: + name: + other: 月度用户 + desc: + other: 本月杰出用户 + read_guidelines: + name: + other: 阅读指南 + desc: + other: 阅读[社区准则]。 + reader: + name: + other: 读者 + desc: + other: 用10个以上的答案在主题中阅读每个答案。 + welcome: + name: + other: 欢迎 + desc: + other: 获得一个点赞投票 + nice_share: + name: + other: 好分享 + desc: + other: 分享了一个拥有25个唯一访客的帖子。 + good_share: + name: + other: 好分享 + desc: + other: 分享了一个拥有300个唯一访客的帖子。 + great_share: + name: + other: 优秀的分享 + desc: + other: 分享了一个拥有1000个唯一访客的帖子。 + out_of_love: + name: + other: 失去爱好 + desc: + other: 一天内使用了 50 个赞。 + higher_love: + name: + other: 更高的爱好 + desc: + other: 一天内使用了 50 个赞 5 次。 + crazy_in_love: + name: + other: 爱情疯狂的 + desc: + other: 一天内使用了 50 个赞 20 次。 + promoter: + name: + other: 推荐人 + desc: + other: 邀请用户。 + campaigner: + name: + other: 宣传者 + desc: + other: 邀请了3个基本用户。 + champion: + name: + other: 冠军 + desc: + other: 邀请了5个成员。 + thank_you: + name: + other: 谢谢 + desc: + other: 有 20 个赞成票的帖子,并投了 10 个赞成票。 + gives_back: + name: + other: 返回 + desc: + other: 拥有100个投票赞成的职位并放弃了100个投票。 + empathetic: + name: + other: 情随境迁 + desc: + other: 拥有500个投票赞成的职位并放弃了1000个投票。 + enthusiast: + name: + other: 狂热 + desc: + other: 连续访问10天。 + aficionado: + name: + other: Aficionado + desc: + other: 连续访问100天。 + devotee: + name: + other: Devotee + desc: + other: 连续访问365天。 + anniversary: + name: + other: 周年纪念日 + desc: + other: 活跃成员一年至少发布一次。 + appreciated: + name: + other: 欣赏 + desc: + other: 在 20 个帖子中获得 1个投票 + respected: + name: + other: 尊敬 + desc: + other: 100个员额获得2次补票。 + admired: + name: + other: 仰慕 + desc: + other: 300个员额获得5次补票。 + solved: + name: + other: 已解决 + desc: + other: 接受答案。 + guidance_counsellor: + name: + other: 指导顾问 + desc: + other: 接受答案。 + know_it_all: + name: + other: 万事通 + desc: + other: 接受50个答案。 + solution_institution: + name: + other: 解决方案机构 + desc: + other: 有150个答案被接受。 + nice_answer: + name: + other: 好答案 + desc: + other: 回答得分为10或以上。 + good_answer: + name: + other: 好答案 + desc: + other: 回答得分为25或更多。 + great_answer: + name: + other: 优秀答案 + desc: + other: 回答得分为50或以上。 + nice_question: + name: + other: 好问题 + desc: + other: 问题得分为10或以上。 + good_question: + name: + other: 好问题 + desc: + other: 问题得分为25或更多。 + great_question: + name: + other: 很棒的问题 + desc: + other: 问题得分为50或更多。 + popular_question: + name: + other: 热门问题 + desc: + other: 问题有 500 个浏览量。 + notable_question: + name: + other: 值得关注问题 + desc: + other: 问题有 1,000 个浏览量。 + famous_question: + name: + other: 著名的问题 + desc: + other: 问题有 5,000 个浏览量。 + popular_link: + name: + other: 热门链接 + desc: + other: 发布了一个带有50个点击的外部链接。 + hot_link: + name: + other: 热门链接 + desc: + other: 发布了一个带有300个点击的外部链接。 + famous_link: + name: + other: 著名链接 + desc: + other: 发布了一个带有100个点击的外部链接。 + default_badge_groups: + getting_started: + name: + other: 完成初始化 + community: + name: + other: Community 专题 + posting: + name: + other: 发帖 +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: 如何排版 + desc: >- +
        • 引用问题或答案: #4

        • 添加链接

          <https://url.com>

          [标题](https://url.com)
        • 段落之间使用空行分隔

        • _斜体_ 或者 **粗体**

        • 使用 个空格缩进代码

        • 在行首添加 > 表示引用

        • 反引号进行转义 `像 _这样_`

        • 使用 ``` 创建代码块

          ```
          这是代码块
          ```
        + pagination: + prev: 上一页 + next: 下一页 + page_title: + question: 问题 + questions: 问题 + tag: 标签 + tags: 标签 + tag_wiki: 标签维基 + create_tag: 创建标签 + edit_tag: 编辑标签 + ask_a_question: 创建问题 + edit_question: 编辑问题 + edit_answer: 编辑回答 + search: 搜索 + posts_containing: 帖子包含 + settings: 设置 + notifications: 通知 + login: 登录 + sign_up: 注册 + account_recovery: 账号恢复 + account_activation: 账号激活 + confirm_email: 确认电子邮件 + account_suspended: 账号已被封禁 + admin: 后台管理 + change_email: 修改邮箱 + install: Answer 安装 + upgrade: Answer 升级 + maintenance: 网站维护 + users: 用户 + oauth_callback: 处理中 + http_404: HTTP 错误 404 + http_50X: HTTP 错误 500 + http_403: HTTP 错误 403 + logout: 退出 + posts: 帖子 + notifications: + title: 通知 + inbox: 收件箱 + achievement: 成就 + new_alerts: 新通知 + all_read: 全部标记为已读 + show_more: 显示更多 + someone: 有人 + inbox_type: + all: 全部 + posts: 帖子 + invites: 邀请 + votes: 投票 + answer: 回答 + question: 问题 + badge_award: 徽章 + suspended: + title: 你的账号账号已被封禁 + until_time: "你的账号被封禁直到 {{ time }}。" + forever: 你的账号已被永久封禁。 + end: 你违反了我们的社区准则。 + contact_us: 联系我们 + editor: + blockquote: + text: 引用 + bold: + text: 粗体 + chart: + text: 图表 + flow_chart: 流程图 + sequence_diagram: 时序图 + class_diagram: 类图 + state_diagram: 状态图 + entity_relationship_diagram: 实体关系图 + user_defined_diagram: 用户自定义图表 + gantt_chart: 甘特图 + pie_chart: 饼图 + code: + text: 代码块 + add_code: 添加代码块 + form: + fields: + code: + label: 代码块 + msg: + empty: 代码块不能为空 + language: + label: 语言 + placeholder: 自动识别 + btn_cancel: 取消 + btn_confirm: 添加 + formula: + text: 公式 + options: + inline: 行内公式 + block: 块级公式 + heading: + text: 标题 + options: + h1: 标题 1 + h2: 标题 2 + h3: 标题 3 + h4: 标题 4 + h5: 标题 5 + h6: 标题 6 + help: + text: 帮助 + hr: + text: 水平线 + image: + text: 图片 + add_image: 添加图片 + tab_image: 上传图片 + form_image: + fields: + file: + label: 图像文件 + btn: 选择图片 + msg: + empty: 请选择图片文件。 + only_image: 只能上传图片文件。 + max_size: 文件大小不能超过 {{size}} MB。 + desc: + label: 描述 + tab_url: 图片地址 + form_url: + fields: + url: + label: 图片地址 + msg: + empty: 图片地址不能为空 + name: + label: 描述 + btn_cancel: 取消 + btn_confirm: 添加 + uploading: 上传中 + indent: + text: 缩进 + outdent: + text: 减少缩进 + italic: + text: 斜体 + link: + text: 超链接 + add_link: 添加超链接 + form: + fields: + url: + label: 链接 + msg: + empty: 链接不能为空。 + name: + label: 描述 + btn_cancel: 取消 + btn_confirm: 添加 + ordered_list: + text: 有序列表 + unordered_list: + text: 无序列表 + table: + text: 表格 + heading: 表头 + cell: 单元格 + file: + text: 附件 + not_supported: "不支持的文件类型。请尝试上传其他类型的文件如: {{file_type}}。" + max_size: "上传文件超过 {{size}} MB。" + close_modal: + title: 关闭原因是... + btn_cancel: 取消 + btn_submit: 提交 + remark: + empty: 不能为空。 + msg: + empty: 请选择一个原因。 + report_modal: + flag_title: 我举报这篇帖子的原因是... + close_title: 我关闭这篇帖子的原因是... + review_question_title: 审查问题 + review_answer_title: 审查回答 + review_comment_title: 审查评论 + btn_cancel: 取消 + btn_submit: 提交 + remark: + empty: 不能为空 + msg: + empty: 请选择一个原因。 + not_a_url: URL 格式不正确。 + url_not_match: URL 来源与当前网站不匹配。 + tag_modal: + title: 创建新标签 + form: + fields: + display_name: + label: 显示名称 + msg: + empty: 显示名称不能为空。 + range: 显示名称不能超过 35 个字符。 + slug_name: + label: URL 固定链接 + desc: URL 固定链接不能超过 35 个字符。 + msg: + empty: URL 固定链接不能为空。 + range: URL 固定链接不能超过 35 个字符。 + character: URL 固定链接包含非法字符。 + desc: + label: 描述 + revision: + label: 编辑历史 + edit_summary: + label: 编辑备注 + placeholder: >- + 简单描述更改原因(更正拼写、修复语法、改进格式) + btn_cancel: 取消 + btn_submit: 提交 + btn_post: 发布新标签 + tag_info: + created_at: 创建于 + edited_at: 编辑于 + history: 历史 + synonyms: + title: 同义词 + text: 以下标签将被重置到 + empty: 此标签目前没有同义词。 + btn_add: 添加同义词 + btn_edit: 编辑 + btn_save: 保存 + synonyms_text: 以下标签将被重置到 + delete: + title: 删除标签 + tip_with_posts: >- +

        我们不允许 删除带有帖子的标签

        请先从帖子中移除此标签。

        + tip_with_synonyms: >- +

        我们不允许 删除带有同义词的标签

        请先从此标签中删除同义词。

        + tip: 确定要删除吗? + close: 关闭 + merge: + title: 合并标签 + source_tag_title: 源标签 + source_tag_description: 源标签及其相关数据将重新映射到目标标签。 + target_tag_title: 目标标签 + target_tag_description: 合并后将在这两个标签之间将创建一个同义词。 + no_results: 没有匹配的标签 + btn_submit: 提交 + btn_close: 关闭 + edit_tag: + title: 编辑标签 + default_reason: 编辑标签 + default_first_reason: 添加标签 + btn_save_edits: 保存更改 + btn_cancel: 取消 + dates: + long_date: MM 月 DD 日 + long_date_with_year: "YYYY 年 MM 月 DD 日" + long_date_with_time: "YYYY 年 MM 月 DD 日 HH:mm" + now: 刚刚 + x_seconds_ago: "{{count}} 秒前" + x_minutes_ago: "{{count}} 分钟前" + x_hours_ago: "{{count}} 小时前" + hour: 小时 + day: 天 + hours: 小时 + days: 日 + month: 月 + months: 月 + year: 年 + reaction: + heart: 爱心 + smile: 微笑 + frown: 愁 + btn_label: 添加或删除回应。 + undo_emoji: 撤销 {{ emoji }} 回应 + react_emoji: 用 {{ emoji }} 回应 + unreact_emoji: 撤销 {{ emoji }} + comment: + btn_add_comment: 添加评论 + reply_to: 回复 + btn_reply: 回复 + btn_edit: 编辑 + btn_delete: 删除 + btn_flag: 举报 + btn_save_edits: 保存更改 + btn_cancel: 取消 + show_more: "{{count}} 条剩余评论" + tip_question: >- + 使用评论提问更多信息或者提出改进意见。避免在评论里回答问题。 + tip_answer: >- + 使用评论对回答者进行回复,或者通知回答者你已更新了问题的内容。如果要补充或者完善问题的内容,请在原问题中更改。 + tip_vote: 它给帖子添加了一些有用的内容 + edit_answer: + title: 编辑回答 + default_reason: 编辑回答 + default_first_reason: 添加答案 + form: + fields: + revision: + label: 编辑历史 + answer: + label: 回答内容 + feedback: + characters: 内容长度至少 6 个字符 + edit_summary: + label: 编辑摘要 + placeholder: >- + 简单描述更改原因(更正拼写、修复语法、改进格式) + btn_save_edits: 保存更改 + btn_cancel: 取消 + tags: + title: 标签 + sort_buttons: + popular: 热门 + name: 名称 + newest: 最新 + button_follow: 关注 + button_following: 已关注 + tag_label: 个问题 + search_placeholder: 通过标签名称过滤 + no_desc: 此标签无描述。 + more: 更多 + wiki: 维基 + ask: + title: 创建问题 + edit_title: 编辑问题 + default_reason: 编辑问题 + default_first_reason: 创建问题 + similar_questions: 相似问题 + form: + fields: + revision: + label: 修订版本 + title: + label: 标题 + placeholder: 你的主题是什么?请具体说明。 + msg: + empty: 标题不能为空。 + range: 标题最多 150 个字符 + body: + label: 内容 + msg: + empty: 内容不能为空。 + hint: + optional_body: 描述这个问题是什么。 + minimum_characters: "详细描述这个问题,至少需要 {{min_content_length}} 字符。" + tags: + label: 标签 + msg: + empty: 必须选择一个标签 + answer: + label: 回答内容 + msg: + empty: 回答内容不能为空 + edit_summary: + label: 编辑备注 + placeholder: >- + 简单描述更改原因(更正拼写、修复语法、改进格式) + btn_post_question: 提交问题 + btn_save_edits: 保存更改 + answer_question: 回答自己的问题 + post_question&answer: 提交问题和回答 + tag_selector: + add_btn: 添加标签 + create_btn: 创建新标签 + search_tag: 搜索标签 + hint: 描述您的内容是关于什么,至少需要一个标签。 + hint_zero_tags: 描述您的内容与什么有关。 + hint_more_than_one_tag: "描述您的内容是关于什么,至少需要{{min_tags_number}}个标签。" + no_result: 没有匹配的标签 + tag_required_text: 必选标签(至少一个) + header: + nav: + question: 问题 + tag: 标签 + user: 用户 + badges: 徽章 + profile: 用户主页 + setting: 账号设置 + logout: 退出 + admin: 后台管理 + review: 审查 + bookmark: 收藏夹 + moderation: 管理 + search: + placeholder: 搜索 + footer: + build_on: 由 <1>Apache Answer 提供动力 + upload_img: + name: 更改 + loading: 加载中... + pic_auth_code: + title: 验证码 + placeholder: 输入图片中的文字 + msg: + empty: 验证码不能为空。 + inactive: + first: >- + 就差一步!我们发送了一封激活邮件到 {{mail}}。请按照邮件中的说明激活你的账户。 + info: "如果没有收到,请检查你的垃圾邮件文件夹。" + another: >- + 我们向你的邮箱 {{mail}} 发送了另一封激活电子邮件。可能需要几分钟才能到达;请务必检查您的垃圾邮件箱。 + btn_name: 重新发送激活邮件 + change_btn_name: 更改邮箱 + msg: + empty: 不能为空。 + resend_email: + url_label: 确定要重新发送激活邮件吗? + url_text: 你也可以将上面的激活链接给该用户。 + login: + login_to_continue: 登录以继续 + info_sign: 没有账户?<1>注册 + info_login: 已经有账户?<1>登录 + agreements: 登录即表示您同意<1>隐私政策和<3>服务条款。 + forgot_pass: 忘记密码? + name: + label: 名字 + msg: + empty: 名字不能为空 + range: 名称长度必须在 2 至 30 个字符之间。 + character: '只能由 "a-z", "0-9", " - . _" 组成' + email: + label: 邮箱 + msg: + empty: 邮箱不能为空 + password: + label: 密码 + msg: + empty: 密码不能为空 + different: 两次输入密码不一致 + account_forgot: + page_title: 忘记密码 + btn_name: 发送恢复邮件 + send_success: >- + 如果存在邮箱为 {{mail}} 账户,你将很快收到一封重置密码的说明邮件。 + email: + label: 邮箱 + msg: + empty: 邮箱不能为空 + change_email: + btn_cancel: 取消 + btn_update: 更新电子邮件地址 + send_success: >- + 如果存在邮箱为 {{mail}} 的账户,你将很快收到一封重置密码的说明邮件。 + email: + label: 新的电子邮件地址 + msg: + empty: 邮箱不能为空。 + oauth: + connect: 连接到 {{ auth_name }} + remove: 移除 {{ auth_name }} + oauth_bind_email: + subtitle: 向你的账户添加恢复邮件地址。 + btn_update: 更新电子邮件地址 + email: + label: 邮箱 + msg: + empty: 邮箱不能为空。 + modal_title: 邮箱已经存在。 + modal_content: 该电子邮件地址已经注册。你确定要连接到已有账户吗? + modal_cancel: 更改邮箱 + modal_confirm: 连接到已有账户 + password_reset: + page_title: 密码重置 + btn_name: 重置我的密码 + reset_success: >- + 你已经成功更改密码;你将被重定向到登录页面。 + link_invalid: >- + 抱歉,此密码重置链接已失效。也许是你已经重置过密码了? + to_login: 前往登录页面 + password: + label: 密码 + msg: + empty: 密码不能为空。 + length: 密码长度在8-32个字符之间 + different: 两次输入密码不一致 + password_confirm: + label: 确认新密码 + settings: + page_title: 设置 + goto_modify: 前往修改 + nav: + profile: 我的资料 + notification: 通知 + account: 账号 + interface: 界面 + profile: + heading: 个人资料 + btn_name: 保存 + display_name: + label: 显示名称 + msg: 昵称不能为空。 + msg_range: 显示名称长度必须为 2-30 个字符。 + username: + label: 用户名 + caption: 用户可以通过 "@用户名" 来提及你。 + msg: 用户名不能为空 + msg_range: 显示名称长度必须为 2-30 个字符。 + character: '只能由 "a-z", "0-9", " - . _" 组成' + avatar: + label: 头像 + gravatar: Gravatar + gravatar_text: 你可以更改图像在 + custom: 自定义 + custom_text: 你可以上传你的图片。 + default: 系统 + msg: 请上传头像 + bio: + label: 关于我 + website: + label: 网站 + placeholder: "https://example.com" + msg: 网址格式不正确 + location: + label: 位置 + placeholder: "城市,国家" + notification: + heading: 邮件通知 + turn_on: 开启 + inbox: + label: 收件箱通知 + description: 你的提问有新的回答,评论,邀请回答和其他。 + all_new_question: + label: 所有新问题 + description: 获取所有新问题的通知。每周最多有50个问题。 + all_new_question_for_following_tags: + label: 所有关注标签的新问题 + description: 获取关注的标签下新问题通知。 + account: + heading: 账号 + change_email_btn: 更改邮箱 + change_pass_btn: 更改密码 + change_email_info: >- + 邮件已发送。请根据指引完成验证。 + email: + label: 电子邮件地址 + new_email: + label: 新的电子邮件地址 + msg: 新邮箱不能为空。 + pass: + label: 当前密码 + msg: 密码不能为空。 + password_title: 密码 + current_pass: + label: 当前密码 + msg: + empty: 当前密码不能为空 + length: 密码长度必须在 8 至 32 之间 + different: 两次输入的密码不匹配 + new_pass: + label: 新密码 + pass_confirm: + label: 确认新密码 + interface: + heading: 界面 + lang: + label: 界面语言 + text: 设置用户界面语言,在刷新页面后生效。 + my_logins: + title: 我的登录 + label: 使用这些账户登录或注册本网站。 + modal_title: 移除登录 + modal_content: 你确定要从账户里移除该登录? + modal_confirm_btn: 移除 + remove_success: 移除成功 + toast: + update: 更新成功 + update_password: 密码更新成功。 + flag_success: 感谢标记。 + forbidden_operate_self: 禁止对自己执行操作 + review: 您的修订将在审阅通过后显示。 + sent_success: 发送成功 + related_question: + title: 相似 + answers: 个回答 + linked_question: + title: 关联 + description: 帖子关联到 + no_linked_question: 没有与之关联的贴子。 + invite_to_answer: + title: 受邀人 + desc: 邀请你认为可能知道答案的人。 + invite: 邀请回答 + add: 添加人员 + search: 搜索人员 + question_detail: + action: 操作 + created: 创建于 + Asked: 提问于 + asked: 提问于 + update: 修改于 + Edited: 编辑于 + edit: 编辑于 + commented: 评论 + Views: 阅读次数 + Follow: 关注此问题 + Following: 已关注 + follow_tip: 关注此问题以接收通知 + answered: 回答于 + closed_in: 关闭于 + show_exist: 查看类似问题。 + useful: 有用的 + question_useful: 它是有用和明确的 + question_un_useful: 它不明确或没用的 + question_bookmark: 收藏该问题 + answer_useful: 这是有用的 + answer_un_useful: 它是没有用的 + answers: + title: 个回答 + score: 评分 + newest: 最新 + oldest: 最旧 + btn_accept: 采纳 + btn_accepted: 已被采纳 + write_answer: + title: 你的回答 + edit_answer: 编辑我的回答 + btn_name: 提交你的回答 + add_another_answer: 添加另一个回答 + confirm_title: 继续回答 + continue: 继续 + confirm_info: >- +

        你确定要提交一个新的回答吗?

        作为替代,你可以通过编辑来完善和改进之前的回答。

        + empty: 回答内容不能为空。 + characters: 内容长度至少 6 个字符。 + tips: + header_1: 感谢你的回答 + li1_1: 请务必确定在 回答问题。提供详细信息并分享你的研究。 + li1_2: 用参考资料或个人经历来支持你所做的任何陈述。 + header_2: 但是 请避免... + li2_1: 请求帮助,寻求澄清,或答复其他答案。 + reopen: + confirm_btn: 重新打开 + title: 重新打开这个帖子 + content: 确定要重新打开吗? + list: + confirm_btn: 列表显示 + title: 列表中显示这个帖子 + content: 确定要列表中显示这个帖子吗? + unlist: + confirm_btn: 列表隐藏 + title: 从列表中隐藏这个帖子 + content: 确定要从列表中隐藏这个帖子吗? + pin: + title: 置顶该帖子 + content: 你确定要全局置顶吗?这个帖子将出现在所有帖子列表的顶部。 + confirm_btn: 置顶 + delete: + title: 删除 + question: >- + 我们不建议 删除有回答的帖子。因为这样做会使得后来的读者无法从该帖子中获得帮助。

        如果删除过多有回答的帖子,你的账号将会被禁止提问。你确定要删除吗? + answer_accepted: >- +

        我们不建议删除被采纳的回答。因为这样做会使得后来的读者无法从该帖子中获得帮助。

        如果删除过多被采纳的回答,你的账号将会被禁止回答任何提问。你确定要删除吗? + other: 你确定要删除? + tip_answer_deleted: 该回答已被删除 + undelete_title: 撤销删除本帖 + undelete_desc: 你确定你要撤销删除吗? + btns: + confirm: 确认 + cancel: 取消 + edit: 编辑 + save: 保存 + delete: 删除 + undelete: 撤消删除 + list: 列表显示 + unlist: 列表隐藏 + unlisted: 已隐藏 + login: 登录 + signup: 注册 + logout: 退出 + verify: 验证 + create: 创建 + approve: 批准 + reject: 拒绝 + skip: 跳过 + discard_draft: 丢弃草稿 + pinned: 已置顶 + all: 全部 + question: 问题 + answer: 回答 + comment: 评论 + refresh: 刷新 + resend: 重新发送 + deactivate: 取消激活 + active: 激活 + suspend: 封禁 + unsuspend: 解禁 + close: 关闭 + reopen: 重新打开 + ok: 确定 + light: 浅色 + dark: 深色 + system_setting: 跟随系统 + default: 默认 + reset: 重置 + tag: 标签 + post_lowercase: 帖子 + filter: 筛选 + ignore: 忽略 + submit: 提交 + normal: 正常 + closed: 已关闭 + deleted: 已删除 + deleted_permanently: 永久删除 + pending: 等待处理 + more: 更多 + view: 浏览量 + card: 卡片 + compact: 紧凑 + display_below: 在下方显示 + always_display: 总是显示 + or: 或者 + back_sites: 返回网站 + search: + title: 搜索结果 + keywords: 关键词 + options: 选项 + follow: 关注 + following: 已关注 + counts: "{{count}} 个结果" + counts_loading: "... 个结果" + more: 更多 + sort_btns: + relevance: 相关性 + newest: 最新的 + active: 活跃的 + score: 评分 + more: 更多 + tips: + title: 高级搜索提示 + tag: "<1>[tag] 在指定标签中搜索" + user: "<1>user:username 根据作者搜索" + answer: "<1>answers:0 搜索未回答的问题" + score: "<1>score:3 评分 3+ 的帖子" + question: "<1>is:question 搜索问题" + is_answer: "<1>is:answer 搜索回答" + empty: 找不到任何相关的内容。
        请尝试其他关键字,或者减少查找内容的长度。 + share: + name: 分享 + copy: 复制链接 + via: 分享到... + copied: 已复制 + facebook: 分享到 Facebook + twitter: 分享到 X + cannot_vote_for_self: 你不能给自己的帖子投票。 + modal_confirm: + title: 发生错误... + delete_permanently: + title: 永久删除 + content: 您确定要永久删除吗? + account_result: + success: 你的账号已通过验证,即将返回首页。 + link: 返回首页 + oops: 糟糕! + invalid: 您使用的链接不再有效。 + confirm_new_email: 你的电子邮箱已更新 + confirm_new_email_invalid: >- + 抱歉,此验证链接已失效。也许是你的邮箱已经成功更改了? + unsubscribe: + page_title: 退订 + success_title: 退订成功 + success_desc: 您已成功退订,并且将不会再收到我们的邮件。 + link: 更改设置 + question: + following_tags: 已关注的标签 + edit: 编辑 + save: 保存 + follow_tag_tip: 关注标签来筛选你的问题列表。 + hot_questions: 热门问题 + all_questions: 全部问题 + x_questions: "{{ count }} 个问题" + x_answers: "{{ count }} 个回答" + x_posts: "{{ count }} 个帖子" + questions: 问题 + answers: 回答 + newest: 最新 + active: 活跃 + hot: 热门 + frequent: 频繁的 + recommend: 推荐 + score: 评分 + unanswered: 未回答 + modified: 更新于 + answered: 回答于 + asked: 提问于 + closed: 已关闭 + follow_a_tag: 关注一个标签 + more: 更多 + personal: + overview: 概览 + answers: 回答 + answer: 回答 + questions: 问题 + question: 问题 + bookmarks: 收藏 + reputation: 声望 + comments: 评论 + votes: 得票 + badges: 徽章 + newest: 最新 + score: 评分 + edit_profile: 编辑资料 + visited_x_days: "已访问 {{ count }} 天" + viewed: 浏览次数 + joined: 加入于 + comma: "," + last_login: 上次登录 + about_me: 关于我 + about_me_empty: "// Hello, World!" + top_answers: 高分回答 + top_questions: 高分问题 + stats: 状态 + list_empty: 没有找到相关的内容。
        试试看其他选项卡? + content_empty: 未找到帖子。 + accepted: 已采纳 + answered: 回答于 + asked: 提问于 + downvoted: 点踩 + mod_short: 版主 + mod_long: 版主 + x_reputation: 声望 + x_votes: 得票 + x_answers: 个回答 + x_questions: 个问题 + recent_badges: 最近的徽章 + install: + title: 安装 + next: 下一步 + done: 完成 + config_yaml_error: 无法创建 config.yaml 文件。 + lang: + label: 请选择一种语言 + db_type: + label: 数据库引擎 + db_username: + label: 用户名 + placeholder: root + msg: 用户名不能为空 + db_password: + label: 密码 + placeholder: root + msg: 密码不能为空 + db_host: + label: 数据库主机 + placeholder: "db:3306" + msg: 数据库地址不能为空 + db_name: + label: 数据库名 + placeholder: 回答 + msg: 数据库名称不能为空。 + db_file: + label: 数据库文件 + placeholder: /data/answer.db + msg: 数据库文件不能为空。 + ssl_enabled: + label: 启用 SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL 模式 + ssl_root_cert: + placeholder: sslrootcert文件路径 + msg: sslrootcert 文件的路径不能为空 + ssl_cert: + placeholder: sslcert文件路径 + msg: sslcert 文件的路径不能为空 + ssl_key: + placeholder: sslkey 文件路径 + msg: sslcert 文件的路径不能为空 + config_yaml: + title: 创建 config.yaml + label: 已创建 config.yaml 文件。 + desc: >- + 你可以手动在 <1>/var/wwww/xxx/ 目录中创建 <1>config.yaml 文件并粘贴以下文本。 + info: 完成后,点击“下一步”按钮。 + site_information: 站点信息 + admin_account: 管理员账号 + site_name: + label: 站点名称 + msg: 站点名称不能为空。 + msg_max_length: 站点名称长度不得超过 30 个字符。 + site_url: + label: 网站网址 + text: 此网站的网址。 + msg: + empty: 网址不能为空。 + incorrect: 网址格式不正确。 + max_length: 网址长度不得超过 512 个字符。 + contact_email: + label: 联系邮箱 + text: 负责本网站的主要联系人的电子邮件地址。 + msg: + empty: 联系人邮箱不能为空。 + incorrect: 联系人邮箱地址不正确。 + login_required: + label: 私有的 + switch: 需要登录 + text: 只有登录用户才能访问这个社区。 + admin_name: + label: 名字 + msg: 名字不能为空。 + character: '只能由 "a-z", "0-9", " - . _" 组成' + msg_max_length: 名称长度必须在 2 至 30 个字符之间。 + admin_password: + label: 密码 + text: >- + 您需要此密码才能登录。请将其存储在一个安全的位置。 + msg: 密码不能为空。 + msg_min_length: 密码必须至少 8 个字符长。 + msg_max_length: 密码长度不能超过 32 个字符。 + admin_confirm_password: + label: "确认密码" + text: "请重新输入您的密码以确认。" + msg: "确认密码不一致。" + admin_email: + label: 邮箱 + text: 您需要此电子邮件才能登录。 + msg: + empty: 邮箱不能为空。 + incorrect: 邮箱格式不正确。 + ready_title: 您的网站已准备好 + ready_desc: >- + 如果你想改变更多的设置,请访问 <1>管理区域;在网站菜单中找到它。 + good_luck: "玩得愉快,祝你好运!" + warn_title: 警告 + warn_desc: >- + 文件 <1>config.yaml 已存在。如果你要重置该文件中的任何配置项,请先删除它。 + install_now: 您可以尝试 <1>现在安装。 + installed: 已安裝 + installed_desc: >- + 你似乎已经安装过了。如果要重新安装,请先清除旧的数据库表。 + db_failed: 数据连接异常! + db_failed_desc: >- + 这或者意味着数据库信息在 <1>config.yaml 文件不正确,或者无法与数据库服务器建立联系。这可能意味着你的主机数据库服务器故障。 + counts: + views: 次浏览 + votes: 个点赞 + answers: 个回答 + accepted: 已被采纳 + page_error: + http_error: HTTP 错误 {{ code }} + desc_403: 您无权访问此页面。 + desc_404: 很抱歉,此页面不存在。 + desc_50X: 服务器遇到了一个错误,无法完成你的请求。 + back_home: 返回首页 + page_maintenance: + desc: "我们正在进行维护,我们将很快回来。" + nav_menus: + dashboard: 后台管理 + contents: 内容管理 + questions: 问题 + answers: 回答 + users: 用户管理 + badges: 徽章 + flags: 举报管理 + settings: 站点设置 + general: 一般 + interface: 界面 + smtp: SMTP + branding: 品牌 + legal: 法律条款 + write: 撰写 + terms: 服务条款 + tos: 服务条款 + privacy: 隐私政策 + seo: SEO + customize: 自定义 + themes: 主题 + login: 登录 + privileges: 特权 + plugins: 插件 + installed_plugins: 已安装插件 + apperance: 外观 + website_welcome: 欢迎来到 {{site_name}} + user_center: + login: 登录 + qrcode_login_tip: 请使用 {{ agentName }} 扫描二维码并登录。 + login_failed_email_tip: 登录失败,请允许此应用访问您的邮箱信息,然后重试。 + badges: + modal: + title: 恭喜 + content: 你赢得了一个新徽章。 + close: 关闭 + confirm: 查看徽章 + title: 徽章 + awarded: 授予 + earned_×: 以获得 ×{{ number }} + ×_awarded: "{{ number }} 得到" + can_earn_multiple: 你可以多次获得 + earned: 获得 + admin: + admin_header: + title: 后台管理 + dashboard: + title: 后台管理 + welcome: 欢迎来到管理后台! + site_statistics: 站点统计 + questions: "问题:" + resolved: "已解决:" + unanswered: "未回答:" + answers: "回答:" + comments: "评论:" + votes: "投票:" + users: "用户:" + flags: "举报:" + reviews: "审查:" + site_health: 网站健康 + version: "版本" + https: "HTTPS:" + upload_folder: "上传文件夹:" + run_mode: "运行模式:" + private: 私有 + public: 公开 + smtp: "SMTP:" + timezone: "时区:" + system_info: 系统信息 + go_version: "Go版本:" + database: "数据库:" + database_size: "数据库大小:" + storage_used: "已用存储空间:" + uptime: "运行时间:" + links: 链接 + plugins: 插件 + github: GitHub + blog: 博客 + contact: 联系 + forum: 论坛 + documents: 文档 + feedback: 用户反馈 + support: 帮助 + review: 审查 + config: 配置 + update_to: 更新到 + latest: 最新版本 + check_failed: 校验失败 + "yes": "是" + "no": "否" + not_allowed: 拒绝 + allowed: 允许 + enabled: 已启用 + disabled: 停用 + writable: 可写 + not_writable: 不可写 + flags: + title: 举报 + pending: 等待处理 + completed: 已完成 + flagged: 被举报内容 + flagged_type: 标记了 {{ type }} + created: 创建于 + action: 操作 + review: 审查 + user_role_modal: + title: 更改用户状态为... + btn_cancel: 取消 + btn_submit: 提交 + new_password_modal: + title: 设置新密码 + form: + fields: + password: + label: 密码 + text: 用户将被退出,需要再次登录。 + msg: 密码的长度必须是8-32个字符。 + btn_cancel: 取消 + btn_submit: 提交 + edit_profile_modal: + title: 编辑资料 + form: + fields: + display_name: + label: 显示名称 + msg_range: 显示名称长度必须为 2-30 个字符。 + username: + label: 用户名 + msg_range: 用户名长度必须为 2-30 个字符。 + email: + label: 电子邮件地址 + msg_invalid: 无效的邮箱地址 + edit_success: 修改成功 + btn_cancel: 取消 + btn_submit: 提交 + user_modal: + title: 添加新用户 + form: + fields: + users: + label: 批量添加用户 + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: 用逗号分隔“name, email, password”,每行一个用户。 + msg: "请输入用户的邮箱,每行一个。" + display_name: + label: 显示名称 + msg: 显示名称长度必须为 2-30 个字符 + email: + label: 邮箱 + msg: 邮箱无效。 + password: + label: 密码 + msg: 密码的长度必须是8-32个字符。 + btn_cancel: 取消 + btn_submit: 提交 + users: + title: 用户 + name: 名称 + email: 邮箱 + reputation: 声望 + created_at: 创建时间 + delete_at: 删除时间 + suspend_at: 封禁时间 + suspend_until: 封禁到期 + status: 状态 + role: 角色 + action: 操作 + change: 更改 + all: 全部 + staff: 工作人员 + more: 更多 + inactive: 不活跃 + suspended: 已封禁 + deleted: 已删除 + normal: 正常 + Moderator: 版主 + Admin: 管理员 + User: 用户 + filter: + placeholder: "按名称筛选,用户:id" + set_new_password: 设置新密码 + edit_profile: 编辑资料 + change_status: 更改状态 + change_role: 更改角色 + show_logs: 显示日志 + add_user: 添加用户 + deactivate_user: + title: 停用用户 + content: 未激活的用户必须重新验证他们的邮箱。 + delete_user: + title: 删除此用户 + content: 确定要删除此用户?此操作无法撤销! + remove: 移除内容 + label: 删除所有问题、 答案、 评论等 + text: 如果你只想删除用户账户,请不要选中此项。 + suspend_user: + title: 挂起此用户 + content: 被封禁的用户将无法登录。 + label: 用户将被封禁多长时间? + forever: 永久 + questions: + page_title: 问题 + unlisted: 已隐藏 + post: 标题 + votes: 得票数 + answers: 回答数 + created: 创建于 + status: 状态 + action: 操作 + change: 更改 + pending: 等待处理 + filter: + placeholder: "按标题过滤,问题:id" + answers: + page_title: 回答 + post: 标题 + votes: 得票数 + created: 创建于 + status: 状态 + action: 操作 + change: 更改 + filter: + placeholder: "按标题筛选,答案:id" + general: + page_title: 一般 + name: + label: 站点名称 + msg: 不能为空 + text: "站点的名称,作为站点的标题。" + site_url: + label: 网站网址 + msg: 网站网址不能为空。 + validate: 请输入一个有效的 URL。 + text: 此网站的地址。 + short_desc: + label: 简短站点描述 + msg: 简短网站描述不能为空。 + text: "简短的标语,作为网站主页的标题(Html 的 title 标签)。" + desc: + label: 站点描述 + msg: 网站描述不能为空。 + text: "使用一句话描述本站,作为网站的描述(Html 的 meta 标签)。" + contact_email: + label: 联系邮箱 + msg: 联系人邮箱不能为空。 + validate: 联系人邮箱无效。 + text: 本网站的主要联系邮箱地址。 + check_update: + label: 软件更新 + text: 自动检查软件更新 + interface: + page_title: 界面 + language: + label: 界面语言 + msg: 不能为空 + text: 设置用户界面语言,在刷新页面后生效。 + time_zone: + label: 时区 + msg: 时区不能为空。 + text: 选择一个与您相同时区的城市。 + avatar: + label: 默认头像 + text: 没有自定义头像的用户。 + gravatar_base_url: + label: Gravatar 根路径 URL + text: Gravatar 提供商的 API 基础的 URL。当为空时忽略。 + smtp: + page_title: SMTP + from_email: + label: 发件人邮箱 + msg: 发件人邮箱不能为空。 + text: 用于发送邮件的地址。 + from_name: + label: 发件人 + msg: 不能为空 + text: 发件人的名字。 + smtp_host: + label: SMTP 主机 + msg: 不能为空 + text: 邮件服务器 + encryption: + label: 加密 + msg: 不能为空 + text: 对于大多数服务器而言,SSL 是推荐开启的。 + ssl: SSL + tls: TLS + none: 无加密 + smtp_port: + label: SMTP 端口 + msg: SMTP 端口必须在 1 ~ 65535 之间。 + text: 邮件服务器的端口号。 + smtp_username: + label: SMTP 用户名 + msg: 不能为空 + smtp_password: + label: SMTP 密码 + msg: 不能为空 + test_email_recipient: + label: 测试收件邮箱 + text: 提供用于接收测试邮件的邮箱地址。 + msg: 测试收件邮箱无效 + smtp_authentication: + label: 启用身份验证 + title: SMTP 身份验证 + msg: 不能为空 + "yes": "是" + "no": "否" + branding: + page_title: 品牌 + logo: + label: 网站标志(Logo) + msg: 图标不能为空。 + text: 在你的网站左上方的Logo图标。使用一个高度为56,长宽比大于3:1的宽长方形图像。如果留空,将显示网站标题文本。 + mobile_logo: + label: 移动端 Logo + text: 在你的网站的移动版上使用的标志。使用一个高度为56的宽矩形图像。如果留空,将使用 "Logo"设置中的图像。 + square_icon: + label: 方形图标 + msg: 方形图标不能为空。 + text: 用作元数据图标的基础的图像。最好是大于512x512。 + favicon: + label: 收藏夹图标 + text: 网站的图标。要在 CDN 正常工作,它必须是 png。 将调整大小到32x32。如果留空,将使用“方形图标”。 + legal: + page_title: 法律条款 + terms_of_service: + label: 服务条款 + text: "您可以在此添加服务内容的条款。如果您已经在别处托管了文档,请在这里提供完整的URL。" + privacy_policy: + label: 隐私政策 + text: "您可以在此添加隐私政策内容。如果您已经在别处托管了文档,请在这里提供完整的URL。" + external_content_display: + label: 外部内容 + text: "内容包括从外部网站嵌入的图像、视频和媒体。" + always_display: 总是显示外部内容 + ask_before_display: 在显示外部内容之前询问 + write: + page_title: 编辑 + min_content: + label: 最小问题长度 + text: 最小允许的问题内容长度(字符)。 + restrict_answer: + title: 回答编辑 + label: 每个用户对于每个问题只能有一个回答 + text: "用户可以使用编辑按钮优化已有的回答" + min_tags: + label: "问题的最少标签数" + text: "一个问题所需标签的最小数量。" + recommend_tags: + label: 推荐标签 + text: "推荐标签将默认显示在下拉列表中。" + msg: + contain_reserved: "推荐标签不能包含保留标签" + required_tag: + title: 设置必填标签 + label: 设置“推荐标签”为必需的标签 + text: "每个新问题必须至少有一个推荐标签。" + reserved_tags: + label: 保留标签 + text: "只有版主才能使用保留的标签。" + image_size: + label: 最大图像大小 (MB) + text: "最大图像上传大小." + attachment_size: + label: 最大附件大小 (MB) + text: "最大附件文件上传大小。" + image_megapixels: + label: 最大图像兆像素 + text: "允许图像的最大兆位数。" + image_extensions: + label: 允许的图像后缀 + text: "允许图像显示的文件扩展名的列表,用英文逗号分隔。" + attachment_extensions: + label: 允许的附件后缀 + text: "允许上传的文件扩展名列表与英文逗号分开。警告:允许上传可能会导致安全问题。" + seo: + page_title: 搜索引擎优化 + permalink: + label: 固定链接 + text: 自定义URL结构可以提高可用性,以及你的链接的向前兼容性。 + robots: + label: robots.txt + text: 这将永久覆盖任何相关的网站设置。 + themes: + page_title: 主题 + themes: + label: 主题 + text: 选择一个现有主题。 + color_scheme: + label: 配色方案 + navbar_style: + label: 导航栏背景样式 + primary_color: + label: 主色调 + text: 修改您主题使用的颜色 + css_and_html: + page_title: CSS 与 HTML + custom_css: + label: 自定义 CSS + text: > + + head: + label: 头部 + text: > + + header: + label: 页眉 + text: > + + footer: + label: 页脚 + text: 这将在 </body> 之前插入。 + sidebar: + label: 侧边栏 + text: 这将插入侧边栏中。 + login: + page_title: 登录 + membership: + title: 会员 + label: 允许新注册 + text: 关闭以防止任何人创建新账户。 + email_registration: + title: 邮箱注册 + label: 允许邮箱注册 + text: 关闭以阻止任何人通过邮箱创建新账户。 + allowed_email_domains: + title: 允许的邮箱域 + text: 允许注册账户的邮箱域。每行一个域名。留空时忽略。 + private: + title: 非公开的 + label: 需要登录 + text: 只有登录用户才能访问这个社区。 + password_login: + title: 密码登录 + label: 允许使用邮箱和密码登录 + text: "警告:如果您未配置过其他登录方式,关闭密码登录后您则可能无法登录。" + installed_plugins: + title: 已安装插件 + plugin_link: 插件扩展功能。您可以在<1>插件仓库中找到插件。 + filter: + all: 全部 + active: 已启用 + inactive: 未启用 + outdated: 已过期 + plugins: + label: 插件 + text: 选择一个现有的插件。 + name: 名称 + version: 版本 + status: 状态 + action: 操作 + deactivate: 停用 + activate: 启用 + settings: 设置 + settings_users: + title: 用户 + avatar: + label: 默认头像 + text: 没有自定义头像的用户。 + gravatar_base_url: + label: Gravatar 根路径 URL + text: Gravatar 提供商的 API 基础的 URL。当为空时忽略。 + profile_editable: + title: 个人资料可编辑 + allow_update_display_name: + label: 允许用户修改显示名称 + allow_update_username: + label: 允许用户修改用户名 + allow_update_avatar: + label: 允许用户修改个人头像 + allow_update_bio: + label: 允许用户修改个人介绍 + allow_update_website: + label: 允许用户修改个人主页网址 + allow_update_location: + label: 允许用户更改位置 + privilege: + title: 特权 + level: + label: 级别所需声望 + text: 选择特权所需的声望值 + msg: + should_be_number: 输入必须是数字 + number_larger_1: 数字应该大于等于 1 + badges: + action: 操作 + active: 活跃的 + activate: 启用 + all: 全部 + awards: 奖项 + deactivate: 取消激活 + filter: + placeholder: 按名称筛选,或使用 badge:id + group: 组 + inactive: 未启用 + name: 名字 + show_logs: 显示日志 + status: 状态 + title: 徽章 + form: + optional: (选填) + empty: 不能为空 + invalid: 是无效的 + btn_submit: 保存 + not_found_props: "所需属性 {{ key }} 未找到。" + select: 选择 + page_review: + review: 评论 + proposed: 提案 + question_edit: 问题编辑 + answer_edit: 回答编辑 + tag_edit: '标签管理: 编辑标签' + edit_summary: 编辑备注 + edit_question: 编辑问题 + edit_answer: 编辑回答 + edit_tag: 编辑标签 + empty: 没有剩余的审核任务。 + approve_revision_tip: 您是否批准此修订? + approve_flag_tip: 您是否批准此举报? + approve_post_tip: 您是否批准此帖子? + approve_user_tip: 您是否批准此修订? + suggest_edits: 建议的编辑 + flag_post: 举报帖子 + flag_user: 举报用户 + queued_post: 排队的帖子 + queued_user: 排队用户 + filter_label: 类型 + reputation: 声望值 + flag_post_type: 举报这个帖子的类型是 {{ type }} + flag_user_type: 举报这个用户的类型是 {{ type }} + edit_post: 编辑帖子 + list_post: 文章列表 + unlist_post: 隐藏的帖子 + timeline: + undeleted: 取消删除 + deleted: 删除 + downvote: 反对 + upvote: 点赞 + accept: 采纳 + cancelled: 已取消 + commented: '评论:' + rollback: 回滚 + edited: 最后编辑于 + answered: 回答于 + asked: 提问于 + closed: 关闭 + reopened: 重新开启 + created: 创建于 + pin: 已置顶 + unpin: 取消置頂 + show: 已显示 + hide: 已隐藏 + title: "历史记录" + tag_title: "时间线" + show_votes: "显示投票" + n_or_a: N/A + title_for_question: "时间线" + title_for_answer: "{{ title }} 的 {{ author }} 回答时间线" + title_for_tag: "时间线" + datetime: 日期时间 + type: 类型 + by: 由 + comment: 评论 + no_data: "空空如也" + users: + title: 用户 + users_with_the_most_reputation: 本周声望最高的用户 + users_with_the_most_vote: 本周投票最多的用户 + staffs: 我们的社区工作人员 + reputation: 声望值 + votes: 投票 + prompt: + leave_page: 确定要离开此页面? + changes_not_save: 您的更改尚未保存 + draft: + discard_confirm: 您确定要丢弃您的草稿吗? + messages: + post_deleted: 该帖子已被删除。 + post_cancel_deleted: 此帖子已被删除 + post_pin: 该帖子已被置顶。 + post_unpin: 该帖子已被取消置顶。 + post_hide_list: 此帖子已经从列表中隐藏。 + post_show_list: 该帖子已显示到列表中。 + post_reopen: 这个帖子已被重新打开. + post_list: 这个帖子已经被显示 + post_unlist: 这个帖子已经被隐藏 + post_pending: 您的帖子正在等待审核。它将在它获得批准后可见。 + post_closed: 此帖已关闭。 + answer_deleted: 该回答已被删除. + answer_cancel_deleted: 此答案已取消删除。 + change_user_role: 此用户的角色已被更改。 + user_inactive: 此用户已经处于未激活状态。 + user_normal: 此用户已经是正常的。 + user_suspended: 此用户已被封禁。 + user_deleted: 此用户已被删除 + badge_activated: 此徽章已被激活。 + badge_inactivated: 此徽章已被禁用。 + users_deleted: 这些用户已被删除。 + posts_deleted: 这些问题已被删除。 + answers_deleted: 这些答案已被删除。 + copy: 复制到剪贴板 + copied: 已复制 + external_content_warning: 外部图像/媒体未显示。 + + diff --git a/data/i18n/zh_TW.yaml b/data/i18n/zh_TW.yaml new file mode 100644 index 000000000..f0d254de9 --- /dev/null +++ b/data/i18n/zh_TW.yaml @@ -0,0 +1,2359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# The following fields are used for back-end +backend: + base: + success: + other: 成功。 + unknown: + other: 未知的錯誤。 + request_format_error: + other: 要求格式錯誤。 + unauthorized_error: + other: 未授權。 + database_error: + other: 資料伺服器錯誤。 + forbidden_error: + other: 已拒絕存取。 + duplicate_request_error: + other: 重複送出。 + action: + report: + other: 檢舉 + edit: + other: 編輯 + delete: + other: 删除 + close: + other: 關閉 + reopen: + other: 再次開啟。 + forbidden_error: + other: 已拒絕存取。 + pin: + other: 置頂 + hide: + other: 不公開 + unpin: + other: 取消置頂 + show: + other: 清單 + invite_someone_to_answer: + other: 編輯 + undelete: + other: 還原 + merge: + other: 合併 + role: + name: + user: + other: 使用者 + admin: + other: 管理員 + moderator: + other: 版主 + description: + user: + other: 預設沒有特別閱讀權限。 + admin: + other: 擁有存取此網站的全部權限。 + moderator: + other: 可以存取除了管理員設定以外的所有貼文。 + privilege: + level_1: + description: + other: Level 1 (less reputation required for private team, group) + level_2: + description: + other: Level 2 (low reputation required for startup community) + level_3: + description: + other: Level 3 (high reputation required for mature community) + level_custom: + description: + other: Custom Level + rank_question_add_label: + other: Ask question + rank_answer_add_label: + other: Write answer + rank_comment_add_label: + other: 寫留言 + rank_report_add_label: + other: Flag + rank_comment_vote_up_label: + other: Upvote comment + rank_link_url_limit_label: + other: Post more than 2 links at a time + rank_question_vote_up_label: + other: Upvote question + rank_answer_vote_up_label: + other: Upvote answer + rank_question_vote_down_label: + other: Downvote question + rank_answer_vote_down_label: + other: Downvote answer + rank_invite_someone_to_answer_label: + other: Invite someone to answer + rank_tag_add_label: + other: Create new tag + rank_tag_edit_label: + other: Edit tag description (need to review) + rank_question_edit_label: + other: Edit other's question (need to review) + rank_answer_edit_label: + other: Edit other's answer (need to review) + rank_question_edit_without_review_label: + other: Edit other's question without review + rank_answer_edit_without_review_label: + other: Edit other's answer without review + rank_question_audit_label: + other: Review question edits + rank_answer_audit_label: + other: Review answer edits + rank_tag_audit_label: + other: Review tag edits + rank_tag_edit_without_review_label: + other: Edit tag description without review + rank_tag_synonym_label: + other: Manage tag synonyms + email: + other: 電子郵件 + e_mail: + other: 電子郵件 + password: + other: 密碼 + pass: + other: 密碼 + old_pass: + other: 目前密碼 + original_text: + other: 此貼文 + email_or_password_wrong_error: + other: 電郵和密碼不匹配。 + error: + common: + invalid_url: + other: URL 無效。 + status_invalid: + other: 無效狀態。 + password: + space_invalid: + other: 密碼不能包含空白字元。 + admin: + cannot_update_their_password: + other: 你不能修改自己的密码。 + cannot_edit_their_profile: + other: You cannot modify your profile. + cannot_modify_self_status: + other: You cannot modify your status. + email_or_password_wrong: + other: 電郵和密碼不匹配。 + answer: + not_found: + other: 未發現答案。 + cannot_deleted: + other: 沒有刪除權限。 + cannot_update: + other: 沒有更新權限。 + question_closed_cannot_add: + other: Questions are closed and cannot be added. + content_cannot_empty: + other: Answer content cannot be empty. + comment: + edit_without_permission: + other: 不允許編輯留言。 + not_found: + other: 未發現留言。 + cannot_edit_after_deadline: + other: 這則留言時間過久,無法修改。 + content_cannot_empty: + other: Comment content cannot be empty. + email: + duplicate: + other: 這個電子郵件地址已被使用。 + need_to_be_verified: + other: 需驗證電子郵件地址。 + verify_url_expired: + other: 電子郵件地址驗證網址已過期,請重寄電子郵件。 + illegal_email_domain_error: + other: Email is not allowed from that email domain. Please use another one. + lang: + not_found: + other: 未找到語言檔。 + object: + captcha_verification_failed: + other: 驗證碼錯誤。 + disallow_follow: + other: 你不被允許追蹤。 + disallow_vote: + other: 你無法投票。 + disallow_vote_your_self: + other: 你不能為自己的貼文投票。 + not_found: + other: 找不到物件。 + verification_failed: + other: 驗證失敗。 + email_or_password_incorrect: + other: 電子郵件地址和密碼不匹配。 + old_password_verification_failed: + other: 舊密碼驗證失敗 + new_password_same_as_previous_setting: + other: 新密碼與先前的一樣。 + already_deleted: + other: 這則貼文已被刪除。 + meta: + object_not_found: + other: Meta object not found + question: + already_deleted: + other: This post has been deleted. + under_review: + other: Your post is awaiting review. It will be visible after it has been approved. + not_found: + other: 找不到問題。 + cannot_deleted: + other: 無刪除權限。 + cannot_close: + other: 無關閉權限。 + cannot_update: + other: 無更新權限。 + content_cannot_empty: + other: Content cannot be empty. + content_less_than_minimum: + other: Not enough content entered. + rank: + fail_to_meet_the_condition: + other: Reputation rank fail to meet the condition. + vote_fail_to_meet_the_condition: + other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. + no_enough_rank_to_operate: + other: You need at least {{.Rank}} reputation to do this. + report: + handle_failed: + other: 報告處理失敗。 + not_found: + other: 找不到報告。 + tag: + already_exist: + other: Tag already exists. + not_found: + other: 找不到標籤。 + recommend_tag_not_found: + other: Recommend tag is not exist. + recommend_tag_enter: + other: 請輸入至少一個必需的標籤。 + not_contain_synonym_tags: + other: 不應包含同義詞標籤。 + cannot_update: + other: 沒有權限更新。 + is_used_cannot_delete: + other: You cannot delete a tag that is in use. + cannot_set_synonym_as_itself: + other: 你不能將目前標籤的同義詞設定為本身。 + minimum_count: + other: Not enough tags were entered. + smtp: + config_from_name_cannot_be_email: + other: The from name cannot be a email address. + theme: + not_found: + other: 未找到主題。 + revision: + review_underway: + other: 目前無法編輯,有一個版本在審查佇列中。 + no_permission: + other: No permission to revise. + user: + external_login_missing_user_id: + other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. + external_login_unbinding_forbidden: + other: Please set a login password for your account before you remove this login. + email_or_password_wrong: + other: + other: 電子郵箱和密碼不匹配。 + not_found: + other: 未找到使用者。 + suspended: + other: 該使用者已被停權。 + username_invalid: + other: 使用者名稱無效。 + username_duplicate: + other: 使用者名稱已被使用。 + set_avatar: + other: 大頭照設定錯誤。 + cannot_update_your_role: + other: 您不能修改自己的角色。 + not_allowed_registration: + other: Currently the site is not open for registration. + not_allowed_login_via_password: + other: Currently the site is not allowed to login via password. + access_denied: + other: Access denied + page_access_denied: + other: You do not have access to this page. + add_bulk_users_format_error: + other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" + add_bulk_users_amount_error: + other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." + status_suspended_forever: + other: "This user was suspended forever. This user doesn't meet a community guideline." + status_suspended_until: + other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." + status_deleted: + other: "This user was deleted." + status_inactive: + other: "This user is inactive." + config: + read_config_failed: + other: 讀取組態失敗 + database: + connection_failed: + other: 資料庫連線失敗 + create_table_failed: + other: 表建立失敗 + install: + create_config_failed: + other: 無法建立 config.yaml 檔。 + upload: + unsupported_file_format: + other: 不支援的檔案格式。 + site_info: + config_not_found: + other: Site config not found. + badge: + object_not_found: + other: Badge object not found + reason: + spam: + name: + other: 垃圾訊息 + desc: + other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. + rude_or_abusive: + name: + other: rude or abusive + desc: + other: "A reasonable person would find this content inappropriate for respectful discourse." + a_duplicate: + name: + other: a duplicate + desc: + other: This question has been asked before and already has an answer. + placeholder: + other: Enter the existing question link + not_a_answer: + name: + other: not an answer + desc: + other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." + no_longer_needed: + name: + other: no longer needed + desc: + other: This comment is outdated, conversational or not relevant to this post. + something: + name: + other: something else + desc: + other: This post requires staff attention for another reason not listed above. + placeholder: + other: Let us know specifically what you are concerned about + community_specific: + name: + other: a community-specific reason + desc: + other: This question doesn't meet a community guideline. + not_clarity: + name: + other: needs details or clarity + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + looks_ok: + name: + other: looks OK + desc: + other: This post is good as-is and not low quality. + needs_edit: + name: + other: needs edit, and I did it + desc: + other: Improve and correct problems with this post yourself. + needs_close: + name: + other: 需關閉 + desc: + other: A closed question can't answer, but still can edit, vote and comment. + needs_delete: + name: + other: needs delete + desc: + other: This post will be deleted. + question: + close: + duplicate: + name: + other: 垃圾訊息 + desc: + other: 此問題以前就有人問過,而且已經有了答案。 + guideline: + name: + other: 一个社群特定原因 + desc: + other: 此問題不符合社群準則。 + multiple: + name: + other: 需要細節或明晰 + desc: + other: This question currently includes multiple questions in one. It should focus on one problem only. + other: + name: + other: 其他原因 + desc: + other: 這個帖子需要上面沒有列出的另一個原因。 + operation_type: + asked: + other: 提問於 + answered: + other: 回答於 + modified: + other: 修改於 + deleted_title: + other: Deleted question + questions_title: + other: Questions + tag: + tags_title: + other: Tags + no_description: + other: The tag has no description. + notification: + action: + update_question: + other: 更新了問題 + answer_the_question: + other: 回答了問題 + update_answer: + other: 更新了答案 + accept_answer: + other: 已接受的回答 + comment_question: + other: 留言了問題 + comment_answer: + other: 留言了答案 + reply_to_you: + other: 回覆了你 + mention_you: + other: 提到了你 + your_question_is_closed: + other: 你的問題已被關閉 + your_question_was_deleted: + other: 你的問題已被刪除 + your_answer_was_deleted: + other: 你的答案已被刪除 + your_comment_was_deleted: + other: 你的留言已被刪除 + up_voted_question: + other: upvoted question + down_voted_question: + other: downvoted question + up_voted_answer: + other: upvoted answer + down_voted_answer: + other: downvoted answer + up_voted_comment: + other: upvoted comment + invited_you_to_answer: + other: invited you to answer + earned_badge: + other: You've earned the "{{.BadgeName}}" badge + email_tpl: + change_email: + title: + other: "[{{.SiteName}}] Confirm your new email address" + body: + other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + new_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} answered your question" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + invited_you_to_answer: + title: + other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_comment: + title: + other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" + body: + other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + new_question: + title: + other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" + body: + other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" + pass_reset: + title: + other: "[{{.SiteName }}] Password reset" + body: + other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + register: + title: + other: "[{{.SiteName}}] Confirm your new account" + body: + other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + test: + title: + other: "[{{.SiteName}}] Test Email" + body: + other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." + action_activity_type: + upvote: + other: upvote + upvoted: + other: upvoted + downvote: + other: downvote + downvoted: + other: downvoted + accept: + other: 採納 + accepted: + other: 已採納 + edit: + other: 編輯 + review: + queued_post: + other: Queued post + flagged_post: + other: Flagged post + suggested_post_edit: + other: Suggested edits + reaction: + tooltip: + other: "{{ .Names }} and {{ .Count }} more..." + badge: + default_badges: + autobiographer: + name: + other: Autobiographer + desc: + other: Filled out profile information. + certified: + name: + other: Certified + desc: + other: Completed our new user tutorial. + editor: + name: + other: 編輯者 + desc: + other: First post edit. + first_flag: + name: + other: First Flag + desc: + other: First flagged a post. + first_upvote: + name: + other: First Upvote + desc: + other: First up voted a post. + first_link: + name: + other: 首個連結 + desc: + other: First added a link to another post. + first_reaction: + name: + other: First Reaction + desc: + other: First reacted to the post. + first_share: + name: + other: First Share + desc: + other: First shared a post. + scholar: + name: + other: Scholar + desc: + other: Asked a question and accepted an answer. + commentator: + name: + other: Commentator + desc: + other: Leave 5 comments. + new_user_of_the_month: + name: + other: New User of the Month + desc: + other: Outstanding contributions in their first month. + read_guidelines: + name: + other: Read Guidelines + desc: + other: Read the [community guidelines]. + reader: + name: + other: 閱讀者 + desc: + other: Read every answers in a topic with more than 10 answers. + welcome: + name: + other: 歡迎 + desc: + other: Received a up vote. + nice_share: + name: + other: Nice Share + desc: + other: Shared a post with 25 unique visitors. + good_share: + name: + other: Good Share + desc: + other: Shared a post with 300 unique visitors. + great_share: + name: + other: Great Share + desc: + other: Shared a post with 1000 unique visitors. + out_of_love: + name: + other: Out of Love + desc: + other: Used 50 up votes in a day. + higher_love: + name: + other: Higher Love + desc: + other: Used 50 up votes in a day 5 times. + crazy_in_love: + name: + other: Crazy in Love + desc: + other: Used 50 up votes in a day 20 times. + promoter: + name: + other: Promoter + desc: + other: Invited a user. + campaigner: + name: + other: Campaigner + desc: + other: Invited 3 basic users. + champion: + name: + other: Champion + desc: + other: Invited 5 members. + thank_you: + name: + other: 感謝 + desc: + other: Has 20 up voted posts and gave 10 up votes. + gives_back: + name: + other: Gives Back + desc: + other: Has 100 up voted posts and gave 100 up votes. + empathetic: + name: + other: Empathetic + desc: + other: Has 500 up voted posts and gave 1000 up votes. + enthusiast: + name: + other: Enthusiast + desc: + other: Visited 10 consecutive days. + aficionado: + name: + other: Aficionado + desc: + other: Visited 100 consecutive days. + devotee: + name: + other: Devotee + desc: + other: Visited 365 consecutive days. + anniversary: + name: + other: Anniversary + desc: + other: Active member for a year, posted at least once. + appreciated: + name: + other: Appreciated + desc: + other: Received 1 up vote on 20 posts. + respected: + name: + other: Respected + desc: + other: Received 2 up votes on 100 posts. + admired: + name: + other: Admired + desc: + other: Received 5 up votes on 300 posts. + solved: + name: + other: Solved + desc: + other: Have an answer be accepted. + guidance_counsellor: + name: + other: Guidance Counsellor + desc: + other: Have 10 answers be accepted. + know_it_all: + name: + other: Know-it-All + desc: + other: Have 50 answers be accepted. + solution_institution: + name: + other: Solution Institution + desc: + other: Have 150 answers be accepted. + nice_answer: + name: + other: Nice Answer + desc: + other: Answer score of 10 or more. + good_answer: + name: + other: Good Answer + desc: + other: Answer score of 25 or more. + great_answer: + name: + other: Great Answer + desc: + other: Answer score of 50 or more. + nice_question: + name: + other: Nice Question + desc: + other: Question score of 10 or more. + good_question: + name: + other: Good Question + desc: + other: Question score of 25 or more. + great_question: + name: + other: Great Question + desc: + other: Question score of 50 or more. + popular_question: + name: + other: Popular Question + desc: + other: Question with 500 views. + notable_question: + name: + other: Notable Question + desc: + other: Question with 1,000 views. + famous_question: + name: + other: Famous Question + desc: + other: Question with 5,000 views. + popular_link: + name: + other: Popular Link + desc: + other: Posted an external link with 50 clicks. + hot_link: + name: + other: Hot Link + desc: + other: Posted an external link with 300 clicks. + famous_link: + name: + other: Famous Link + desc: + other: Posted an external link with 100 clicks. + default_badge_groups: + getting_started: + name: + other: Getting Started + community: + name: + other: Community + posting: + name: + other: Posting +# The following fields are used for interface presentation(Front-end) +ui: + how_to_format: + title: 如何設定文字格式 + desc: >- +
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        + pagination: + prev: 上一頁 + next: 下一頁 + page_title: + question: 問題 + questions: 問題 + tag: 標籤 + tags: 標籤 + tag_wiki: 標籤 wiki + create_tag: Create Tag + edit_tag: 編輯標籤 + ask_a_question: Create Question + edit_question: 編輯問題 + edit_answer: 編輯回答 + search: 搜尋 + posts_containing: 包含的貼文 + settings: 設定 + notifications: 通知 + login: 登入 + sign_up: 註冊 + account_recovery: 帳號恢復 + account_activation: 帳號啟用 + confirm_email: 確認電子郵件 + account_suspended: 帳號已被停權 + admin: 後台管理 + change_email: 修改電子郵件 + install: Answer 安裝 + upgrade: Answer 升級 + maintenance: 網站維護 + users: 使用者 + oauth_callback: Processing + http_404: HTTP 錯誤 404 + http_50X: HTTP 錯誤 500 + http_403: HTTP 錯誤 403 + logout: 登出 + posts: Posts + notifications: + title: 通知 + inbox: 收件夾 + achievement: 成就 + new_alerts: New alerts + all_read: 全部標記為已讀 + show_more: 顯示更多 + someone: Someone + inbox_type: + all: 所有 + posts: Posts + invites: Invites + votes: Votes + answer: Answer + question: Question + badge_award: Badge + suspended: + title: 您的帳號已被停權 + until_time: "你的帳號被停權至{{ time }}。" + forever: 你的帳號已被永久停權。 + end: 違反了我們的社群準則。 + contact_us: Contact us + editor: + blockquote: + text: 引用 + bold: + text: 粗體 + chart: + text: 圖表 + flow_chart: 流程圖 + sequence_diagram: 時序圖 + class_diagram: 類圖 + state_diagram: 狀態圖 + entity_relationship_diagram: 實體關係圖 + user_defined_diagram: 用戶自定義圖表 + gantt_chart: 甘特圖 + pie_chart: 圓餅圖 + code: + text: 代碼示例 + add_code: 添加代碼示例 + form: + fields: + code: + label: 代碼塊 + msg: + empty: 代碼不能為空 + language: + label: 語言 + placeholder: 自動偵測 + btn_cancel: 取消 + btn_confirm: 添加 + formula: + text: 公式 + options: + inline: 內聯公式 + block: 公式塊 + heading: + text: 標題 + options: + h1: 標題 1 + h2: 標題 2 + h3: 標題 3 + h4: 標題 4 + h5: 標題 5 + h6: 標題 6 + help: + text: 幫助 + hr: + text: Horizontal rule + image: + text: 圖片 + add_image: 添加圖片 + tab_image: 上傳圖片 + form_image: + fields: + file: + label: 圖檔 + btn: 選擇圖片 + msg: + empty: 文件不能為空。 + only_image: 只能上傳圖片文件。 + max_size: File size cannot exceed {{size}} MB. + desc: + label: 圖片描述 + tab_url: 圖片地址 + form_url: + fields: + url: + label: 圖片地址 + msg: + empty: 圖片地址不能為空 + name: + label: 圖片描述 + btn_cancel: 取消 + btn_confirm: 添加 + uploading: 上傳中... + indent: + text: 增加縮排 + outdent: + text: 減少縮排 + italic: + text: 斜體 + link: + text: 超連結 + add_link: 添加超連結 + form: + fields: + url: + label: 連結 + msg: + empty: 連結不能為空。 + name: + label: 描述 + btn_cancel: 取消 + btn_confirm: 添加 + ordered_list: + text: Numbered list + unordered_list: + text: Bulleted list + table: + text: 表格 + heading: 表頭 + cell: 單元格 + file: + text: Attach files + not_supported: "Don’t support that file type. Try again with {{file_type}}." + max_size: "Attach files size cannot exceed {{size}} MB." + close_modal: + title: 關閉原因是... + btn_cancel: 取消 + btn_submit: 提交 + remark: + empty: 不能為空。 + msg: + empty: 請選擇一個原因。 + report_modal: + flag_title: 報告為... + close_title: 關閉原因是... + review_question_title: 審核問題 + review_answer_title: 審核回答 + review_comment_title: 審核評論 + btn_cancel: 取消 + btn_submit: 提交 + remark: + empty: 不能為空 + msg: + empty: 請選擇一個原因。 + not_a_url: URL format is incorrect. + url_not_match: URL origin does not match the current website. + tag_modal: + title: 創建新標籤 + form: + fields: + display_name: + label: Display name + msg: + empty: 顯示名稱不能為空。 + range: 顯示名稱不能超過 35 個字符。 + slug_name: + label: URL slug + desc: URL slug up to 35 characters. + msg: + empty: URL 固定連結不能為空。 + range: URL 固定連結不能超過 35 個字元。 + character: URL 固定連結包含非法字元。 + desc: + label: 描述 + revision: + label: Revision + edit_summary: + label: Edit summary + placeholder: >- + Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) + btn_cancel: 取消 + btn_submit: 提交 + btn_post: Post new tag + tag_info: + created_at: 創建於 + edited_at: 編輯於 + history: 歷史 + synonyms: + title: 同義詞 + text: 以下標籤等同於 + empty: 此標籤目前沒有同義詞。 + btn_add: 添加同義詞 + btn_edit: 編輯 + btn_save: 儲存 + synonyms_text: 以下標籤等同於 + delete: + title: 刪除標籤 + tip_with_posts: >- +

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        + tip_with_synonyms: >- +

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        + tip: 你確定要刪除嗎? + close: 關閉 + merge: + title: Merge tag + source_tag_title: Source tag + source_tag_description: The source tag and its associated data will be remapped to the target tag. + target_tag_title: Target tag + target_tag_description: A synonym between these two tags will be created after merging. + no_results: No tags matched + btn_submit: 送出 + btn_close: 關閉 + edit_tag: + title: 編輯標籤 + default_reason: 編輯標籤 + default_first_reason: Add tag + btn_save_edits: 儲存更改 + btn_cancel: 取消 + dates: + long_date: MM月DD日 + long_date_with_year: "YYYY年MM月DD日" + long_date_with_time: "YYYY 年 MM 月 DD 日 HH:mm" + now: 剛剛 + x_seconds_ago: "{{count}} 秒前" + x_minutes_ago: "{{count}} 分鐘前" + x_hours_ago: "{{count}} 小時前" + hour: 小時 + day: 天 + hours: hours + days: days + month: month + months: months + year: year + reaction: + heart: heart + smile: smile + frown: frown + btn_label: add or remove reactions + undo_emoji: undo {{ emoji }} reaction + react_emoji: react with {{ emoji }} + unreact_emoji: unreact with {{ emoji }} + comment: + btn_add_comment: 添加評論 + reply_to: 回復 + btn_reply: 回復 + btn_edit: 編輯 + btn_delete: 刪除 + btn_flag: 舉報 + btn_save_edits: 保存 + btn_cancel: 取消 + show_more: "{{count}} 條剩餘評論" + tip_question: >- + 通过評論询问更多问题或提出改進建議。避免在評論中回答問題。 + tip_answer: >- + 使用評論回復其他用戶或通知他們进行更改。如果你要添加新的信息,請編輯你的帖子,而不是發表評論。 + tip_vote: It adds something useful to the post + edit_answer: + title: 編輯回答 + default_reason: 編輯回答 + default_first_reason: Add answer + form: + fields: + revision: + label: 編輯歷史 + answer: + label: 回答內容 + feedback: + characters: 內容必須至少6個字元長度。 + edit_summary: + label: Edit summary + placeholder: >- + 簡單描述更改原因 (錯別字、文字表達、格式等等) + btn_save_edits: 儲存更改 + btn_cancel: 取消 + tags: + title: 標籤 + sort_buttons: + popular: 熱門 + name: 名稱 + newest: Newest + button_follow: 關注 + button_following: 已關注 + tag_label: 個問題 + search_placeholder: 通過標籤名過濾 + no_desc: 此標籤無描述。 + more: 更多 + wiki: Wiki + ask: + title: Create Question + edit_title: 編輯問題 + default_reason: 編輯問題 + default_first_reason: Create question + similar_questions: 相似的問題 + form: + fields: + revision: + label: 編輯歷史 + title: + label: 標題 + placeholder: What's your topic? Be specific. + msg: + empty: 標題不能為空 + range: 標題最多 150 個字元 + body: + label: 正文 + msg: + empty: 正文不能爲空。 + hint: + optional_body: Describe what the question is about. + minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." + tags: + label: 標籤 + msg: + empty: 標籤不能為空 + answer: + label: 回答內容 + msg: + empty: 回答內容不能為空 + edit_summary: + label: Edit summary + placeholder: >- + 簡單描述更改原因 (錯別字、文字表達、格式等等) + btn_post_question: 提出問題 + btn_save_edits: 儲存更改 + answer_question: 回答您自己的問題 + post_question&answer: 發布您的問題和答案 + tag_selector: + add_btn: 建立標籤 + create_btn: 建立新標籤 + search_tag: 搜尋標籤 + hint: Describe what your content is about, at least one tag is required. + hint_zero_tags: Describe what your content is about. + hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." + no_result: 沒有匹配的標籤 + tag_required_text: 必填標籤 (至少一個) + header: + nav: + question: 問題 + tag: 標籤 + user: 用戶 + badges: Badges + profile: 用戶主頁 + setting: 帳號設置 + logout: 登出 + admin: 後台管理 + review: 審查 + bookmark: Bookmarks + moderation: Moderation + search: + placeholder: 搜尋 + footer: + build_on: Powered by <1> Apache Answer + upload_img: + name: 更改 + loading: 讀取中... + pic_auth_code: + title: 驗證碼 + placeholder: 輸入上面的文字 + msg: + empty: 验证码不能為空 + inactive: + first: >- + 就差一步!我們寄送了一封啟用電子郵件到 {{mail}}。請按照郵件中的說明啟用您的帳戶。 + info: "如果沒有收到,請檢查您的垃圾郵件文件夾。" + another: >- + 我們向您發送了另一封啟用電子郵件,地址為 {{mail}}。它可能需要幾分鐘才能到達;請務必檢查您的垃圾郵件文件夾。 + btn_name: 重新發送啟用郵件 + change_btn_name: 更改郵箱 + msg: + empty: 不能為空 + resend_email: + url_label: Are you sure you want to resend the activation email? + url_text: You can also give the activation link above to the user. + login: + login_to_continue: 登入以繼續 + info_sign: 沒有帳戶?<1>註冊 + info_login: 已經有一個帳號?<1>登入 + agreements: 登入即表示您同意<1>隱私政策和<3>服務條款。 + forgot_pass: 忘記密碼? + name: + label: 名稱 + msg: + empty: 名稱不能為空 + range: Name must be between 2 to 30 characters in length. + character: 'Must use the character set "a-z", "0-9", " - . _"' + email: + label: 郵箱 + msg: + empty: 郵箱不能為空 + password: + label: 密碼 + msg: + empty: 密碼不能為空 + different: 兩次輸入密碼不一致 + account_forgot: + page_title: 忘記密碼 + btn_name: 向我發送恢復郵件 + send_success: >- + 如果帳號與{{mail}}相符,您應該很快就會收到一封電子郵件,說明如何重置您的密碼。 + email: + label: 郵箱 + msg: + empty: 郵箱不能為空 + change_email: + btn_cancel: 取消 + btn_update: 更新電子郵件地址 + send_success: >- + 如果帳號與{{mail}}相符,您應該很快就會收到一封電子郵件,說明如何重置您的密碼。 + email: + label: New email + msg: + empty: 郵箱不能為空 + oauth: + connect: Connect with {{ auth_name }} + remove: Remove {{ auth_name }} + oauth_bind_email: + subtitle: Add a recovery email to your account. + btn_update: Update email address + email: + label: Email + msg: + empty: Email cannot be empty. + modal_title: Email already existes. + modal_content: This email address already registered. Are you sure you want to connect to the existing account? + modal_cancel: Change email + modal_confirm: Connect to the existing account + password_reset: + page_title: 密碼重置 + btn_name: 重置我的密碼 + reset_success: >- + 你已經成功更改密碼,將返回登入頁面 + link_invalid: >- + 抱歉,此密碼重置連結已失效。也許是你已經重置過密碼了? + to_login: 前往登入頁面 + password: + label: 密碼 + msg: + empty: 密碼不能為空 + length: 密碼長度在8-32個字元之間 + different: 兩次輸入密碼不一致 + password_confirm: + label: Confirm new password + settings: + page_title: 設置 + goto_modify: Go to modify + nav: + profile: 我的資料 + notification: 通知 + account: 帳號 + interface: 界面 + profile: + heading: 個人資料 + btn_name: 保存 + display_name: + label: Display name + msg: 顯示名稱不能為空。 + msg_range: Display name must be 2-30 characters in length. + username: + label: 用戶名 + caption: 用戶之間可以通過 "@用戶名" 進行交互。 + msg: 用戶名不能為空 + msg_range: Username must be 2-30 characters in length. + character: 'Must use the character set "a-z", "0-9", "- . _"' + avatar: + label: Profile image + gravatar: 頭像 + gravatar_text: You can change image on + custom: 自定義 + custom_text: 您可以上傳您的圖片。 + default: 系統 + msg: 請上傳頭像 + bio: + label: About me + website: + label: 網站 + placeholder: "https://example.com" + msg: 網站格式不正確 + location: + label: 位置 + placeholder: "城市, 國家" + notification: + heading: 通知 + turn_on: Turn on + inbox: + label: Email notifications + description: Answers to your questions, comments, invites, and more. + all_new_question: + label: All new questions + description: Get notified of all new questions. Up to 50 questions per week. + all_new_question_for_following_tags: + label: All new questions for following tags + description: Get notified of new questions for following tags. + account: + heading: 帳號 + change_email_btn: 更改郵箱 + change_pass_btn: 更改密碼 + change_email_info: >- + 我們已經寄出一封郵件至此電子郵件地址,請遵照說明進行確認。 + email: + label: 電子郵件地址 + new_email: + label: 新電子郵件地址 + msg: 新電子郵件地址不能為空白。 + pass: + label: 目前密碼 + msg: Password cannot be empty. + password_title: 密碼 + current_pass: + label: Current password + msg: + empty: Current password cannot be empty. + length: 密碼長度必須在 8 至 32 之間 + different: 兩次輸入的密碼不匹配 + new_pass: + label: New password + pass_confirm: + label: 確認新密碼 + interface: + heading: 介面 + lang: + label: 介面語言 + text: 設定使用者介面語言,在重新整裡頁面後生效。 + my_logins: + title: 我的登入 + label: 使用這些帳號登入或註冊此網站。 + modal_title: 移除登入 + modal_content: Are you sure you want to remove this login from your account? + modal_confirm_btn: Remove + remove_success: Removed successfully + toast: + update: 更新成功 + update_password: 更改密碼成功。 + flag_success: 感謝您的標記 + forbidden_operate_self: 禁止自己操作 + review: 您的修訂將在審核通過後顯示。 + sent_success: Sent successfully + related_question: + title: Related + answers: 個回答 + linked_question: + title: Linked + description: Posts linked to + no_linked_question: No contents linked from this content. + invite_to_answer: + title: People Asked + desc: Invite people who you think might know the answer. + invite: Invite to answer + add: Add people + search: Search people + question_detail: + action: Action + created: Created + Asked: 提問於 + asked: 提問於 + update: 修改於 + Edited: Edited + edit: 最後編輯於 + commented: commented + Views: 閱讀次數 + Follow: 關注 + Following: 已關注 + follow_tip: Follow this question to receive notifications + answered: 回答於 + closed_in: 關閉於 + show_exist: 顯示現有問題。 + useful: Useful + question_useful: It is useful and clear + question_un_useful: It is unclear or not useful + question_bookmark: Bookmark this question + answer_useful: It is useful + answer_un_useful: It is not useful + answers: + title: 個回答 + score: 評分 + newest: 最新 + oldest: Oldest + btn_accept: 採納 + btn_accepted: 已被採納 + write_answer: + title: 你的回答 + edit_answer: Edit my existing answer + btn_name: 提交你的回答 + add_another_answer: 添加另一個答案 + confirm_title: 繼續回答 + continue: 繼續 + confirm_info: >- +

        您確定要添加一個新的回答嗎?

        您可以使用编辑链接来完善和改进您现有的答案。

        + empty: 回答內容不能為空。 + characters: 內容必須至少6個字元長度。 + tips: + header_1: Thanks for your answer + li1_1: Please be sure to answer the question. Provide details and share your research. + li1_2: Back up any statements you make with references or personal experience. + header_2: But avoid ... + li2_1: Asking for help, seeking clarification, or responding to other answers. + reopen: + confirm_btn: Reopen + title: 重新打開這個貼文 + content: 確定要重新打開嗎? + list: + confirm_btn: List + title: List this post + content: Are you sure you want to list? + unlist: + confirm_btn: Unlist + title: Unlist this post + content: Are you sure you want to unlist? + pin: + title: Pin this post + content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. + confirm_btn: Pin + delete: + title: 刪除此貼 + question: >- + 我們不建議刪除有回答的貼文。因為這樣做會使得後來的讀者無法從該問題中獲得幫助。

        如果刪除過多有回答的貼文,你的帳號將會被禁止提問。你確定要刪除嗎? + answer_accepted: >- +

        我們不建議刪除被採納的回答。因為這樣做會使得後來的讀者無法從該回答中獲得幫助。

        如果刪除過多被採納的貼文,你的帳號將會被禁止回答任何提問。你確定要刪除嗎? + other: 你確定要刪除? + tip_answer_deleted: 此回答已被刪除 + undelete_title: Undelete this post + undelete_desc: Are you sure you wish to undelete? + btns: + confirm: 確認 + cancel: 取消 + edit: 編輯 + save: 儲存 + delete: 刪除 + undelete: 還原 + list: 清單 + unlist: Unlist + unlisted: Unlisted + login: 登入 + signup: 註冊 + logout: 登出 + verify: 驗證 + create: 建立 + approve: 核准 + reject: 拒絕 + skip: 略過 + discard_draft: Discard draft + pinned: Pinned + all: All + question: Question + answer: Answer + comment: Comment + refresh: Refresh + resend: Resend + deactivate: Deactivate + active: Active + suspend: Suspend + unsuspend: Unsuspend + close: Close + reopen: Reopen + ok: OK + light: Light + dark: Dark + system_setting: System setting + default: Default + reset: Reset + tag: Tag + post_lowercase: post + filter: Filter + ignore: Ignore + submit: Submit + normal: Normal + closed: Closed + deleted: Deleted + deleted_permanently: Deleted permanently + pending: Pending + more: More + view: View + card: Card + compact: Compact + display_below: Display below + always_display: Always display + or: or + back_sites: Back to sites + search: + title: 搜尋結果 + keywords: 關鍵詞 + options: 選項 + follow: 追蹤 + following: 已關注 + counts: "{{count}} 個結果" + counts_loading: "... Results" + more: 更多 + sort_btns: + relevance: 相關性 + newest: 最新的 + active: 活躍的 + score: 評分 + more: 更多 + tips: + title: 高級搜尋提示 + tag: "<1>[tag] 在指定標籤中搜尋" + user: "<1>user:username 根據作者搜尋" + answer: "<1>answers:0 搜尋未回答的問題" + score: "<1>score:3 得分為 3+ 的帖子" + question: "<1>is:question 只搜尋問題" + is_answer: "<1>is:answer 只搜尋回答" + empty: 找不到任何相關的內容。
        請嘗試其他關鍵字,或者減少查找內容的長度。 + share: + name: 分享 + copy: 複製連結 + via: 分享在... + copied: 已複製 + facebook: 分享到 Facebook + twitter: Share to X + cannot_vote_for_self: You can't vote for your own post. + modal_confirm: + title: 發生錯誤... + delete_permanently: + title: Delete permanently + content: Are you sure you want to delete permanently? + account_result: + success: 你的帳號已通過驗證,即將返回首頁。 + link: 繼續訪問主頁 + oops: Oops! + invalid: The link you used no longer works. + confirm_new_email: 你的電子郵箱已更新 + confirm_new_email_invalid: >- + 抱歉,此驗證連結已失效。也許是你的郵箱已經成功更改了? + unsubscribe: + page_title: 退訂 + success_title: 取消訂閱成功 + success_desc: 您已成功從訂閱者清單中移除且不會在收到任何來自我們的郵件。 + link: 更改設置 + question: + following_tags: 已關注的標籤 + edit: 編輯 + save: 儲存 + follow_tag_tip: 按照標籤整理您的問題列表。 + hot_questions: 熱門問題 + all_questions: 全部問題 + x_questions: "{{ count }} 個問題" + x_answers: "{{ count }} 個回答" + x_posts: "{{ count }} Posts" + questions: 個問題 + answers: 回答 + newest: 最新的 + active: 活躍的 + hot: Hot + frequent: Frequent + recommend: Recommend + score: 評分 + unanswered: 未回答 + modified: 修改於 + answered: 回答於 + asked: 提問於 + closed: 已關閉 + follow_a_tag: 關注一個標籤 + more: 更多 + personal: + overview: 概覽 + answers: 回答 + answer: 回答 + questions: 問題 + question: 問題 + bookmarks: 書籤 + reputation: 聲望 + comments: 評論 + votes: 得票 + badges: Badges + newest: 最新 + score: 評分 + edit_profile: Edit profile + visited_x_days: "已造訪 {{ count }} 天" + viewed: 閱讀次數 + joined: 加入於 + comma: "," + last_login: 出現時間 + about_me: 關於我 + about_me_empty: "// 你好, 世界 !" + top_answers: 熱門回答 + top_questions: 熱門問題 + stats: 狀態 + list_empty: 沒有找到相關的內容。
        試試看其他標籤? + content_empty: No posts found. + accepted: 已採納 + answered: 回答於 + asked: 提問於 + downvoted: downvoted + mod_short: MOD + mod_long: 管理員 + x_reputation: 聲望 + x_votes: 得票 + x_answers: 個回答 + x_questions: 個問題 + recent_badges: Recent Badges + install: + title: Installation + next: 下一步 + done: 完成 + config_yaml_error: 無法建立 config.yaml 檔。 + lang: + label: Please choose a language + db_type: + label: Database engine + db_username: + label: 用戶名 + placeholder: 根 + msg: 用戶名不能為空 + db_password: + label: 密碼 + placeholder: root + msg: 密碼不能為空 + db_host: + label: Database host + placeholder: "db: 3306" + msg: Database host cannot be empty. + db_name: + label: Database name + placeholder: 回答 + msg: Database name cannot be empty. + db_file: + label: Database file + placeholder: /data/answer.db + msg: Database file cannot be empty. + ssl_enabled: + label: Enable SSL + ssl_enabled_on: + label: On + ssl_enabled_off: + label: Off + ssl_mode: + label: SSL Mode + ssl_root_cert: + placeholder: sslrootcert file path + msg: Path to sslrootcert file cannot be empty + ssl_cert: + placeholder: sslcert file path + msg: Path to sslcert file cannot be empty + ssl_key: + placeholder: sslkey file path + msg: Path to sslkey file cannot be empty + config_yaml: + title: 創建 config.yaml + label: 已創建 config.yaml 文件。 + desc: >- + 您可以手動在 <1>/var/wwww/xxx/ 目錄中創建<1>config.yaml 文件並粘貼以下文本。 + info: 完成後點擊"下一步"按鈕。 + site_information: 網站資訊 + admin_account: 管理員帳戶 + site_name: + label: Site name + msg: Site name cannot be empty. + msg_max_length: Site name must be at maximum 30 characters in length. + site_url: + label: 網站 URL + text: 此網站的地址。 + msg: + empty: 網站URL不能為空。 + incorrect: 網站URL格式不正確。 + max_length: Site URL must be at maximum 512 characters in length. + contact_email: + label: Contact email + text: 負責本網站的主要聯絡人的電子郵件地址。 + msg: + empty: Contact email cannot be empty. + incorrect: Contact email incorrect format. + login_required: + label: Private + switch: Login required + text: Only logged in users can access this community. + admin_name: + label: 暱稱 + msg: 暱稱不能為空。 + character: 'Must use the character set "a-z", "0-9", " - . _"' + msg_max_length: Name must be between 2 to 30 characters in length. + admin_password: + label: 密碼 + text: >- + 您需要此密碼才能登入。請將其儲存在一個安全的位置。 + msg: 密碼不能為空。 + msg_min_length: Password must be at least 8 characters in length. + msg_max_length: Password must be at maximum 32 characters in length. + admin_confirm_password: + label: "Confirm Password" + text: "Please re-enter your password to confirm." + msg: "Confirm password does not match." + admin_email: + label: 郵箱 + text: 您需要此電子郵件才能登入。 + msg: + empty: 郵箱不能為空。 + incorrect: 郵箱格式不正確。 + ready_title: Your site is ready + ready_desc: >- + 如果你想改變更多的設定,請瀏覽<1>管理員部分;在網站選單中找到它。 + good_luck: "玩得愉快,祝您好運!" + warn_title: 警告 + warn_desc: >- + 檔案<1>config.yaml已存在。如果您需要重置此文件中的任何配置項,請先刪除它。 + install_now: 您可以嘗試<1>現在安裝。 + installed: 已安裝 + installed_desc: >- + 您似乎已經安裝過了。要重新安裝,請先清除舊的資料庫表。 + db_failed: 資料連接異常! + db_failed_desc: >- + This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. + counts: + views: 觀看 + votes: 得票 + answers: 回答 + accepted: 已採納 + page_error: + http_error: HTTP 错误 {{ code }} + desc_403: You don't have permission to access this page. + desc_404: Unfortunately, this page doesn't exist. + desc_50X: The server encountered an error and could not complete your request. + back_home: Back to homepage + page_maintenance: + desc: "我們正在維護中,很快就會回來。" + nav_menus: + dashboard: 後台管理 + contents: 內容 + questions: 問題 + answers: 回答 + users: 使用者管理 + badges: Badges + flags: 檢舉 + settings: 設定 + general: 一般 + interface: 介面 + smtp: SMTP + branding: 品牌 + legal: 法律條款 + write: 撰寫 + terms: Terms + tos: 服務條款 + privacy: 隱私政策 + seo: SEO + customize: 自定義 + themes: 主題 + login: 登入 + privileges: Privileges + plugins: Plugins + installed_plugins: Installed Plugins + apperance: Appearance + website_welcome: Welcome to {{site_name}} + user_center: + login: Login + qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. + login_failed_email_tip: Login failed, please allow this app to access your email information before try again. + badges: + modal: + title: Congratulations + content: You've earned a new badge. + close: Close + confirm: View badges + title: Badges + awarded: Awarded + earned_×: Earned ×{{ number }} + ×_awarded: "{{ number }} awarded" + can_earn_multiple: You can earn this multiple times. + earned: Earned + admin: + admin_header: + title: 後台管理 + dashboard: + title: 後台管理 + welcome: Welcome to Admin! + site_statistics: Site statistics + questions: "問題:" + resolved: "Resolved:" + unanswered: "Unanswered:" + answers: "回答:" + comments: "評論:" + votes: "投票:" + users: "Users:" + flags: "檢舉:" + reviews: "Reviews:" + site_health: Site health + version: "版本" + https: "HTTPS:" + upload_folder: "Upload folder:" + run_mode: "Running mode:" + private: Private + public: Public + smtp: "SMTP:" + timezone: "時區:" + system_info: System info + go_version: "Go version:" + database: "Database:" + database_size: "Database size:" + storage_used: "已用儲存空間:" + uptime: "運行時間:" + links: Links + plugins: Plugins + github: GitHub + blog: Blog + contact: Contact + forum: Forum + documents: 文件 + feedback: 用戶反饋 + support: 支持 + review: 審核 + config: 配置 + update_to: 更新到 + latest: 最新版本 + check_failed: 校驗失敗 + "yes": "是" + "no": "否" + not_allowed: 不允許 + allowed: 允許 + enabled: 已啟用 + disabled: 停用 + writable: Writable + not_writable: Not writable + flags: + title: 檢舉 + pending: 等待處理 + completed: 已完成 + flagged: 已標記 + flagged_type: Flagged {{ type }} + created: 創建於 + action: 操作 + review: 審核 + user_role_modal: + title: 更改用戶狀態為... + btn_cancel: 取消 + btn_submit: 提交 + new_password_modal: + title: Set new password + form: + fields: + password: + label: Password + text: The user will be logged out and need to login again. + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + edit_profile_modal: + title: Edit profile + form: + fields: + display_name: + label: Display name + msg_range: Display name must be 2-30 characters in length. + username: + label: Username + msg_range: Username must be 2-30 characters in length. + email: + label: Email + msg_invalid: Invalid Email Address. + edit_success: Edited successfully + btn_cancel: Cancel + btn_submit: Submit + user_modal: + title: Add new user + form: + fields: + users: + label: Bulk add user + placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" + text: Separate “name, email, password” with commas. One user per line. + msg: "Please enter the user's email, one per line." + display_name: + label: Display name + msg: Display name must be 2-30 characters in length. + email: + label: Email + msg: Email is not valid. + password: + label: Password + msg: Password must be at 8-32 characters in length. + btn_cancel: Cancel + btn_submit: Submit + users: + title: 用戶 + name: 名稱 + email: 郵箱 + reputation: 聲望 + created_at: Created time + delete_at: Deleted time + suspend_at: Suspended time + suspend_until: Suspend until + status: 狀態 + role: 角色 + action: 操作 + change: 更改 + all: 全部 + staff: 工作人員 + more: More + inactive: 不活躍 + suspended: 已停權 + deleted: 已刪除 + normal: 正常 + Moderator: 版主 + Admin: 管理員 + User: 用戶 + filter: + placeholder: "按名稱篩選,用戶:id" + set_new_password: 設置新密碼 + edit_profile: Edit profile + change_status: 更改狀態 + change_role: 更改角色 + show_logs: 顯示日誌 + add_user: 新增使用者 + deactivate_user: + title: Deactivate user + content: An inactive user must re-validate their email. + delete_user: + title: Delete this user + content: Are you sure you want to delete this user? This is permanent! + remove: Remove their content + label: Remove all questions, answers, comments, etc. + text: Don’t check this if you wish to only delete the user’s account. + suspend_user: + title: Suspend this user + content: A suspended user can't log in. + label: How long will the user be suspended for? + forever: Forever + questions: + page_title: 問題 + unlisted: Unlisted + post: 標題 + votes: 得票數 + answers: 回答 + created: 創建於 + status: 狀態 + action: 操作 + change: 更改 + pending: Pending + filter: + placeholder: "按標題過濾,問題:id" + answers: + page_title: 回答 + post: 發布 + votes: 得票數 + created: 創建於 + status: 狀態 + action: 操作 + change: 更改 + filter: + placeholder: "按名稱篩選,answer:id" + general: + page_title: 一般 + name: + label: Site name + msg: 不能為空 + text: "網站的名稱,如標題標籤中所用。" + site_url: + label: 網站網址 + msg: 網站網址不能為空。 + validate: 請輸入一個有效的 URL。 + text: 此網站的網址。 + short_desc: + label: Short site description + msg: 網站簡短描述不能為空。 + text: "簡短的描述,如主頁上的標題標籤所使用的那样。" + desc: + label: Site description + msg: 網站描述不能為空。 + text: "使用一句話描述本站,作為網站的描述(Html 的 meta 標籤)。" + contact_email: + label: Contact email + msg: 聯絡人信箱不能為空。 + validate: 聯絡人信箱無效。 + text: 負責本網站的主要聯絡人的電子郵件信箱。 + check_update: + label: Software updates + text: Automatically check for updates + interface: + page_title: 介面 + language: + label: Interface language + msg: 界面語言不能為空 + text: 設置用戶界面語言,在刷新頁面后生效。 + time_zone: + label: 時區 + msg: 時區不能為空。 + text: 選擇一個與您相同時區的城市。 + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar base URL + text: URL of the Gravatar provider's API base. Ignored when empty. + smtp: + page_title: SMTP + from_email: + label: From email + msg: 發件人電子郵件不能为空。 + text: 發送郵件的郵箱地址 + from_name: + label: From name + msg: 發件人名稱不能为空。 + text: 發件人的名稱 + smtp_host: + label: SMTP host + msg: SMTP 主機名稱不能為空。 + text: 郵件服務器 + encryption: + label: 加密 + msg: 加密不能為空。 + text: 對於大多數服務器,SSL 是推薦的選項。 + ssl: SSL + tls: TLS + none: 無 + smtp_port: + label: SMTP port + msg: SMTP 埠必須在 1 ~ 65535 之間。 + text: 郵件服務器的端口號。 + smtp_username: + label: SMTP username + msg: SMTP 用戶名不能為空。 + smtp_password: + label: SMTP password + msg: SMTP 密碼不能為空。 + test_email_recipient: + label: Test email recipients + text: 提供用於接收測試郵件的郵箱地址。 + msg: 測試郵件收件人無效 + smtp_authentication: + label: 啟用身份驗證 + title: SMTP authentication + msg: SMTP 身份驗證不能為空。 + "yes": "是" + "no": "否" + branding: + page_title: 品牌 + logo: + label: 標誌 + msg: 圖標不能為空。 + text: 在你的網站左上方的Logo圖標。使用一個高度為56,長寬比大於3:1的寬長方形圖像。如果留空,將顯示網站標題文本。 + mobile_logo: + label: Mobile logo + text: 在您網站的移動版本上使用的徽標。 使用高度為 56 的寬矩形圖像。如果留空,將使用“徽標”設置中的圖像。 + square_icon: + label: Square icon + msg: 方形圖示不能為空。 + text: 用作元數據圖標的基礎的圖像。最好是大於512x512。 + favicon: + label: 網站圖示 + text: 您網站的圖標。 要在 CDN 上正常工作,它必須是 png。 將調整為 32x32的大小。 如果留空,將使用“方形圖標”。 + legal: + page_title: 法律條款 + terms_of_service: + label: Terms of service + text: "您可以在此加入服務內容的條款。如果您已經在別處托管了文檔,請在這裡提供完整的URL。" + privacy_policy: + label: Privacy policy + text: "您可以在此加入隱私政策內容。如果您已經在別處托管了文檔,請在這裡提供完整的URL。" + external_content_display: + label: External content + text: "Content includes images, videos, and media embedded from external websites." + always_display: Always display external content + ask_before_display: Ask before displaying external content + write: + page_title: 編輯 + min_content: + label: Minimum question body length + text: Minimum allowed question body length in characters. + restrict_answer: + title: Answer write + label: Each user can only write one answer for each question + text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." + min_tags: + label: "Minimum tags per question" + text: "Minimum number of tags required in a question." + recommend_tags: + label: Recommend tags + text: "Recommend tags will show in the dropdown list by default." + msg: + contain_reserved: "recommended tags cannot contain reserved tags" + required_tag: + title: Set required tags + label: Set “Recommend tags” as required tags + text: "每個新問題必須至少有一個推薦標籤。" + reserved_tags: + label: Reserved tags + text: "Reserved tags can only be used by moderator." + image_size: + label: Max image size (MB) + text: "The maximum image upload size." + attachment_size: + label: Max attachment size (MB) + text: "The maximum attachment files upload size." + image_megapixels: + label: Max image megapixels + text: "Maximum number of megapixels allowed for an image." + image_extensions: + label: Authorized image extensions + text: "A list of file extensions allowed for image display, separate with commas." + attachment_extensions: + label: Authorized attachment extensions + text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." + seo: + page_title: 搜尋引擎優化 + permalink: + label: 固定連結 + text: 自定義URL結構可以提高可用性,以及你的連結的向前相容性。 + robots: + label: robots.txt + text: 這將永久覆蓋任何相關的網站設置。 + themes: + page_title: 主題 + themes: + label: 主題 + text: 選擇一個現有主題。 + color_scheme: + label: Color scheme + navbar_style: + label: Navbar background style + primary_color: + label: 主色調 + text: 修改您主題使用的顏色 + css_and_html: + page_title: CSS 與 HTML + custom_css: + label: 自定義CSS + text: > + + head: + label: 頭部 + text: > + + header: + label: 標題 + text: > + + footer: + label: 頁尾 + text: This will insert before </body>. + sidebar: + label: Sidebar + text: This will insert in sidebar. + login: + page_title: 登入 + membership: + title: 會員 + label: 允許新註冊 + text: 關閉以防止任何人創建新帳戶。 + email_registration: + title: Email registration + label: Allow email registration + text: Turn off to prevent anyone creating new account through email. + allowed_email_domains: + title: Allowed email domains + text: Email domains that users must register accounts with. One domain per line. Ignored when empty. + private: + title: 非公開的 + label: 需要登入 + text: 只有登入使用者才能訪問這個社群。 + password_login: + title: Password login + label: Allow email and password login + text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." + installed_plugins: + title: Installed Plugins + plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. + filter: + all: All + active: Active + inactive: Inactive + outdated: Outdated + plugins: + label: Plugins + text: Select an existing plugin. + name: Name + version: Version + status: Status + action: Action + deactivate: Deactivate + activate: Activate + settings: Settings + settings_users: + title: Users + avatar: + label: Default avatar + text: For users without a custom avatar of their own. + gravatar_base_url: + label: Gravatar 基礎網址 + text: URL of the Gravatar provider's API base. Ignored when empty. + profile_editable: + title: Profile editable + allow_update_display_name: + label: Allow users to change their display name + allow_update_username: + label: Allow users to change their username + allow_update_avatar: + label: Allow users to change their profile image + allow_update_bio: + label: Allow users to change their about me + allow_update_website: + label: Allow users to change their website + allow_update_location: + label: Allow users to change their location + privilege: + title: Privileges + level: + label: Reputation required level + text: Choose the reputation required for the privileges + msg: + should_be_number: the input should be number + number_larger_1: number should be equal or larger than 1 + badges: + action: Action + active: Active + activate: Activate + all: All + awards: Awards + deactivate: Deactivate + filter: + placeholder: Filter by name, badge:id + group: Group + inactive: Inactive + name: Name + show_logs: Show logs + status: Status + title: Badges + form: + optional: (選填) + empty: 不能為空 + invalid: 是無效的 + btn_submit: 儲存 + not_found_props: "所需屬性 {{ key }} 未找到。" + select: Select + page_review: + review: 審核 + proposed: 提案 + question_edit: 問題編輯 + answer_edit: 回答編輯 + tag_edit: '標籤管理: 編輯標籤' + edit_summary: 編輯摘要 + edit_question: 編輯問題 + edit_answer: 編輯回答 + edit_tag: 編輯標籤 + empty: 沒有剩餘的審核任務。 + approve_revision_tip: Do you approve this revision? + approve_flag_tip: Do you approve this flag? + approve_post_tip: Do you approve this post? + approve_user_tip: Do you approve this user? + suggest_edits: Suggested edits + flag_post: Flag post + flag_user: Flag user + queued_post: Queued post + queued_user: Queued user + filter_label: Type + reputation: reputation + flag_post_type: Flagged this post as {{ type }}. + flag_user_type: Flagged this user as {{ type }}. + edit_post: Edit post + list_post: List post + unlist_post: Unlist post + timeline: + undeleted: 未刪除的 + deleted: 刪除 + downvote: 反對 + upvote: 贊同 + accept: 採納 + cancelled: 已取消 + commented: '評論:' + rollback: 回滾 + edited: 最後編輯於 + answered: 回答於 + asked: 提問於 + closed: 關閉 + reopened: 重新開啟 + created: 創建於 + pin: pinned + unpin: unpinned + show: listed + hide: unlisted + title: "歷史記錄" + tag_title: "時間線" + show_votes: "顯示投票" + n_or_a: N/A + title_for_question: "時間線" + title_for_answer: "{{ title }} 的 {{ author }} 回答時間線" + title_for_tag: "標籤的時間線" + datetime: 日期時間 + type: 類型 + by: 由 + comment: 評論 + no_data: "我們找不到任何東西。" + users: + title: 用戶 + users_with_the_most_reputation: Users with the highest reputation scores this week + users_with_the_most_vote: Users who voted the most this week + staffs: 我們的社區工作人員 + reputation: 聲望值 + votes: 選票 + prompt: + leave_page: 你確定要離開此頁面? + changes_not_save: 你所做的變更可能不會儲存。 + draft: + discard_confirm: Are you sure you want to discard your draft? + messages: + post_deleted: This post has been deleted. + post_cancel_deleted: This post has been undeleted. + post_pin: This post has been pinned. + post_unpin: This post has been unpinned. + post_hide_list: This post has been hidden from list. + post_show_list: This post has been shown to list. + post_reopen: This post has been reopened. + post_list: This post has been listed. + post_unlist: This post has been unlisted. + post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. + post_closed: This post has been closed. + answer_deleted: This answer has been deleted. + answer_cancel_deleted: This answer has been undeleted. + change_user_role: This user's role has been changed. + user_inactive: This user is already inactive. + user_normal: This user is already normal. + user_suspended: This user has been suspended. + user_deleted: This user has been deleted. + badge_activated: This badge has been activated. + badge_inactivated: This badge has been inactivated. + users_deleted: These users have been deleted. + posts_deleted: These questions have been deleted. + answers_deleted: These answers have been deleted. + copy: Copy to clipboard + copied: Copied + external_content_warning: External images/media are not displayed. + + diff --git a/go.mod b/go.mod index 969d9ebbc..52d64c738 100644 --- a/go.mod +++ b/go.mod @@ -117,6 +117,7 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/joho/godotenv v1.5.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect diff --git a/go.sum b/go.sum index 35db004db..69d97751e 100644 --- a/go.sum +++ b/go.sum @@ -354,6 +354,8 @@ github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg= github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= From d773b8690608ca7dbcf8ef28d5f69a1f889f058d Mon Sep 17 00:00:00 2001 From: maishivamhoo123 Date: Thu, 25 Dec 2025 10:01:25 +0530 Subject: [PATCH 52/92] fix: remove unrelated generated files --- data/conf/config.yaml | 25 - data/i18n/af_ZA.yaml | 1384 ----------------------- data/i18n/ar_SA.yaml | 1384 ----------------------- data/i18n/az_AZ.yaml | 1371 ----------------------- data/i18n/bal_BA.yaml | 1371 ----------------------- data/i18n/ban_ID.yaml | 1371 ----------------------- data/i18n/bn_BD.yaml | 1371 ----------------------- data/i18n/bs_BA.yaml | 1371 ----------------------- data/i18n/ca_ES.yaml | 1384 ----------------------- data/i18n/cs_CZ.yaml | 2359 ---------------------------------------- data/i18n/cy_GB.yaml | 2359 ---------------------------------------- data/i18n/da_DK.yaml | 2359 ---------------------------------------- data/i18n/de_DE.yaml | 2359 ---------------------------------------- data/i18n/el_GR.yaml | 1384 ----------------------- data/i18n/en_US.yaml | 2395 ---------------------------------------- data/i18n/es_ES.yaml | 2359 ---------------------------------------- data/i18n/fa_IR.yaml | 2359 ---------------------------------------- data/i18n/fi_FI.yaml | 1384 ----------------------- data/i18n/fr_FR.yaml | 2359 ---------------------------------------- data/i18n/he_IL.yaml | 1384 ----------------------- data/i18n/hi_IN.yaml | 2359 ---------------------------------------- data/i18n/hu_HU.yaml | 1384 ----------------------- data/i18n/hy_AM.yaml | 1371 ----------------------- data/i18n/i18n.yaml | 64 -- data/i18n/id_ID.yaml | 2359 ---------------------------------------- data/i18n/it_IT.yaml | 2359 ---------------------------------------- data/i18n/ja_JP.yaml | 2360 ---------------------------------------- data/i18n/ko_KR.yaml | 2359 ---------------------------------------- data/i18n/ml_IN.yaml | 2359 ---------------------------------------- data/i18n/nl_NL.yaml | 1384 ----------------------- data/i18n/no_NO.yaml | 1385 ----------------------- data/i18n/pl_PL.yaml | 2414 ----------------------------------------- data/i18n/pt_BR.yaml | 1381 ----------------------- data/i18n/pt_PT.yaml | 2359 ---------------------------------------- data/i18n/ro_RO.yaml | 2359 ---------------------------------------- data/i18n/ru_RU.yaml | 2360 ---------------------------------------- data/i18n/sk_SK.yaml | 2359 ---------------------------------------- data/i18n/sq_AL.yaml | 1371 ----------------------- data/i18n/sr_SP.yaml | 1384 ----------------------- data/i18n/sv_SE.yaml | 2359 ---------------------------------------- data/i18n/te_IN.yaml | 2359 ---------------------------------------- data/i18n/tr_TR.yaml | 2359 ---------------------------------------- data/i18n/uk_UA.yaml | 2359 ---------------------------------------- data/i18n/vi_VN.yaml | 2359 ---------------------------------------- data/i18n/zh_CN.yaml | 2359 ---------------------------------------- data/i18n/zh_TW.yaml | 2359 ---------------------------------------- 46 files changed, 86335 deletions(-) delete mode 100644 data/conf/config.yaml delete mode 100644 data/i18n/af_ZA.yaml delete mode 100644 data/i18n/ar_SA.yaml delete mode 100644 data/i18n/az_AZ.yaml delete mode 100644 data/i18n/bal_BA.yaml delete mode 100644 data/i18n/ban_ID.yaml delete mode 100644 data/i18n/bn_BD.yaml delete mode 100644 data/i18n/bs_BA.yaml delete mode 100644 data/i18n/ca_ES.yaml delete mode 100644 data/i18n/cs_CZ.yaml delete mode 100644 data/i18n/cy_GB.yaml delete mode 100644 data/i18n/da_DK.yaml delete mode 100644 data/i18n/de_DE.yaml delete mode 100644 data/i18n/el_GR.yaml delete mode 100644 data/i18n/en_US.yaml delete mode 100644 data/i18n/es_ES.yaml delete mode 100644 data/i18n/fa_IR.yaml delete mode 100644 data/i18n/fi_FI.yaml delete mode 100644 data/i18n/fr_FR.yaml delete mode 100644 data/i18n/he_IL.yaml delete mode 100644 data/i18n/hi_IN.yaml delete mode 100644 data/i18n/hu_HU.yaml delete mode 100644 data/i18n/hy_AM.yaml delete mode 100644 data/i18n/i18n.yaml delete mode 100644 data/i18n/id_ID.yaml delete mode 100644 data/i18n/it_IT.yaml delete mode 100644 data/i18n/ja_JP.yaml delete mode 100644 data/i18n/ko_KR.yaml delete mode 100644 data/i18n/ml_IN.yaml delete mode 100644 data/i18n/nl_NL.yaml delete mode 100644 data/i18n/no_NO.yaml delete mode 100644 data/i18n/pl_PL.yaml delete mode 100644 data/i18n/pt_BR.yaml delete mode 100644 data/i18n/pt_PT.yaml delete mode 100644 data/i18n/ro_RO.yaml delete mode 100644 data/i18n/ru_RU.yaml delete mode 100644 data/i18n/sk_SK.yaml delete mode 100644 data/i18n/sq_AL.yaml delete mode 100644 data/i18n/sr_SP.yaml delete mode 100644 data/i18n/sv_SE.yaml delete mode 100644 data/i18n/te_IN.yaml delete mode 100644 data/i18n/tr_TR.yaml delete mode 100644 data/i18n/uk_UA.yaml delete mode 100644 data/i18n/vi_VN.yaml delete mode 100644 data/i18n/zh_CN.yaml delete mode 100644 data/i18n/zh_TW.yaml diff --git a/data/conf/config.yaml b/data/conf/config.yaml deleted file mode 100644 index 6419bb538..000000000 --- a/data/conf/config.yaml +++ /dev/null @@ -1,25 +0,0 @@ -debug: false -server: - http: - addr: 0.0.0.0:80 -data: - database: - driver: sqlite3 - connection: ./data/answer.db - cache: - file_path: data/cache/cache.db -i18n: - bundle_dir: data/i18n -service_config: - upload_path: data/uploads - clean_up_uploads: true - clean_orphan_uploads_period_hours: 48 - purge_deleted_files_period_days: 30 -swaggerui: - show: true - protocol: http - host: 127.0.0.1 - address: :80 -ui: - base_url: "" - api_base_url: "" diff --git a/data/i18n/af_ZA.yaml b/data/i18n/af_ZA.yaml deleted file mode 100644 index 0121bde1a..000000000 --- a/data/i18n/af_ZA.yaml +++ /dev/null @@ -1,1384 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: Success. - unknown: - other: Unknown error. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - email: - other: Email - password: - other: Password - email_or_password_wrong_error: - other: Email and password do not match. - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - question: - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - rank: - fail_to_meet_the_condition: - other: Rank fail to meet the condition. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend Tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - smtp: - config_from_name_cannot_be_email: - other: The From Name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to Revision. - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - report: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude: - name: - other: rude or abusive - desc: - other: A reasonable person would find this content inappropriate for respectful discourse. - duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - not_answer: - name: - other: not an answer - desc: - other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. - not_need: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - other: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comments - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to {{site_name}} - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to {{site_name}} - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as <link> - head: - label: Head - text: This will insert before </head> - header: - label: Header - text: This will insert after <body> - footer: - label: Footer - text: This will insert before </body>. - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/ar_SA.yaml b/data/i18n/ar_SA.yaml deleted file mode 100644 index 25c086f11..000000000 --- a/data/i18n/ar_SA.yaml +++ /dev/null @@ -1,1384 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: Success. - unknown: - other: Unknown error. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - email: - other: Email - password: - other: Password - email_or_password_wrong_error: - other: Email and password do not match. - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - question: - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - rank: - fail_to_meet_the_condition: - other: Rank fail to meet the condition. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend Tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - smtp: - config_from_name_cannot_be_email: - other: The From Name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to Revision. - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - report: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude: - name: - other: rude or abusive - desc: - other: A reasonable person would find this content inappropriate for respectful discourse. - duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - not_answer: - name: - other: not an answer - desc: - other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. - not_need: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - other: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comments - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to {{site_name}} - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to {{site_name}} - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/az_AZ.yaml b/data/i18n/az_AZ.yaml deleted file mode 100644 index 4249c5f03..000000000 --- a/data/i18n/az_AZ.yaml +++ /dev/null @@ -1,1371 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: "Success." - unknown: - other: "Unknown error." - request_format_error: - other: "Request format is not valid." - unauthorized_error: - other: "Unauthorized." - database_error: - other: "Data server error." - role: - name: - user: - other: "User" - admin: - other: "Admin" - moderator: - other: "Moderator" - description: - user: - other: "Default with no special access." - admin: - other: "Have the full power to access the site." - moderator: - other: "Has access to all posts except admin settings." - email: - other: "Email" - password: - other: "Password" - email_or_password_wrong_error: - other: "Email and password do not match." - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: "Answer do not found." - cannot_deleted: - other: "No permission to delete." - cannot_update: - other: "No permission to update." - comment: - edit_without_permission: - other: "Comment are not allowed to edit." - not_found: - other: "Comment not found." - email: - duplicate: - other: "Email already exists." - need_to_be_verified: - other: "Email should be verified." - verify_url_expired: - other: "Email verified URL has expired, please resend the email." - lang: - not_found: - other: "Language file not found." - object: - captcha_verification_failed: - other: "Captcha wrong." - disallow_follow: - other: "You are not allowed to follow." - disallow_vote: - other: "You are not allowed to vote." - disallow_vote_your_self: - other: "You can't vote for your own post." - not_found: - other: "Object not found." - verification_failed: - other: "Verification failed." - email_or_password_incorrect: - other: "Email and password do not match." - old_password_verification_failed: - other: "The old password verification failed" - new_password_same_as_previous_setting: - other: "The new password is the same as the previous one." - question: - not_found: - other: "Question not found." - cannot_deleted: - other: "No permission to delete." - cannot_close: - other: "No permission to close." - cannot_update: - other: "No permission to update." - rank: - fail_to_meet_the_condition: - other: "Rank fail to meet the condition." - report: - handle_failed: - other: "Report handle failed." - not_found: - other: "Report not found." - tag: - not_found: - other: "Tag not found." - recommend_tag_not_found: - other: "Recommend Tag is not exist." - recommend_tag_enter: - other: "Please enter at least one required tag." - not_contain_synonym_tags: - other: "Should not contain synonym tags." - cannot_update: - other: "No permission to update." - cannot_set_synonym_as_itself: - other: "You cannot set the synonym of the current tag as itself." - smtp: - config_from_name_cannot_be_email: - other: "The From Name cannot be a email address." - theme: - not_found: - other: "Theme not found." - revision: - review_underway: - other: "Can't edit currently, there is a version in the review queue." - no_permission: - other: "No permission to Revision." - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: "User not found." - suspended: - other: "User has been suspended." - username_invalid: - other: "Username is invalid." - username_duplicate: - other: "Username is already in use." - set_avatar: - other: "Avatar set failed." - cannot_update_your_role: - other: "You cannot modify your role." - not_allowed_registration: - other: "Currently the site is not open for registration" - config: - read_config_failed: - other: "Read config failed" - database: - connection_failed: - other: "Database connection failed" - create_table_failed: - other: "Create table failed" - install: - create_config_failed: - other: "Can't create the config.yaml file." - report: - spam: - name: - other: "spam" - desc: - other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." - rude: - name: - other: "rude or abusive" - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - duplicate: - name: - other: "a duplicate" - desc: - other: "This question has been asked before and already has an answer." - not_answer: - name: - other: "not an answer" - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." - not_need: - name: - other: "no longer needed" - desc: - other: "This comment is outdated, conversational or not relevant to this post." - other: - name: - other: "something else" - desc: - other: "This post requires staff attention for another reason not listed above." - question: - close: - duplicate: - name: - other: "spam" - desc: - other: "This question has been asked before and already has an answer." - guideline: - name: - other: "a community-specific reason" - desc: - other: "This question doesn't meet a community guideline." - multiple: - name: - other: "needs details or clarity" - desc: - other: "This question currently includes multiple questions in one. It should focus on one problem only." - other: - name: - other: "something else" - desc: - other: "This post requires another reason not listed above." - operation_type: - asked: - other: "asked" - answered: - other: "answered" - modified: - other: "modified" - notification: - action: - update_question: - other: "updated question" - answer_the_question: - other: "answered question" - update_answer: - other: "updated answer" - accept_answer: - other: "accepted answer" - comment_question: - other: "commented question" - comment_answer: - other: "commented answer" - reply_to_you: - other: "replied to you" - mention_you: - other: "mentioned you" - your_question_is_closed: - other: "Your question has been closed" - your_question_was_deleted: - other: "Your question has been deleted" - your_answer_was_deleted: - other: "Your answer has been deleted" - your_comment_was_deleted: - other: "Your comment has been deleted" -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comment - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to Answer - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name up to 30 characters - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username up to 30 characters - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to Answer - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: "After you've done that, click “Next” button." - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: display_name must be at 2 - 30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/bal_BA.yaml b/data/i18n/bal_BA.yaml deleted file mode 100644 index 4249c5f03..000000000 --- a/data/i18n/bal_BA.yaml +++ /dev/null @@ -1,1371 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: "Success." - unknown: - other: "Unknown error." - request_format_error: - other: "Request format is not valid." - unauthorized_error: - other: "Unauthorized." - database_error: - other: "Data server error." - role: - name: - user: - other: "User" - admin: - other: "Admin" - moderator: - other: "Moderator" - description: - user: - other: "Default with no special access." - admin: - other: "Have the full power to access the site." - moderator: - other: "Has access to all posts except admin settings." - email: - other: "Email" - password: - other: "Password" - email_or_password_wrong_error: - other: "Email and password do not match." - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: "Answer do not found." - cannot_deleted: - other: "No permission to delete." - cannot_update: - other: "No permission to update." - comment: - edit_without_permission: - other: "Comment are not allowed to edit." - not_found: - other: "Comment not found." - email: - duplicate: - other: "Email already exists." - need_to_be_verified: - other: "Email should be verified." - verify_url_expired: - other: "Email verified URL has expired, please resend the email." - lang: - not_found: - other: "Language file not found." - object: - captcha_verification_failed: - other: "Captcha wrong." - disallow_follow: - other: "You are not allowed to follow." - disallow_vote: - other: "You are not allowed to vote." - disallow_vote_your_self: - other: "You can't vote for your own post." - not_found: - other: "Object not found." - verification_failed: - other: "Verification failed." - email_or_password_incorrect: - other: "Email and password do not match." - old_password_verification_failed: - other: "The old password verification failed" - new_password_same_as_previous_setting: - other: "The new password is the same as the previous one." - question: - not_found: - other: "Question not found." - cannot_deleted: - other: "No permission to delete." - cannot_close: - other: "No permission to close." - cannot_update: - other: "No permission to update." - rank: - fail_to_meet_the_condition: - other: "Rank fail to meet the condition." - report: - handle_failed: - other: "Report handle failed." - not_found: - other: "Report not found." - tag: - not_found: - other: "Tag not found." - recommend_tag_not_found: - other: "Recommend Tag is not exist." - recommend_tag_enter: - other: "Please enter at least one required tag." - not_contain_synonym_tags: - other: "Should not contain synonym tags." - cannot_update: - other: "No permission to update." - cannot_set_synonym_as_itself: - other: "You cannot set the synonym of the current tag as itself." - smtp: - config_from_name_cannot_be_email: - other: "The From Name cannot be a email address." - theme: - not_found: - other: "Theme not found." - revision: - review_underway: - other: "Can't edit currently, there is a version in the review queue." - no_permission: - other: "No permission to Revision." - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: "User not found." - suspended: - other: "User has been suspended." - username_invalid: - other: "Username is invalid." - username_duplicate: - other: "Username is already in use." - set_avatar: - other: "Avatar set failed." - cannot_update_your_role: - other: "You cannot modify your role." - not_allowed_registration: - other: "Currently the site is not open for registration" - config: - read_config_failed: - other: "Read config failed" - database: - connection_failed: - other: "Database connection failed" - create_table_failed: - other: "Create table failed" - install: - create_config_failed: - other: "Can't create the config.yaml file." - report: - spam: - name: - other: "spam" - desc: - other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." - rude: - name: - other: "rude or abusive" - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - duplicate: - name: - other: "a duplicate" - desc: - other: "This question has been asked before and already has an answer." - not_answer: - name: - other: "not an answer" - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." - not_need: - name: - other: "no longer needed" - desc: - other: "This comment is outdated, conversational or not relevant to this post." - other: - name: - other: "something else" - desc: - other: "This post requires staff attention for another reason not listed above." - question: - close: - duplicate: - name: - other: "spam" - desc: - other: "This question has been asked before and already has an answer." - guideline: - name: - other: "a community-specific reason" - desc: - other: "This question doesn't meet a community guideline." - multiple: - name: - other: "needs details or clarity" - desc: - other: "This question currently includes multiple questions in one. It should focus on one problem only." - other: - name: - other: "something else" - desc: - other: "This post requires another reason not listed above." - operation_type: - asked: - other: "asked" - answered: - other: "answered" - modified: - other: "modified" - notification: - action: - update_question: - other: "updated question" - answer_the_question: - other: "answered question" - update_answer: - other: "updated answer" - accept_answer: - other: "accepted answer" - comment_question: - other: "commented question" - comment_answer: - other: "commented answer" - reply_to_you: - other: "replied to you" - mention_you: - other: "mentioned you" - your_question_is_closed: - other: "Your question has been closed" - your_question_was_deleted: - other: "Your question has been deleted" - your_answer_was_deleted: - other: "Your answer has been deleted" - your_comment_was_deleted: - other: "Your comment has been deleted" -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comment - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to Answer - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name up to 30 characters - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username up to 30 characters - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to Answer - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: "After you've done that, click “Next” button." - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: display_name must be at 2 - 30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/ban_ID.yaml b/data/i18n/ban_ID.yaml deleted file mode 100644 index 4249c5f03..000000000 --- a/data/i18n/ban_ID.yaml +++ /dev/null @@ -1,1371 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: "Success." - unknown: - other: "Unknown error." - request_format_error: - other: "Request format is not valid." - unauthorized_error: - other: "Unauthorized." - database_error: - other: "Data server error." - role: - name: - user: - other: "User" - admin: - other: "Admin" - moderator: - other: "Moderator" - description: - user: - other: "Default with no special access." - admin: - other: "Have the full power to access the site." - moderator: - other: "Has access to all posts except admin settings." - email: - other: "Email" - password: - other: "Password" - email_or_password_wrong_error: - other: "Email and password do not match." - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: "Answer do not found." - cannot_deleted: - other: "No permission to delete." - cannot_update: - other: "No permission to update." - comment: - edit_without_permission: - other: "Comment are not allowed to edit." - not_found: - other: "Comment not found." - email: - duplicate: - other: "Email already exists." - need_to_be_verified: - other: "Email should be verified." - verify_url_expired: - other: "Email verified URL has expired, please resend the email." - lang: - not_found: - other: "Language file not found." - object: - captcha_verification_failed: - other: "Captcha wrong." - disallow_follow: - other: "You are not allowed to follow." - disallow_vote: - other: "You are not allowed to vote." - disallow_vote_your_self: - other: "You can't vote for your own post." - not_found: - other: "Object not found." - verification_failed: - other: "Verification failed." - email_or_password_incorrect: - other: "Email and password do not match." - old_password_verification_failed: - other: "The old password verification failed" - new_password_same_as_previous_setting: - other: "The new password is the same as the previous one." - question: - not_found: - other: "Question not found." - cannot_deleted: - other: "No permission to delete." - cannot_close: - other: "No permission to close." - cannot_update: - other: "No permission to update." - rank: - fail_to_meet_the_condition: - other: "Rank fail to meet the condition." - report: - handle_failed: - other: "Report handle failed." - not_found: - other: "Report not found." - tag: - not_found: - other: "Tag not found." - recommend_tag_not_found: - other: "Recommend Tag is not exist." - recommend_tag_enter: - other: "Please enter at least one required tag." - not_contain_synonym_tags: - other: "Should not contain synonym tags." - cannot_update: - other: "No permission to update." - cannot_set_synonym_as_itself: - other: "You cannot set the synonym of the current tag as itself." - smtp: - config_from_name_cannot_be_email: - other: "The From Name cannot be a email address." - theme: - not_found: - other: "Theme not found." - revision: - review_underway: - other: "Can't edit currently, there is a version in the review queue." - no_permission: - other: "No permission to Revision." - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: "User not found." - suspended: - other: "User has been suspended." - username_invalid: - other: "Username is invalid." - username_duplicate: - other: "Username is already in use." - set_avatar: - other: "Avatar set failed." - cannot_update_your_role: - other: "You cannot modify your role." - not_allowed_registration: - other: "Currently the site is not open for registration" - config: - read_config_failed: - other: "Read config failed" - database: - connection_failed: - other: "Database connection failed" - create_table_failed: - other: "Create table failed" - install: - create_config_failed: - other: "Can't create the config.yaml file." - report: - spam: - name: - other: "spam" - desc: - other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." - rude: - name: - other: "rude or abusive" - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - duplicate: - name: - other: "a duplicate" - desc: - other: "This question has been asked before and already has an answer." - not_answer: - name: - other: "not an answer" - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." - not_need: - name: - other: "no longer needed" - desc: - other: "This comment is outdated, conversational or not relevant to this post." - other: - name: - other: "something else" - desc: - other: "This post requires staff attention for another reason not listed above." - question: - close: - duplicate: - name: - other: "spam" - desc: - other: "This question has been asked before and already has an answer." - guideline: - name: - other: "a community-specific reason" - desc: - other: "This question doesn't meet a community guideline." - multiple: - name: - other: "needs details or clarity" - desc: - other: "This question currently includes multiple questions in one. It should focus on one problem only." - other: - name: - other: "something else" - desc: - other: "This post requires another reason not listed above." - operation_type: - asked: - other: "asked" - answered: - other: "answered" - modified: - other: "modified" - notification: - action: - update_question: - other: "updated question" - answer_the_question: - other: "answered question" - update_answer: - other: "updated answer" - accept_answer: - other: "accepted answer" - comment_question: - other: "commented question" - comment_answer: - other: "commented answer" - reply_to_you: - other: "replied to you" - mention_you: - other: "mentioned you" - your_question_is_closed: - other: "Your question has been closed" - your_question_was_deleted: - other: "Your question has been deleted" - your_answer_was_deleted: - other: "Your answer has been deleted" - your_comment_was_deleted: - other: "Your comment has been deleted" -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comment - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to Answer - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name up to 30 characters - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username up to 30 characters - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to Answer - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: "After you've done that, click “Next” button." - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: display_name must be at 2 - 30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/bn_BD.yaml b/data/i18n/bn_BD.yaml deleted file mode 100644 index 4249c5f03..000000000 --- a/data/i18n/bn_BD.yaml +++ /dev/null @@ -1,1371 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: "Success." - unknown: - other: "Unknown error." - request_format_error: - other: "Request format is not valid." - unauthorized_error: - other: "Unauthorized." - database_error: - other: "Data server error." - role: - name: - user: - other: "User" - admin: - other: "Admin" - moderator: - other: "Moderator" - description: - user: - other: "Default with no special access." - admin: - other: "Have the full power to access the site." - moderator: - other: "Has access to all posts except admin settings." - email: - other: "Email" - password: - other: "Password" - email_or_password_wrong_error: - other: "Email and password do not match." - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: "Answer do not found." - cannot_deleted: - other: "No permission to delete." - cannot_update: - other: "No permission to update." - comment: - edit_without_permission: - other: "Comment are not allowed to edit." - not_found: - other: "Comment not found." - email: - duplicate: - other: "Email already exists." - need_to_be_verified: - other: "Email should be verified." - verify_url_expired: - other: "Email verified URL has expired, please resend the email." - lang: - not_found: - other: "Language file not found." - object: - captcha_verification_failed: - other: "Captcha wrong." - disallow_follow: - other: "You are not allowed to follow." - disallow_vote: - other: "You are not allowed to vote." - disallow_vote_your_self: - other: "You can't vote for your own post." - not_found: - other: "Object not found." - verification_failed: - other: "Verification failed." - email_or_password_incorrect: - other: "Email and password do not match." - old_password_verification_failed: - other: "The old password verification failed" - new_password_same_as_previous_setting: - other: "The new password is the same as the previous one." - question: - not_found: - other: "Question not found." - cannot_deleted: - other: "No permission to delete." - cannot_close: - other: "No permission to close." - cannot_update: - other: "No permission to update." - rank: - fail_to_meet_the_condition: - other: "Rank fail to meet the condition." - report: - handle_failed: - other: "Report handle failed." - not_found: - other: "Report not found." - tag: - not_found: - other: "Tag not found." - recommend_tag_not_found: - other: "Recommend Tag is not exist." - recommend_tag_enter: - other: "Please enter at least one required tag." - not_contain_synonym_tags: - other: "Should not contain synonym tags." - cannot_update: - other: "No permission to update." - cannot_set_synonym_as_itself: - other: "You cannot set the synonym of the current tag as itself." - smtp: - config_from_name_cannot_be_email: - other: "The From Name cannot be a email address." - theme: - not_found: - other: "Theme not found." - revision: - review_underway: - other: "Can't edit currently, there is a version in the review queue." - no_permission: - other: "No permission to Revision." - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: "User not found." - suspended: - other: "User has been suspended." - username_invalid: - other: "Username is invalid." - username_duplicate: - other: "Username is already in use." - set_avatar: - other: "Avatar set failed." - cannot_update_your_role: - other: "You cannot modify your role." - not_allowed_registration: - other: "Currently the site is not open for registration" - config: - read_config_failed: - other: "Read config failed" - database: - connection_failed: - other: "Database connection failed" - create_table_failed: - other: "Create table failed" - install: - create_config_failed: - other: "Can't create the config.yaml file." - report: - spam: - name: - other: "spam" - desc: - other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." - rude: - name: - other: "rude or abusive" - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - duplicate: - name: - other: "a duplicate" - desc: - other: "This question has been asked before and already has an answer." - not_answer: - name: - other: "not an answer" - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." - not_need: - name: - other: "no longer needed" - desc: - other: "This comment is outdated, conversational or not relevant to this post." - other: - name: - other: "something else" - desc: - other: "This post requires staff attention for another reason not listed above." - question: - close: - duplicate: - name: - other: "spam" - desc: - other: "This question has been asked before and already has an answer." - guideline: - name: - other: "a community-specific reason" - desc: - other: "This question doesn't meet a community guideline." - multiple: - name: - other: "needs details or clarity" - desc: - other: "This question currently includes multiple questions in one. It should focus on one problem only." - other: - name: - other: "something else" - desc: - other: "This post requires another reason not listed above." - operation_type: - asked: - other: "asked" - answered: - other: "answered" - modified: - other: "modified" - notification: - action: - update_question: - other: "updated question" - answer_the_question: - other: "answered question" - update_answer: - other: "updated answer" - accept_answer: - other: "accepted answer" - comment_question: - other: "commented question" - comment_answer: - other: "commented answer" - reply_to_you: - other: "replied to you" - mention_you: - other: "mentioned you" - your_question_is_closed: - other: "Your question has been closed" - your_question_was_deleted: - other: "Your question has been deleted" - your_answer_was_deleted: - other: "Your answer has been deleted" - your_comment_was_deleted: - other: "Your comment has been deleted" -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comment - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to Answer - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name up to 30 characters - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username up to 30 characters - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to Answer - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: "After you've done that, click “Next” button." - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: display_name must be at 2 - 30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/bs_BA.yaml b/data/i18n/bs_BA.yaml deleted file mode 100644 index 4249c5f03..000000000 --- a/data/i18n/bs_BA.yaml +++ /dev/null @@ -1,1371 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: "Success." - unknown: - other: "Unknown error." - request_format_error: - other: "Request format is not valid." - unauthorized_error: - other: "Unauthorized." - database_error: - other: "Data server error." - role: - name: - user: - other: "User" - admin: - other: "Admin" - moderator: - other: "Moderator" - description: - user: - other: "Default with no special access." - admin: - other: "Have the full power to access the site." - moderator: - other: "Has access to all posts except admin settings." - email: - other: "Email" - password: - other: "Password" - email_or_password_wrong_error: - other: "Email and password do not match." - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: "Answer do not found." - cannot_deleted: - other: "No permission to delete." - cannot_update: - other: "No permission to update." - comment: - edit_without_permission: - other: "Comment are not allowed to edit." - not_found: - other: "Comment not found." - email: - duplicate: - other: "Email already exists." - need_to_be_verified: - other: "Email should be verified." - verify_url_expired: - other: "Email verified URL has expired, please resend the email." - lang: - not_found: - other: "Language file not found." - object: - captcha_verification_failed: - other: "Captcha wrong." - disallow_follow: - other: "You are not allowed to follow." - disallow_vote: - other: "You are not allowed to vote." - disallow_vote_your_self: - other: "You can't vote for your own post." - not_found: - other: "Object not found." - verification_failed: - other: "Verification failed." - email_or_password_incorrect: - other: "Email and password do not match." - old_password_verification_failed: - other: "The old password verification failed" - new_password_same_as_previous_setting: - other: "The new password is the same as the previous one." - question: - not_found: - other: "Question not found." - cannot_deleted: - other: "No permission to delete." - cannot_close: - other: "No permission to close." - cannot_update: - other: "No permission to update." - rank: - fail_to_meet_the_condition: - other: "Rank fail to meet the condition." - report: - handle_failed: - other: "Report handle failed." - not_found: - other: "Report not found." - tag: - not_found: - other: "Tag not found." - recommend_tag_not_found: - other: "Recommend Tag is not exist." - recommend_tag_enter: - other: "Please enter at least one required tag." - not_contain_synonym_tags: - other: "Should not contain synonym tags." - cannot_update: - other: "No permission to update." - cannot_set_synonym_as_itself: - other: "You cannot set the synonym of the current tag as itself." - smtp: - config_from_name_cannot_be_email: - other: "The From Name cannot be a email address." - theme: - not_found: - other: "Theme not found." - revision: - review_underway: - other: "Can't edit currently, there is a version in the review queue." - no_permission: - other: "No permission to Revision." - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: "User not found." - suspended: - other: "User has been suspended." - username_invalid: - other: "Username is invalid." - username_duplicate: - other: "Username is already in use." - set_avatar: - other: "Avatar set failed." - cannot_update_your_role: - other: "You cannot modify your role." - not_allowed_registration: - other: "Currently the site is not open for registration" - config: - read_config_failed: - other: "Read config failed" - database: - connection_failed: - other: "Database connection failed" - create_table_failed: - other: "Create table failed" - install: - create_config_failed: - other: "Can't create the config.yaml file." - report: - spam: - name: - other: "spam" - desc: - other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." - rude: - name: - other: "rude or abusive" - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - duplicate: - name: - other: "a duplicate" - desc: - other: "This question has been asked before and already has an answer." - not_answer: - name: - other: "not an answer" - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." - not_need: - name: - other: "no longer needed" - desc: - other: "This comment is outdated, conversational or not relevant to this post." - other: - name: - other: "something else" - desc: - other: "This post requires staff attention for another reason not listed above." - question: - close: - duplicate: - name: - other: "spam" - desc: - other: "This question has been asked before and already has an answer." - guideline: - name: - other: "a community-specific reason" - desc: - other: "This question doesn't meet a community guideline." - multiple: - name: - other: "needs details or clarity" - desc: - other: "This question currently includes multiple questions in one. It should focus on one problem only." - other: - name: - other: "something else" - desc: - other: "This post requires another reason not listed above." - operation_type: - asked: - other: "asked" - answered: - other: "answered" - modified: - other: "modified" - notification: - action: - update_question: - other: "updated question" - answer_the_question: - other: "answered question" - update_answer: - other: "updated answer" - accept_answer: - other: "accepted answer" - comment_question: - other: "commented question" - comment_answer: - other: "commented answer" - reply_to_you: - other: "replied to you" - mention_you: - other: "mentioned you" - your_question_is_closed: - other: "Your question has been closed" - your_question_was_deleted: - other: "Your question has been deleted" - your_answer_was_deleted: - other: "Your answer has been deleted" - your_comment_was_deleted: - other: "Your comment has been deleted" -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comment - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to Answer - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name up to 30 characters - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username up to 30 characters - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to Answer - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: "After you've done that, click “Next” button." - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: display_name must be at 2 - 30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/ca_ES.yaml b/data/i18n/ca_ES.yaml deleted file mode 100644 index 25c086f11..000000000 --- a/data/i18n/ca_ES.yaml +++ /dev/null @@ -1,1384 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: Success. - unknown: - other: Unknown error. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - email: - other: Email - password: - other: Password - email_or_password_wrong_error: - other: Email and password do not match. - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - question: - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - rank: - fail_to_meet_the_condition: - other: Rank fail to meet the condition. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend Tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - smtp: - config_from_name_cannot_be_email: - other: The From Name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to Revision. - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - report: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude: - name: - other: rude or abusive - desc: - other: A reasonable person would find this content inappropriate for respectful discourse. - duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - not_answer: - name: - other: not an answer - desc: - other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. - not_need: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - other: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comments - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to {{site_name}} - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to {{site_name}} - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/cs_CZ.yaml b/data/i18n/cs_CZ.yaml deleted file mode 100644 index dbb217faf..000000000 --- a/data/i18n/cs_CZ.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Úspěch. - unknown: - other: Neznámá chyba. - request_format_error: - other: Formát požadavku není platný. - unauthorized_error: - other: Neautorizováno. - database_error: - other: Chyba datového serveru. - forbidden_error: - other: Zakázáno. - duplicate_request_error: - other: Duplicitní odeslání. - action: - report: - other: Nahlásit - edit: - other: Upravit - delete: - other: Smazat - close: - other: Zavřít - reopen: - other: Znovu otevřít - forbidden_error: - other: Zakázáno. - pin: - other: Připnout - hide: - other: Skrýt - unpin: - other: Odepnout - show: - other: Zobrazit - invite_someone_to_answer: - other: Upravit - undelete: - other: Obnovit - merge: - other: Sloučit - role: - name: - user: - other: Uživatel - admin: - other: Administrátor - moderator: - other: Moderátor - description: - user: - other: Výchozí bez zvláštního přístupu. - admin: - other: Má plnou kontrolu nad stránkou. - moderator: - other: Má přístup ke všem příspěvkům kromě admin nastavení. - privilege: - level_1: - description: - other: Úroveň 1 (méně reputace je vyžadováno pro soukromý tým, skupinu) - level_2: - description: - other: Úroveň 2 (nízká reputace je vyžadována pro startovací komunitu) - level_3: - description: - other: Úroveň 3 (vysoká reputace je vyžadována pro vyspělou komunitu) - level_custom: - description: - other: Vlastní úroveň - rank_question_add_label: - other: Položit dotaz - rank_answer_add_label: - other: Napsat odpověď - rank_comment_add_label: - other: Napsat komentář - rank_report_add_label: - other: Nahlásit - rank_comment_vote_up_label: - other: Hlasovat pro komentář - rank_link_url_limit_label: - other: Zveřejnit více než 2 odkazy najednou - rank_question_vote_up_label: - other: Hlasovat pro dotaz - rank_answer_vote_up_label: - other: Hlasovat pro odpověď - rank_question_vote_down_label: - other: Hlasovat proti otázce - rank_answer_vote_down_label: - other: Hlasovat proti odpovědi - rank_invite_someone_to_answer_label: - other: Pozvěte někoho, aby odpověděl - rank_tag_add_label: - other: Vytvořit nový štítek - rank_tag_edit_label: - other: Upravit popis štítku (vyžaduje kontrolu) - rank_question_edit_label: - other: Upravit dotaz někoho jiného (vyžaduje kontrolu) - rank_answer_edit_label: - other: Upravit odpověď někoho jiného (vyžaduje kontrolu) - rank_question_edit_without_review_label: - other: Upravit dotaz někoho jiného (bez kontroly) - rank_answer_edit_without_review_label: - other: Upravit odpověď někoho jiného (bez kontroly) - rank_question_audit_label: - other: Zkontrolovat úpravy dotazu - rank_answer_audit_label: - other: Zkontrolovat úpravy odpovědí - rank_tag_audit_label: - other: Zkontrolovat úpravy štítků - rank_tag_edit_without_review_label: - other: Upravit popis štítku (bez kontroly) - rank_tag_synonym_label: - other: Správa synonym štítků - email: - other: Email - e_mail: - other: Email - password: - other: Heslo - pass: - other: Heslo - old_pass: - other: Current password - original_text: - other: Tento příspěvek - email_or_password_wrong_error: - other: Email a heslo nesouhlasí. - error: - common: - invalid_url: - other: Neplatná URL. - status_invalid: - other: Neplatný stav. - password: - space_invalid: - other: Heslo nesmí obsahovat mezery. - admin: - cannot_update_their_password: - other: Nemůžete změnit své heslo. - cannot_edit_their_profile: - other: Nemůžete upravovat svůj profil. - cannot_modify_self_status: - other: Nemůžete změnit svůj stav. - email_or_password_wrong: - other: Email a heslo nesouhlasí. - answer: - not_found: - other: Odpověď nebyla nalezena. - cannot_deleted: - other: Nemáte právo mazat. - cannot_update: - other: Nemáte právo aktualizovat. - question_closed_cannot_add: - other: Dotazy jsou uzavřené a není možno je přidávat. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Nejsou povoleny úpravy komentáře. - not_found: - other: Komentář nebyl nalezen. - cannot_edit_after_deadline: - other: Tento komentář byl pro úpravy příliš dlouhý. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: Email už existuje. - need_to_be_verified: - other: Email musí být ověřen. - verify_url_expired: - other: Platnost ověřovacího URL vypršela, pošlete si ověřovací email znovu. - illegal_email_domain_error: - other: Email z této domény není povolen. Použijte jinou doménu. - lang: - not_found: - other: Jazykový soubor nenalezen. - object: - captcha_verification_failed: - other: Nesprávně vyplněná Captcha. - disallow_follow: - other: Nemáte oprávnění sledovat. - disallow_vote: - other: Nemáte oprávnění hlasovat. - disallow_vote_your_self: - other: Nemůžete hlasovat pro svůj vlastní příspěvek. - not_found: - other: Objekt nenalezen. - verification_failed: - other: Ověření se nezdařilo. - email_or_password_incorrect: - other: Email a heslo nesouhlasí. - old_password_verification_failed: - other: Ověření starého hesla selhalo - new_password_same_as_previous_setting: - other: Nové heslo je stejné jako předchozí. - already_deleted: - other: Tento příspěvek byl odstraněn. - meta: - object_not_found: - other: Meta objekt nenalezen - question: - already_deleted: - other: Tento příspěvek byl odstraněn. - under_review: - other: Váš příspěvek čeká na kontrolu. Bude viditelný po jeho schválení. - not_found: - other: Dotaz nenalezen. - cannot_deleted: - other: Nemáte oprávnění k mazání. - cannot_close: - other: Nemáte oprávnění k uzavření. - cannot_update: - other: Nemáte oprávnění pro aktualizaci. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Hodnost reputace nesplňuje podmínku. - vote_fail_to_meet_the_condition: - other: Děkujeme za zpětnou vazbu. Potřebujete alespoň úroveň {{.Rank}}, abyste mohli hlasovat. - no_enough_rank_to_operate: - other: Potřebujete alespoň úroveň {{.Rank}} k provedení této akce. - report: - handle_failed: - other: Report selhal. - not_found: - other: Report nebyl nalezen. - tag: - already_exist: - other: Štítek již existuje. - not_found: - other: Štítek nebyl nalezen. - recommend_tag_not_found: - other: Doporučený štítek nebyl nalezen. - recommend_tag_enter: - other: Zadejte prosím alespoň jeden povinný štítek. - not_contain_synonym_tags: - other: Nemělo by obsahovat synonyma štítků. - cannot_update: - other: Nemáte oprávnění pro aktualizaci. - is_used_cannot_delete: - other: Nemůžete odstranit štítek, který se používá. - cannot_set_synonym_as_itself: - other: Aktuální štítek nelze jako synonymum stejného štítku. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: Jméno odesílatele nemůže být emailová adresa. - theme: - not_found: - other: Motiv nebyl nalezen. - revision: - review_underway: - other: V současné době nelze upravit, čeká na kontrolu. - no_permission: - other: Nemáte oprávnění k revizi. - user: - external_login_missing_user_id: - other: Platforma třetí strany neposkytuje unikátní UserID, takže se nemůžete přihlásit, kontaktujte prosím správce webových stránek. - external_login_unbinding_forbidden: - other: Před odebráním tohoto typu přihlášení nastavte přihlašovací heslo pro svůj účet. - email_or_password_wrong: - other: - other: Email a heslo nesouhlasí. - not_found: - other: Uživatel nebyl nalezen. - suspended: - other: Uživatelský účet byl pozastaven. - username_invalid: - other: Uživatelské jméno je neplatné. - username_duplicate: - other: Uživatelské jméno je již použito. - set_avatar: - other: Nastavení avataru se nezdařilo. - cannot_update_your_role: - other: Nemůžete upravovat svoji roli. - not_allowed_registration: - other: Registrace nejsou povolené. - not_allowed_login_via_password: - other: Přihlášení přes heslo není povolené. - access_denied: - other: Přístup zamítnut - page_access_denied: - other: Nemáte přístup k této stránce. - add_bulk_users_format_error: - other: "Chyba formátu pole {{.Field}} poblíž '{{.Content}}' na řádku {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "Počet uživatelů, které přidáte najednou, by měl být v rozsahu 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Načtení konfigurace selhalo - database: - connection_failed: - other: Spojení s databází selhalo - create_table_failed: - other: Vytvoření tabulky selhalo - install: - create_config_failed: - other: Soubor config.yaml nelze vytvořit. - upload: - unsupported_file_format: - other: Nepodporovaný formát souboru. - site_info: - config_not_found: - other: Konfigurace webu nebyla nalezena. - badge: - object_not_found: - other: Objekt odznaku nebyl nalezen - reason: - spam: - name: - other: spam - desc: - other: Tento příspěvek je reklama nebo vandalismus. Není užitečný ani relevantní pro aktuální téma. - rude_or_abusive: - name: - other: hrubý nebo zneužívající - desc: - other: "Rozumný člověk by tento obsah považoval za nevhodný pro slušnou konverzaci." - a_duplicate: - name: - other: duplicita - desc: - other: Tento dotaz byl položen dříve a již má odpověď. - placeholder: - other: Zadejte existující odkaz na dotaz - not_a_answer: - name: - other: není odpověď - desc: - other: "Toto bylo zveřejněno jako odpověď, ale nesnaží se odpovědět na dotaz. Měla by to být úprava, komentář, nebo úplně jiný dotaz." - no_longer_needed: - name: - other: již není potřeba - desc: - other: Tento komentář je zastaralý, konverzační nebo není relevantní pro tento příspěvek. - something: - name: - other: jiný důvod - desc: - other: Tento příspěvek vyžaduje pozornost moderátorů z jiného důvodu, který není uveden výše. - placeholder: - other: Dejte nám vědět konkrétně, v čem je problém - community_specific: - name: - other: důvod specifický pro komunitu - desc: - other: Tento dotaz nesplňuje pravidla komunity. - not_clarity: - name: - other: vyžaduje detaily nebo upřesnění - desc: - other: Tento dotaz v současné době obsahuje více otázek. Měl by se zaměřit pouze na jeden problém. - looks_ok: - name: - other: vypadá v pořádku - desc: - other: Tento příspěvek je dobrý tak jak je, nemá nízkou kvalitu. - needs_edit: - name: - other: potřebuje úpravu, kterou jsem udělal(a) - desc: - other: Zlepšete a opravte problémy s tímto příspěvkem. - needs_close: - name: - other: potřebuje zavřít - desc: - other: Na uzavřený dotaz není možné odpovídat, ale stále může být upraven a je možné pro něj hlasovat a komentovat jej. - needs_delete: - name: - other: potřebuje smazat - desc: - other: Tento příspěvek bude odstraněn. - question: - close: - duplicate: - name: - other: spam - desc: - other: Tento dotaz byl položena dříve a již má odpověď. - guideline: - name: - other: důvod specifický pro komunitu - desc: - other: Tento dotaz nesplňuje pravidla komunity. - multiple: - name: - other: vyžaduje detaily nebo upřesnění - desc: - other: Tento dotaz v současné době obsahuje více otázek. Měla by se zaměřit pouze na jeden problém. - other: - name: - other: jiný důvod - desc: - other: Tento příspěvek vyžaduje pozornost moderátorů z jiného důvodu, který není uveden výše. - operation_type: - asked: - other: dotázáno - answered: - other: zodpovězeno - modified: - other: upraveno - deleted_title: - other: Smazat dotaz - questions_title: - other: Dotazy - tag: - tags_title: - other: Štítky - no_description: - other: Štítek nemá žádný popis. - notification: - action: - update_question: - other: upravený dotaz - answer_the_question: - other: položil(a) dotaz - update_answer: - other: upravil(a) odpověď - accept_answer: - other: přijal(a) odpověď - comment_question: - other: okomentoval(a) dotaz - comment_answer: - other: okomentoval(a) odpověď - reply_to_you: - other: vám odpověděl(a) - mention_you: - other: vás zmínil(a) - your_question_is_closed: - other: Váš dotaz byl uzavřen - your_question_was_deleted: - other: Váš dotaz byl odstraněn - your_answer_was_deleted: - other: Vaše odpověď byla smazána - your_comment_was_deleted: - other: Váš komentář byl odstraněn - up_voted_question: - other: hlasoval(a) pro dotaz - down_voted_question: - other: hlasoval(a) proti dotazu - up_voted_answer: - other: hlasoval(a) pro odpověď - down_voted_answer: - other: hlasoval(a) proti odpovědi - up_voted_comment: - other: hlasoval(a) pro komentář - invited_you_to_answer: - other: vás pozval, abyste odpověděl(a) - earned_badge: - other: Získali jste odznak "{{.BadgeName}}" - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Potvrďte svůj nový email" - body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} odpověděl(a) na váš dotaz" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_question: - title: - other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Obnova hesla" - body: - other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - register: - title: - other: "[{{.SiteName}}] Potvrďte svůj nový účet" - body: - other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - test: - title: - other: "[{{.SiteName}}] Zkušební email" - body: - other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: - upvote: - other: hlasovat pro - upvoted: - other: hlasováno pro - downvote: - other: hlasovat proti - downvoted: - other: hlasováno proti - accept: - other: přijmout - accepted: - other: přijato - edit: - other: upravit - review: - queued_post: - other: Příspěvek ve frontě - flagged_post: - other: Nahlášený příspěvek - suggested_post_edit: - other: Navrhované úpravy - reaction: - tooltip: - other: "{{ .Names }} a {{ .Count }} dalších..." - badge: - default_badges: - autobiographer: - name: - other: Životopisec - desc: - other: Profil vyplněn. - certified: - name: - other: Certifikovaný - desc: - other: Tutoriál pro nové uživatele dokončen. - editor: - name: - other: Editor - desc: - other: První úprava příspěvku. - first_flag: - name: - other: První nahlášení - desc: - other: První nahlášení příspěvku. - first_upvote: - name: - other: První hlas pro - desc: - other: První hlas pro příspěvek. - first_link: - name: - other: První odkaz - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: První sdílení - desc: - other: První sdílení příspěvku. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Napište 5 komentářů. - new_user_of_the_month: - name: - other: Nový uživatel měsíce - desc: - other: Výjimečný přínos ve svém prvním měsíci na stránce. - read_guidelines: - name: - other: Přečíst pravidla - desc: - other: Přečtěte si [pravidla komunity]. - reader: - name: - other: Čtenář - desc: - other: Přečtěte si všechny odpovědi v tématu s více než 10 odpověďmi. - welcome: - name: - other: Vítejte - desc: - other: Obdržel(a) hlas. - nice_share: - name: - other: Povedené sdílení - desc: - other: Sdílel(a) příspěvek s 25 unikátními návštěvníky. - good_share: - name: - other: Dobré sdílení - desc: - other: Sdílel(a) příspěvek s 300 unikátními návštěvníky. - great_share: - name: - other: Skvělé sdílení - desc: - other: Sdílel(a) příspěvek s 1000 unikátními návštěvníky. - out_of_love: - name: - other: Optimista - desc: - other: Využito 50 hlasů pro za den. - higher_love: - name: - other: Vytrvalý optimista - desc: - other: 5 krát využito 50 hlasů pro za den. - crazy_in_love: - name: - other: Bláznivý optimista - desc: - other: 20 krát využito 50 hlasů pro za den. - promoter: - name: - other: Promotér - desc: - other: Pozval(a) uživatele. - campaigner: - name: - other: Campaigner - desc: - other: Pozval(a) 3 uživatele. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: Thank You - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Active member for a year, posted at least once. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - create_tag: Create Tag - edit_tag: Edit Tag - ask_a_question: Create Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - oauth_callback: Processing - http_404: HTTP Error 404 - http_50X: HTTP Error 500 - http_403: HTTP Error 403 - logout: Log Out - posts: Posts - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - new_alerts: New alerts - all_read: Mark all as read - show_more: Show more - someone: Someone - inbox_type: - all: All - posts: Posts - invites: Invites - votes: Votes - answer: Answer - question: Question - badge_award: Badge - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - contact_us: Contact us - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image file - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed {{size}} MB. - desc: - label: Description - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered list - unordered_list: - text: Bulleted list - table: - text: Table - heading: Heading - cell: Cell - file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - not_a_url: URL format is incorrect. - url_not_match: URL origin does not match the current website. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description - revision: - label: Revision - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_cancel: Cancel - btn_submit: Submit - btn_post: Post new tag - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - tip_with_posts: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - tip_with_synonyms: >- -

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        - tip: Are you sure you wish to delete? - close: Close - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - default_first_reason: Add tag - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - hours: hours - days: days - month: month - months: months - year: year - reaction: - heart: heart - smile: smile - frown: frown - btn_label: add or remove reactions - undo_emoji: undo {{ emoji }} reaction - react_emoji: react with {{ emoji }} - unreact_emoji: unreact with {{ emoji }} - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: "{{count}} more comments" - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - tip_vote: It adds something useful to the post - edit_answer: - title: Edit Answer - default_reason: Edit answer - default_first_reason: Add answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: Newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - wiki: Wiki - ask: - title: Create Question - edit_title: Edit Question - default_reason: Edit question - default_first_reason: Create question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: What's your topic? Be specific. - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - badges: Badges - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - bookmark: Bookmarks - moderation: Moderation - search: - placeholder: Search - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - resend_email: - url_label: Are you sure you want to resend the activation email? - url_text: You can also give the activation link above to the user. - login: - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New email - msg: - empty: Email cannot be empty. - oauth: - connect: Connect with {{ auth_name }} - remove: Remove {{ auth_name }} - oauth_bind_email: - subtitle: Add a recovery email to your account. - btn_update: Update email address - email: - label: Email - msg: - empty: Email cannot be empty. - modal_title: Email already existes. - modal_content: This email address already registered. Are you sure you want to connect to the existing account? - modal_cancel: Change email - modal_confirm: Connect to the existing account - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm new password - settings: - page_title: Settings - goto_modify: Go to modify - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile image - gravatar: Gravatar - gravatar_text: You can change image on - custom: Custom - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About me - website: - label: Website - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location - placeholder: "City, Country" - notification: - heading: Email Notifications - turn_on: Turn on - inbox: - label: Inbox notifications - description: Answers to your questions, comments, invites, and more. - all_new_question: - label: All new questions - description: Get notified of all new questions. Up to 50 questions per week. - all_new_question_for_following_tags: - label: All new questions for following tags - description: Get notified of new questions for following tags. - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - pass: - label: Current password - msg: Password cannot be empty. - password_title: Password - current_pass: - label: Current password - msg: - empty: Current password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New password - pass_confirm: - label: Confirm new password - interface: - heading: Interface - lang: - label: Interface language - text: User interface language. It will change when you refresh the page. - my_logins: - title: My logins - label: Log in or sign up on this site using these accounts. - modal_title: Remove login - modal_content: Are you sure you want to remove this login from your account? - modal_confirm_btn: Remove - remove_success: Removed successfully - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - sent_success: Sent successfully - related_question: - title: Related - answers: answers - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Pozvěte další uživatele - desc: Pozvěte lidi, o kterých si myslíte, že mohou odpovědět. - invite: Invite to answer - add: Add people - search: Search people - question_detail: - action: Action - created: Created - Asked: Asked - asked: asked - update: Modified - Edited: Edited - edit: edited - commented: commented - Views: Viewed - Follow: Follow - Following: Following - follow_tip: Follow this question to receive notifications - answered: answered - closed_in: Closed in - show_exist: Show existing question. - useful: Useful - question_useful: It is useful and clear - question_un_useful: It is unclear or not useful - question_bookmark: Bookmark this question - answer_useful: It is useful - answer_un_useful: It is not useful - answers: - title: Answers - score: Score - newest: Newest - oldest: Oldest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - edit_answer: Edit my existing answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - tips: - header_1: Thanks for your answer - li1_1: Please be sure to answer the question. Provide details and share your research. - li1_2: Back up any statements you make with references or personal experience. - header_2: But avoid ... - li2_1: Asking for help, seeking clarification, or responding to other answers. - reopen: - confirm_btn: Reopen - title: Reopen this post - content: Are you sure you want to reopen? - list: - confirm_btn: List - title: List this post - content: Are you sure you want to list? - unlist: - confirm_btn: Unlist - title: Unlist this post - content: Are you sure you want to unlist? - pin: - title: Pin this post - content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. - confirm_btn: Pin - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_answer_deleted: This answer has been deleted - undelete_title: Undelete this post - undelete_desc: Are you sure you wish to undelete? - btns: - confirm: Confirm - cancel: Cancel - edit: Edit - save: Save - delete: Delete - undelete: Undelete - list: List - unlist: Unlist - unlisted: Unlisted - login: Log in - signup: Sign up - logout: Log out - verify: Verify - create: Create - approve: Approve - reject: Reject - skip: Skip - discard_draft: Discard draft - pinned: Pinned - all: All - question: Question - answer: Answer - comment: Comment - refresh: Refresh - resend: Resend - deactivate: Deactivate - active: Active - suspend: Suspend - unsuspend: Unsuspend - close: Close - reopen: Reopen - ok: OK - light: Light - dark: Dark - system_setting: System setting - default: Default - reset: Reset - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignore - submit: Submit - normal: Normal - closed: Closed - deleted: Deleted - deleted_permanently: Deleted permanently - pending: Pending - more: More - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - counts_loading: "... Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post. - modal_confirm: - title: Error... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - x_posts: "{{ count }} Posts" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - frequent: Frequent - recommend: Recommend - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - badges: Badges - newest: Newest - score: Score - edit_profile: Edit profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - comma: "," - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - content_empty: No posts found. - accepted: Accepted - answered: answered - asked: asked - downvoted: downvoted - mod_short: MOD - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - recent_badges: Recent Badges - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please choose a language - db_type: - label: Database engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database host - placeholder: "db:3306" - msg: Database host cannot be empty. - db_name: - label: Database name - placeholder: answer - msg: Database name cannot be empty. - db_file: - label: Database file - placeholder: /data/answer.db - msg: Database file cannot be empty. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site name - msg: Site name cannot be empty. - msg_max_length: Site name must be at maximum 30 characters in length. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - max_length: Site URL must be at maximum 512 characters in length. - contact_email: - label: Contact email - text: Email address of key contact responsible for this site. - msg: - empty: Contact email cannot be empty. - incorrect: Contact email incorrect format. - login_required: - label: Private - switch: Login required - text: Only logged in users can access this community. - admin_name: - label: Name - msg: Name cannot be empty. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - msg_min_length: Password must be at least 8 characters in length. - msg_max_length: Password must be at maximum 32 characters in length. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_error: - http_error: HTTP Error {{ code }} - desc_403: You don't have permission to access this page. - desc_404: Unfortunately, this page doesn't exist. - desc_50X: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - badges: Badges - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - terms: Terms - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - login: Login - privileges: Privileges - plugins: Plugins - installed_plugins: Installed Plugins - apperance: Appearance - website_welcome: Welcome to {{site_name}} - user_center: - login: Login - qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. - login_failed_email_tip: Login failed, please allow this app to access your email information before try again. - badges: - modal: - title: Congratulations - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site statistics - questions: "Questions:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - users: "Users:" - flags: "Flags:" - reviews: "Reviews:" - site_health: Site health - version: "Version:" - https: "HTTPS:" - upload_folder: "Upload folder:" - run_mode: "Running mode:" - private: Private - public: Public - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System info - go_version: "Go version:" - database: "Database:" - database_size: "Database size:" - storage_used: "Storage used:" - uptime: "Uptime:" - links: Links - plugins: Plugins - github: GitHub - blog: Blog - contact: Contact - forum: Forum - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - writable: Writable - not_writable: Not writable - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - flagged_type: Flagged {{ type }} - created: Created - action: Action - review: Review - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - edit_profile_modal: - title: Edit profile - form: - fields: - display_name: - label: Display name - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Invalid Email Address. - edit_success: Edited successfully - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - users: - label: Bulk add user - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separate “name, email, password” with commas. One user per line. - msg: "Please enter the user's email, one per line." - display_name: - label: Display name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - more: More - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - edit_profile: Edit profile - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - deactivate_user: - title: Deactivate user - content: An inactive user must re-validate their email. - delete_user: - title: Delete this user - content: Are you sure you want to delete this user? This is permanent! - remove: Remove their content - label: Remove all questions, answers, comments, etc. - text: Don’t check this if you wish to only delete the user’s account. - suspend_user: - title: Suspend this user - content: A suspended user can't log in. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Questions - unlisted: Unlisted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - pending: Pending - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short site description - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site description - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - check_update: - label: Software updates - text: Automatically check for updates - interface: - page_title: Interface - language: - label: Interface language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: From email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - tls: TLS - none: None - smtp_port: - label: SMTP port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test email recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile logo - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square icon - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Write - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Každý uživatel může napsat pouze jednu odpověď na stejný dotaz - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Recommend tags - text: "Recommend tags will show in the dropdown list by default." - msg: - contain_reserved: "recommended tags cannot contain reserved tags" - required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved tags - text: "Reserved tags can only be used by moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - color_scheme: - label: Color scheme - navbar_style: - label: Navbar background style - primary_color: - label: Primary color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: > - - head: - label: Head - text: > - - header: - label: Header - text: > - - footer: - label: Footer - text: This will insert before </body>. - sidebar: - label: Sidebar - text: This will insert in sidebar. - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - email_registration: - title: Email registration - label: Allow email registration - text: Turn off to prevent anyone creating new account through email. - allowed_email_domains: - title: Allowed email domains - text: Email domains that users must register accounts with. One domain per line. Ignored when empty. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - password_login: - title: Password login - label: Allow email and password login - text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." - installed_plugins: - title: Installed Plugins - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. - filter: - all: All - active: Active - inactive: Inactive - outdated: Outdated - plugins: - label: Plugins - text: Select an existing plugin. - name: Name - version: Version - status: Status - action: Action - deactivate: Deactivate - activate: Activate - settings: Settings - settings_users: - title: Users - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: URL základny Gravatar - text: URL of the Gravatar provider's API base. Ignored when empty. - profile_editable: - title: Profile editable - allow_update_display_name: - label: Allow users to change their display name - allow_update_username: - label: Allow users to change their username - allow_update_avatar: - label: Allow users to change their profile image - allow_update_bio: - label: Allow users to change their about me - allow_update_website: - label: Allow users to change their website - allow_update_location: - label: Allow users to change their location - privilege: - title: Privileges - level: - label: Reputation required level - text: Choose the reputation required for the privileges - msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 - badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate - filter: - placeholder: Filter by name, badge:id - group: Group - inactive: Inactive - name: Name - show_logs: Show logs - status: Status - title: Badges - form: - optional: (optional) - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - select: Select - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - approve_revision_tip: Do you approve this revision? - approve_flag_tip: Do you approve this flag? - approve_post_tip: Do you approve this post? - approve_user_tip: Do you approve this user? - suggest_edits: Suggested edits - flag_post: Flag post - flag_user: Flag user - queued_post: Queued post - queued_user: Queued user - filter_label: Type - reputation: reputation - flag_post_type: Flagged this post as {{ type }}. - flag_user_type: Flagged this user as {{ type }}. - edit_post: Edit post - list_post: List post - unlist_post: Unlist post - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - pin: pinned - unpin: unpinned - show: listed - hide: unlisted - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores this week - users_with_the_most_vote: Users who voted the most this week - staffs: Our community staff - reputation: reputation - votes: votes - prompt: - leave_page: Are you sure you want to leave the page? - changes_not_save: Your changes may not be saved. - draft: - discard_confirm: Are you sure you want to discard your draft? - messages: - post_deleted: This post has been deleted. - post_cancel_deleted: This post has been undeleted. - post_pin: This post has been pinned. - post_unpin: This post has been unpinned. - post_hide_list: This post has been hidden from list. - post_show_list: This post has been shown to list. - post_reopen: This post has been reopened. - post_list: This post has been listed. - post_unlist: This post has been unlisted. - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/cy_GB.yaml b/data/i18n/cy_GB.yaml deleted file mode 100644 index 6f27a61f5..000000000 --- a/data/i18n/cy_GB.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Llwyddiant. - unknown: - other: Gwall anhysbys. - request_format_error: - other: Nid yw fformat y cais yn ddilys. - unauthorized_error: - other: Anawdurdodedig. - database_error: - other: Gwall gweinydd data. - forbidden_error: - other: Forbidden. - duplicate_request_error: - other: Duplicate submission. - action: - report: - other: Tynnu sylw - edit: - other: Golygu - delete: - other: Dileu - close: - other: Cau - reopen: - other: Ailagor - forbidden_error: - other: Forbidden. - pin: - other: Pinio - hide: - other: Dad-restru - unpin: - other: Dadbinio - show: - other: Rhestr - invite_someone_to_answer: - other: Edit - undelete: - other: Undelete - merge: - other: Merge - role: - name: - user: - other: Defnyddiwr - admin: - other: Gweinyddwr - moderator: - other: Cymedrolwr - description: - user: - other: Diofyn heb unrhyw fynediad arbennig. - admin: - other: Bod â'r pŵer llawn i gael mynediad i'r safle. - moderator: - other: Mae ganddo fynediad i bob post ac eithrio gosodiadau gweinyddol. - privilege: - level_1: - description: - other: Level 1 (less reputation required for private team, group) - level_2: - description: - other: Level 2 (low reputation required for startup community) - level_3: - description: - other: Level 3 (high reputation required for mature community) - level_custom: - description: - other: Custom Level - rank_question_add_label: - other: Ask question - rank_answer_add_label: - other: Write answer - rank_comment_add_label: - other: Write comment - rank_report_add_label: - other: Flag - rank_comment_vote_up_label: - other: Upvote comment - rank_link_url_limit_label: - other: Post more than 2 links at a time - rank_question_vote_up_label: - other: Upvote question - rank_answer_vote_up_label: - other: Upvote answer - rank_question_vote_down_label: - other: Downvote question - rank_answer_vote_down_label: - other: Downvote answer - rank_invite_someone_to_answer_label: - other: Invite someone to answer - rank_tag_add_label: - other: Create new tag - rank_tag_edit_label: - other: Edit tag description (need to review) - rank_question_edit_label: - other: Edit other's question (need to review) - rank_answer_edit_label: - other: Edit other's answer (need to review) - rank_question_edit_without_review_label: - other: Edit other's question without review - rank_answer_edit_without_review_label: - other: Edit other's answer without review - rank_question_audit_label: - other: Review question edits - rank_answer_audit_label: - other: Review answer edits - rank_tag_audit_label: - other: Review tag edits - rank_tag_edit_without_review_label: - other: Edit tag description without review - rank_tag_synonym_label: - other: Manage tag synonyms - email: - other: Ebost - e_mail: - other: Email - password: - other: Cyfrinair - pass: - other: Password - old_pass: - other: Current password - original_text: - other: This post - email_or_password_wrong_error: - other: Nid yw e-bost a chyfrinair yn cyfateb. - error: - common: - invalid_url: - other: Invalid URL. - status_invalid: - other: Invalid status. - password: - space_invalid: - other: Password cannot contain spaces. - admin: - cannot_update_their_password: - other: Ni allwch addasu eich cyfrinair. - cannot_edit_their_profile: - other: You cannot modify your profile. - cannot_modify_self_status: - other: Ni allwch addasu eich statws. - email_or_password_wrong: - other: Nid yw e-bost a chyfrinair yn cyfateb. - answer: - not_found: - other: Ni cheir yr ateb. - cannot_deleted: - other: Dim caniatâd i ddileu. - cannot_update: - other: Dim caniatâd i ddiweddaru. - question_closed_cannot_add: - other: Mae cwestiynau ar gau ac ni ellir eu hychwanegu. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Nid oes modd golygu sylwadau. - not_found: - other: Sylw heb ei ganfod. - cannot_edit_after_deadline: - other: Mae'r amser sylwadau wedi bod yn rhy hir i'w addasu. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: E-bost yn bodoli eisoes. - need_to_be_verified: - other: Dylid gwirio e-bost. - verify_url_expired: - other: Mae'r URL wedi'i wirio gan e-bost wedi dod i ben, anfonwch yr e-bost eto. - illegal_email_domain_error: - other: Email is not allowed from that email domain. Please use another one. - lang: - not_found: - other: Ffeil iaith heb ei chanfod. - object: - captcha_verification_failed: - other: Captcha anghywir. - disallow_follow: - other: Ni chaniateir i chi ddilyn. - disallow_vote: - other: Ni chaniateir i chi pleidleisio. - disallow_vote_your_self: - other: Ni allwch bleidleisio dros eich post eich hun. - not_found: - other: Heb ganfod y gwrthrych. - verification_failed: - other: Methodd y dilysu. - email_or_password_incorrect: - other: Nid yw e-bost a chyfrinair yn cyfateb. - old_password_verification_failed: - other: Methodd yr hen ddilysiad cyfrinair - new_password_same_as_previous_setting: - other: Mae'r cyfrinair newydd yr un fath â'r un blaenorol. - already_deleted: - other: This post has been deleted. - meta: - object_not_found: - other: Meta object not found - question: - already_deleted: - other: Mae'r postiad hwn wedi'i ddileu. - under_review: - other: Your post is awaiting review. It will be visible after it has been approved. - not_found: - other: Cwestiwn heb ei ganfod. - cannot_deleted: - other: Dim caniatâd i ddileu. - cannot_close: - other: Dim caniatâd i cau. - cannot_update: - other: Dim caniatâd i ddiweddaru. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Reputation rank fail to meet the condition. - vote_fail_to_meet_the_condition: - other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. - no_enough_rank_to_operate: - other: You need at least {{.Rank}} reputation to do this. - report: - handle_failed: - other: Methodd handlen yr adroddiad. - not_found: - other: Heb ganfod yr adroddiad. - tag: - already_exist: - other: Mae tag eisoes yn bodoli. - not_found: - other: Tag heb ei ddarganfod. - recommend_tag_not_found: - other: Recommend tag is not exist. - recommend_tag_enter: - other: Rhowch o leiaf un tag gofynnol. - not_contain_synonym_tags: - other: Ni ddylai gynnwys tagiau cyfystyr. - cannot_update: - other: Dim caniatâd i ddiweddaru. - is_used_cannot_delete: - other: You cannot delete a tag that is in use. - cannot_set_synonym_as_itself: - other: Ni allwch osod cyfystyr y tag cyfredol fel ei hun. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: The from name cannot be a email address. - theme: - not_found: - other: Thema heb ei ddarganfod. - revision: - review_underway: - other: Methu â golygu ar hyn o bryd, mae fersiwn yn y ciw adolygu. - no_permission: - other: No permission to revise. - user: - external_login_missing_user_id: - other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. - external_login_unbinding_forbidden: - other: Please set a login password for your account before you remove this login. - email_or_password_wrong: - other: - other: Nid yw e-bost a chyfrinair yn cyfateb. - not_found: - other: Defnyddwr heb ei ddarganfod. - suspended: - other: Mae'r defnyddiwr hwn wedi'i atal. - username_invalid: - other: Mae'r enw defnyddiwr yn annilys. - username_duplicate: - other: Cymerwyd yr enw defnyddiwr eisoes. - set_avatar: - other: Methodd set avatar. - cannot_update_your_role: - other: Ni allwch addasu eich rôl. - not_allowed_registration: - other: Currently the site is not open for registration. - not_allowed_login_via_password: - other: Currently the site is not allowed to login via password. - access_denied: - other: Access denied - page_access_denied: - other: You do not have access to this page. - add_bulk_users_format_error: - other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Wedi methu darllen y ffurfwedd - database: - connection_failed: - other: Methodd cysylltiad cronfa ddata - create_table_failed: - other: Methwyd creu tabl - install: - create_config_failed: - other: Methu creu'r ffeil config.yaml. - upload: - unsupported_file_format: - other: Fformat ffeil heb ei gefnogi. - site_info: - config_not_found: - other: Site config not found. - badge: - object_not_found: - other: Badge object not found - reason: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude_or_abusive: - name: - other: rude or abusive - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - a_duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - placeholder: - other: Enter the existing question link - not_a_answer: - name: - other: not an answer - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." - no_longer_needed: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - something: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - placeholder: - other: Let us know specifically what you are concerned about - community_specific: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - not_clarity: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - looks_ok: - name: - other: looks OK - desc: - other: This post is good as-is and not low quality. - needs_edit: - name: - other: needs edit, and I did it - desc: - other: Improve and correct problems with this post yourself. - needs_close: - name: - other: needs close - desc: - other: A closed question can't answer, but still can edit, vote and comment. - needs_delete: - name: - other: needs delete - desc: - other: This post will be deleted. - question: - close: - duplicate: - name: - other: sbam - desc: - other: Mae'r cwestiwn hwn wedi'i ofyn o'r blaen ac mae ganddo ateb yn barod. - guideline: - name: - other: rheswm cymunedol-benodol - desc: - other: Nid yw'r cwestiwn hwn yn bodloni canllaw cymunedol. - multiple: - name: - other: angen manylion neu eglurder - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: rhywbeth arall - desc: - other: Mae'r swydd hon angen reswm arall nad yw wedi'i restru uchod. - operation_type: - asked: - other: gofynnodd - answered: - other: atebodd - modified: - other: wedi newid - deleted_title: - other: Deleted question - questions_title: - other: Questions - tag: - tags_title: - other: Tags - no_description: - other: The tag has no description. - notification: - action: - update_question: - other: cwestiwn wedi'i ddiweddaru - answer_the_question: - other: cwestiwn wedi ei ateb - update_answer: - other: ateb wedi'i ddiweddaru - accept_answer: - other: ateb derbyniol - comment_question: - other: cwestiwn a wnaed - comment_answer: - other: ateb a wnaed - reply_to_you: - other: atebodd i chi - mention_you: - other: wedi sôn amdanoch - your_question_is_closed: - other: Mae eich cwestiwn wedi’i gau - your_question_was_deleted: - other: Mae eich cwestiwn wedi’i dileu - your_answer_was_deleted: - other: Mae eich ateb wedi’i dileu - your_comment_was_deleted: - other: Mae eich sylw wedi’i dileu - up_voted_question: - other: upvoted question - down_voted_question: - other: downvoted question - up_voted_answer: - other: upvoted answer - down_voted_answer: - other: downvoted answer - up_voted_comment: - other: upvoted comment - invited_you_to_answer: - other: invited you to answer - earned_badge: - other: You've earned the "{{.BadgeName}}" badge - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Confirm your new email address" - body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} answered your question" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_question: - title: - other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Password reset" - body: - other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - register: - title: - other: "[{{.SiteName}}] Confirm your new account" - body: - other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - test: - title: - other: "[{{.SiteName}}] Test Email" - body: - other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: - upvote: - other: upvote - upvoted: - other: upvoted - downvote: - other: downvote - downvoted: - other: downvoted - accept: - other: accept - accepted: - other: accepted - edit: - other: edit - review: - queued_post: - other: Queued post - flagged_post: - other: Flagged post - suggested_post_edit: - other: Suggested edits - reaction: - tooltip: - other: "{{ .Names }} and {{ .Count }} more..." - badge: - default_badges: - autobiographer: - name: - other: Autobiographer - desc: - other: Filled out profile information. - certified: - name: - other: Certified - desc: - other: Completed our new user tutorial. - editor: - name: - other: Editor - desc: - other: First post edit. - first_flag: - name: - other: First Flag - desc: - other: First flagged a post. - first_upvote: - name: - other: First Upvote - desc: - other: First up voted a post. - first_link: - name: - other: First Link - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: First Share - desc: - other: First shared a post. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Leave 5 comments. - new_user_of_the_month: - name: - other: New User of the Month - desc: - other: Outstanding contributions in their first month. - read_guidelines: - name: - other: Read Guidelines - desc: - other: Read the [community guidelines]. - reader: - name: - other: Reader - desc: - other: Read every answers in a topic with more than 10 answers. - welcome: - name: - other: Welcome - desc: - other: Received a up vote. - nice_share: - name: - other: Nice Share - desc: - other: Shared a post with 25 unique visitors. - good_share: - name: - other: Good Share - desc: - other: Shared a post with 300 unique visitors. - great_share: - name: - other: Great Share - desc: - other: Shared a post with 1000 unique visitors. - out_of_love: - name: - other: Out of Love - desc: - other: Used 50 up votes in a day. - higher_love: - name: - other: Higher Love - desc: - other: Used 50 up votes in a day 5 times. - crazy_in_love: - name: - other: Crazy in Love - desc: - other: Used 50 up votes in a day 20 times. - promoter: - name: - other: Promoter - desc: - other: Invited a user. - campaigner: - name: - other: Campaigner - desc: - other: Invited 3 basic users. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: Thank You - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Active member for a year, posted at least once. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Sut i Fformatio - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Cynt - next: Nesaf - page_title: - question: Cwestiwn - questions: Cwestiynau - tag: Tag - tags: Tagiau - tag_wiki: tag wiki - create_tag: Creu Tag - edit_tag: Golygu Tag - ask_a_question: Create Question - edit_question: Golygu Cwestiwn - edit_answer: Golygu Ateb - search: Chwiliwch - posts_containing: Postiadau yn cynnwys - settings: Gosodiadau - notifications: Hysbysiadau - login: Mewngofnodi - sign_up: Cofrestru - account_recovery: Adfer Cyfrif - account_activation: Ysgogi Cyfrif - confirm_email: Cadarnhau e-bost - account_suspended: Cyfrif wedi'i atal - admin: Gweinyddu - change_email: Addasu E-bost - install: Ateb Gosod - upgrade: Ateb Uwchraddio - maintenance: Cynnal a Chadw Gwefan - users: Defnyddwyr - oauth_callback: Processing - http_404: Gwall HTTP 404 - http_50X: Gwall HTTP 500 - http_403: Gwall HTTP 403 - logout: Log Out - posts: Posts - notifications: - title: Hysbysiadau - inbox: Mewnflwch - achievement: Llwyddiannau - new_alerts: New alerts - all_read: Marciwch y cyfan fel wedi'i ddarllen - show_more: Dangos mwy - someone: Someone - inbox_type: - all: All - posts: Posts - invites: Invites - votes: Votes - answer: Answer - question: Question - badge_award: Badge - suspended: - title: Mae'ch Cyfrif wedi'i Atal - until_time: "Cafodd eich cyfrif ei atal tan {{ time }}." - forever: Cafodd y defnyddiwr hwn ei atal am byth. - end: Nid ydych yn arwain cymunedol. - contact_us: Contact us - editor: - blockquote: - text: Dyfyniad - bold: - text: Cryf - chart: - text: Siart - flow_chart: Siart llif - sequence_diagram: Diagram dilyniant - class_diagram: Diagram dosbarth - state_diagram: Diagram cyflwr - entity_relationship_diagram: Diagram perthynas endid - user_defined_diagram: Diagram wedi'i ddiffinio gan y defnyddiwr - gantt_chart: Siart Gantt - pie_chart: Siart cylch - code: - text: Sampl côd - add_code: Ychwanegu sampl côd - form: - fields: - code: - label: Côd - msg: - empty: Ni all côd fod yn wag. - language: - label: Iaith - placeholder: Synhwyriad awtomatig - btn_cancel: Canslo - btn_confirm: Ychwanegu - formula: - text: Fformiwla - options: - inline: Fformiwla mewn-lein - block: Fformiwla bloc - heading: - text: Pennawd - options: - h1: Pennawd 1 - h2: Pennawd 2 - h3: Pennawd 3 - h4: Pennawd 4 - h5: Pennawd 5 - h6: Pennawd 6 - help: - text: Cymorth - hr: - text: Horizontal rule - image: - text: Delwedd - add_image: Ychwanegu delwedd - tab_image: Uwchlwytho delwedd - form_image: - fields: - file: - label: Image file - btn: Dewis delwedd - msg: - empty: Ni all ffeil fod yn wag. - only_image: Dim ond ffeiliau delwedd a ganiateir. - max_size: File size cannot exceed {{size}} MB. - desc: - label: Disgrifiad - tab_url: URL delwedd - form_url: - fields: - url: - label: URL delwedd - msg: - empty: Ni all URL delwedd fod yn wag. - name: - label: Disgrifiad - btn_cancel: Canslo - btn_confirm: Ychwanegu - uploading: Wrthi'n uwchlwytho - indent: - text: Mewnoliad - outdent: - text: Alloliad - italic: - text: Pwyslais - link: - text: Hypergyswllt - add_link: Ychwanegu hypergyswllt - form: - fields: - url: - label: URL - msg: - empty: Ni all URL fod yn wag. - name: - label: Disgrifiad - btn_cancel: Canslo - btn_confirm: Ychwanegu - ordered_list: - text: Numbered list - unordered_list: - text: Bulleted list - table: - text: Tabl - heading: Pennawd - cell: Cell - file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: Rwy'n cau'r post hon fel... - btn_cancel: Canslo - btn_submit: Cyflwyno - remark: - empty: Ni all fod yn wag. - msg: - empty: Dewis rheswm. - report_modal: - flag_title: Dwi'n tynnu sylw i adrodd y swydd hon fel... - close_title: Rwy'n cau'r post hon fel... - review_question_title: Adolygu cwestiwn - review_answer_title: Adolygu ateb - review_comment_title: Adolygu sylwad - btn_cancel: Canslo - btn_submit: Cyflwyno - remark: - empty: Ni all fod yn wag. - msg: - empty: Dewis rheswm. - not_a_url: URL format is incorrect. - url_not_match: URL origin does not match the current website. - tag_modal: - title: Creu tag newydd - form: - fields: - display_name: - label: Display name - msg: - empty: Ni all fod enw dangos yn wag. - range: Enw arddangos hyd at 35 nod. - slug_name: - label: URL slug - desc: Slug URL hyd at 35 nod. - msg: - empty: Ni all Slug URL fod yn wag. - range: Slug URL hyd at 35 nod. - character: Mae slug URL yn cynnwys set nodau na caniateir. - desc: - label: Disgrifiad - revision: - label: Revision - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_cancel: Canslo - btn_submit: Cyflwyno - btn_post: Post tag newydd - tag_info: - created_at: Creuwyd - edited_at: Golygwyd - history: Hanes - synonyms: - title: Cyfystyron - text: Bydd y tagiau canlynol yn cael eu hail-fapio i - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - tip_with_posts: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - tip_with_synonyms: >- -

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        - tip: Are you sure you wish to delete? - close: Close - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - default_first_reason: Add tag - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - hours: hours - days: days - month: month - months: months - year: year - reaction: - heart: heart - smile: smile - frown: frown - btn_label: add or remove reactions - undo_emoji: undo {{ emoji }} reaction - react_emoji: react with {{ emoji }} - unreact_emoji: unreact with {{ emoji }} - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: "{{count}} more comments" - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - tip_vote: It adds something useful to the post - edit_answer: - title: Edit Answer - default_reason: Edit answer - default_first_reason: Add answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Canslo - tags: - title: Tagiau - sort_buttons: - popular: Poblogaidd - name: Enw - newest: Newest - button_follow: Dilyn - button_following: Yn dilyn - tag_label: cwestiynau - search_placeholder: Hidlo yn ôl enw tag - no_desc: Nid oes gan y tag unrhyw ddisgrifiad. - more: Mwy - wiki: Wiki - ask: - title: Create Question - edit_title: Golygu Cwestiwn - default_reason: Golygu Cwestiwn - default_first_reason: Create question - similar_questions: Cwestiynau tebyg - form: - fields: - revision: - label: Diwygiad - title: - label: Teitl - placeholder: What's your topic? Be specific. - msg: - empty: Ni all teitl fod yn wag. - range: Teitl hyd at 20 nod - body: - label: Corff - msg: - empty: Ni all corff fod yn wag. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Tagiau - msg: - empty: Ni all tagiau fod yn wag. - answer: - label: Ateb - msg: - empty: Ni all ateb fod yn wag. - edit_summary: - label: Edit summary - placeholder: >- - Eglurwch yn fyr eich newidiadau (sillafu wedi'i gywiro, gramadeg sefydlog, fformatio gwell) - btn_post_question: Post cweistiwn - btn_save_edits: Cadw golygiadau - answer_question: Atebwch eich cwestiwn eich hun - post_question&answer: Postiwch eich cwestiwn ac ateb - tag_selector: - add_btn: Ychwanegu tag - create_btn: Creu tag newydd - search_tag: Chwilio tag - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - badges: Badges - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - bookmark: Bookmarks - moderation: Moderation - search: - placeholder: Search - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - resend_email: - url_label: Are you sure you want to resend the activation email? - url_text: You can also give the activation link above to the user. - login: - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New email - msg: - empty: Email cannot be empty. - oauth: - connect: Connect with {{ auth_name }} - remove: Remove {{ auth_name }} - oauth_bind_email: - subtitle: Add a recovery email to your account. - btn_update: Update email address - email: - label: Email - msg: - empty: Email cannot be empty. - modal_title: Email already existes. - modal_content: This email address already registered. Are you sure you want to connect to the existing account? - modal_cancel: Change email - modal_confirm: Connect to the existing account - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm new password - settings: - page_title: Settings - goto_modify: Go to modify - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile image - gravatar: Gravatar - gravatar_text: You can change image on - custom: Custom - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About me - website: - label: Website - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location - placeholder: "City, Country" - notification: - heading: Email Notifications - turn_on: Turn on - inbox: - label: Inbox notifications - description: Answers to your questions, comments, invites, and more. - all_new_question: - label: All new questions - description: Get notified of all new questions. Up to 50 questions per week. - all_new_question_for_following_tags: - label: All new questions for following tags - description: Get notified of new questions for following tags. - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - pass: - label: Current password - msg: Password cannot be empty. - password_title: Password - current_pass: - label: Current password - msg: - empty: Current password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New password - pass_confirm: - label: Confirm new password - interface: - heading: Interface - lang: - label: Interface language - text: User interface language. It will change when you refresh the page. - my_logins: - title: My logins - label: Log in or sign up on this site using these accounts. - modal_title: Remove login - modal_content: Are you sure you want to remove this login from your account? - modal_confirm_btn: Remove - remove_success: Removed successfully - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - sent_success: Sent successfully - related_question: - title: Related - answers: answers - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: People Asked - desc: Select people who you think might know the answer. - invite: Invite to answer - add: Add people - search: Search people - question_detail: - action: Action - created: Created - Asked: Asked - asked: asked - update: Modified - Edited: Edited - edit: edited - commented: commented - Views: Viewed - Follow: Follow - Following: Following - follow_tip: Follow this question to receive notifications - answered: answered - closed_in: Closed in - show_exist: Show existing question. - useful: Useful - question_useful: It is useful and clear - question_un_useful: It is unclear or not useful - question_bookmark: Bookmark this question - answer_useful: It is useful - answer_un_useful: It is not useful - answers: - title: Answers - score: Score - newest: Newest - oldest: Oldest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - edit_answer: Edit my existing answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - tips: - header_1: Thanks for your answer - li1_1: Please be sure to answer the question. Provide details and share your research. - li1_2: Back up any statements you make with references or personal experience. - header_2: But avoid ... - li2_1: Asking for help, seeking clarification, or responding to other answers. - reopen: - confirm_btn: Reopen - title: Reopen this post - content: Are you sure you want to reopen? - list: - confirm_btn: List - title: List this post - content: Are you sure you want to list? - unlist: - confirm_btn: Unlist - title: Unlist this post - content: Are you sure you want to unlist? - pin: - title: Pin this post - content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. - confirm_btn: Pin - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_answer_deleted: This answer has been deleted - undelete_title: Undelete this post - undelete_desc: Are you sure you wish to undelete? - btns: - confirm: Confirm - cancel: Cancel - edit: Edit - save: Save - delete: Delete - undelete: Undelete - list: List - unlist: Unlist - unlisted: Unlisted - login: Log in - signup: Sign up - logout: Log out - verify: Verify - create: Create - approve: Approve - reject: Reject - skip: Skip - discard_draft: Discard draft - pinned: Pinned - all: All - question: Question - answer: Answer - comment: Comment - refresh: Refresh - resend: Resend - deactivate: Deactivate - active: Active - suspend: Suspend - unsuspend: Unsuspend - close: Close - reopen: Reopen - ok: OK - light: Light - dark: Dark - system_setting: System setting - default: Default - reset: Reset - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignore - submit: Submit - normal: Normal - closed: Closed - deleted: Deleted - deleted_permanently: Deleted permanently - pending: Pending - more: More - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - counts_loading: "... Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post. - modal_confirm: - title: Error... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - x_posts: "{{ count }} Posts" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - frequent: Frequent - recommend: Recommend - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - badges: Badges - newest: Newest - score: Score - edit_profile: Edit profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - comma: "," - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - content_empty: No posts found. - accepted: Accepted - answered: answered - asked: asked - downvoted: downvoted - mod_short: MOD - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - recent_badges: Recent Badges - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please choose a language - db_type: - label: Database engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database host - placeholder: "db:3306" - msg: Database host cannot be empty. - db_name: - label: Database name - placeholder: answer - msg: Database name cannot be empty. - db_file: - label: Database file - placeholder: /data/answer.db - msg: Database file cannot be empty. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site name - msg: Site name cannot be empty. - msg_max_length: Site name must be at maximum 30 characters in length. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - max_length: Site URL must be at maximum 512 characters in length. - contact_email: - label: Contact email - text: Email address of key contact responsible for this site. - msg: - empty: Contact email cannot be empty. - incorrect: Contact email incorrect format. - login_required: - label: Private - switch: Login required - text: Only logged in users can access this community. - admin_name: - label: Name - msg: Name cannot be empty. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - msg_min_length: Password must be at least 8 characters in length. - msg_max_length: Password must be at maximum 32 characters in length. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_error: - http_error: HTTP Error {{ code }} - desc_403: You don't have permission to access this page. - desc_404: Unfortunately, this page doesn't exist. - desc_50X: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - badges: Badges - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - terms: Terms - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - login: Login - privileges: Privileges - plugins: Plugins - installed_plugins: Installed Plugins - apperance: Appearance - website_welcome: Welcome to {{site_name}} - user_center: - login: Login - qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. - login_failed_email_tip: Login failed, please allow this app to access your email information before try again. - badges: - modal: - title: Congratulations - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site statistics - questions: "Questions:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - users: "Users:" - flags: "Flags:" - reviews: "Reviews:" - site_health: Site health - version: "Version:" - https: "HTTPS:" - upload_folder: "Upload folder:" - run_mode: "Running mode:" - private: Private - public: Public - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System info - go_version: "Go version:" - database: "Database:" - database_size: "Database size:" - storage_used: "Storage used:" - uptime: "Uptime:" - links: Links - plugins: Plugins - github: GitHub - blog: Blog - contact: Contact - forum: Forum - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - writable: Writable - not_writable: Not writable - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - flagged_type: Flagged {{ type }} - created: Created - action: Action - review: Review - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - edit_profile_modal: - title: Edit profile - form: - fields: - display_name: - label: Display name - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Invalid Email Address. - edit_success: Edited successfully - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - users: - label: Bulk add user - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separate “name, email, password” with commas. One user per line. - msg: "Please enter the user's email, one per line." - display_name: - label: Display name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - more: More - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - edit_profile: Edit profile - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - deactivate_user: - title: Deactivate user - content: An inactive user must re-validate their email. - delete_user: - title: Delete this user - content: Are you sure you want to delete this user? This is permanent! - remove: Remove their content - label: Remove all questions, answers, comments, etc. - text: Don’t check this if you wish to only delete the user’s account. - suspend_user: - title: Suspend this user - content: A suspended user can't log in. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Questions - unlisted: Unlisted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - pending: Pending - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short site description - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site description - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - check_update: - label: Software updates - text: Automatically check for updates - interface: - page_title: Interface - language: - label: Interface language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: From email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - tls: TLS - none: None - smtp_port: - label: SMTP port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test email recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile logo - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square icon - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Write - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Each user can only write one answer for each question - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Recommend tags - text: "Recommend tags will show in the dropdown list by default." - msg: - contain_reserved: "recommended tags cannot contain reserved tags" - required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved tags - text: "Reserved tags can only be used by moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - color_scheme: - label: Color scheme - navbar_style: - label: Navbar background style - primary_color: - label: Primary color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: > - - head: - label: Head - text: > - - header: - label: Header - text: > - - footer: - label: Footer - text: This will insert before </body>. - sidebar: - label: Sidebar - text: This will insert in sidebar. - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - email_registration: - title: Email registration - label: Allow email registration - text: Turn off to prevent anyone creating new account through email. - allowed_email_domains: - title: Allowed email domains - text: Email domains that users must register accounts with. One domain per line. Ignored when empty. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - password_login: - title: Password login - label: Allow email and password login - text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." - installed_plugins: - title: Installed Plugins - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. - filter: - all: All - active: Active - inactive: Inactive - outdated: Outdated - plugins: - label: Plugins - text: Select an existing plugin. - name: Name - version: Version - status: Status - action: Action - deactivate: Deactivate - activate: Activate - settings: Settings - settings_users: - title: Users - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar Base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - profile_editable: - title: Profile editable - allow_update_display_name: - label: Allow users to change their display name - allow_update_username: - label: Allow users to change their username - allow_update_avatar: - label: Allow users to change their profile image - allow_update_bio: - label: Allow users to change their about me - allow_update_website: - label: Allow users to change their website - allow_update_location: - label: Allow users to change their location - privilege: - title: Privileges - level: - label: Reputation required level - text: Choose the reputation required for the privileges - msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 - badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate - filter: - placeholder: Filter by name, badge:id - group: Group - inactive: Inactive - name: Name - show_logs: Show logs - status: Status - title: Badges - form: - optional: (optional) - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - select: Select - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - approve_revision_tip: Do you approve this revision? - approve_flag_tip: Do you approve this flag? - approve_post_tip: Do you approve this post? - approve_user_tip: Do you approve this user? - suggest_edits: Suggested edits - flag_post: Flag post - flag_user: Flag user - queued_post: Queued post - queued_user: Queued user - filter_label: Type - reputation: reputation - flag_post_type: Flagged this post as {{ type }}. - flag_user_type: Flagged this user as {{ type }}. - edit_post: Edit post - list_post: List post - unlist_post: Unlist post - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - pin: pinned - unpin: unpinned - show: listed - hide: unlisted - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores this week - users_with_the_most_vote: Users who voted the most this week - staffs: Our community staff - reputation: reputation - votes: votes - prompt: - leave_page: Are you sure you want to leave the page? - changes_not_save: Your changes may not be saved. - draft: - discard_confirm: Are you sure you want to discard your draft? - messages: - post_deleted: This post has been deleted. - post_cancel_deleted: This post has been undeleted. - post_pin: This post has been pinned. - post_unpin: This post has been unpinned. - post_hide_list: This post has been hidden from list. - post_show_list: This post has been shown to list. - post_reopen: This post has been reopened. - post_list: This post has been listed. - post_unlist: This post has been unlisted. - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/da_DK.yaml b/data/i18n/da_DK.yaml deleted file mode 100644 index 63da094c4..000000000 --- a/data/i18n/da_DK.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Gennemført. - unknown: - other: Ukendt fejl. - request_format_error: - other: Forespørgselsformat er ikke gyldigt. - unauthorized_error: - other: Uautoriseret. - database_error: - other: Data-server fejl. - forbidden_error: - other: Forbudt. - duplicate_request_error: - other: Duplilkeret indenselse. - action: - report: - other: Anmeld - edit: - other: Rediger - delete: - other: Slet - close: - other: Luk - reopen: - other: Genåbn - forbidden_error: - other: Forbudt. - pin: - other: Fastgør - hide: - other: Afliste - unpin: - other: Frigør - show: - other: Liste - invite_someone_to_answer: - other: Rediger - undelete: - other: Genopret - merge: - other: Merge - role: - name: - user: - other: Bruger - admin: - other: Administrator - moderator: - other: Moderator - description: - user: - other: Standard uden særlig adgang. - admin: - other: Hav den fulde magt til at få adgang til webstedet. - moderator: - other: Har adgang til alle indlæg undtagen administratorindstillinger. - privilege: - level_1: - description: - other: Niveau 1 (mindre omdømme kræves for private team, gruppe) - level_2: - description: - other: Niveau 2 (lav omdømme kræves for opstart fællesskab) - level_3: - description: - other: Niveau 3 (højt omdømme kræves for moden fællesskab) - level_custom: - description: - other: Brugerdefineret Niveau - rank_question_add_label: - other: Stil spørgsmål - rank_answer_add_label: - other: Skriv svar - rank_comment_add_label: - other: Skriv kommentar - rank_report_add_label: - other: Anmeld - rank_comment_vote_up_label: - other: Op-stem kommentar - rank_link_url_limit_label: - other: Skriv mere end 2 links ad gangen - rank_question_vote_up_label: - other: Op-stem spørgsmål - rank_answer_vote_up_label: - other: Op-stem svar - rank_question_vote_down_label: - other: Ned-stem spørgsmål - rank_answer_vote_down_label: - other: Ned-stem svar - rank_invite_someone_to_answer_label: - other: Inviter nogen til at svare - rank_tag_add_label: - other: Opret et nyt tag - rank_tag_edit_label: - other: Rediger tag beskrivelse (skal gennemgås) - rank_question_edit_label: - other: Rediger andres spørgsmål (skal gennemgås) - rank_answer_edit_label: - other: Redigere andres svar (skal gennemgås) - rank_question_edit_without_review_label: - other: Rediger andres spørgsmål uden gennemgang - rank_answer_edit_without_review_label: - other: Rediger andres svar uden gennemgang - rank_question_audit_label: - other: Gennemse spørgsmål redigeringer - rank_answer_audit_label: - other: Gennemgå svar redigeringer - rank_tag_audit_label: - other: Gennemse tag redigeringer - rank_tag_edit_without_review_label: - other: Rediger tag beskrivelse uden gennemgang - rank_tag_synonym_label: - other: Administrer tag synonymer - email: - other: E-mail - e_mail: - other: E-mail - password: - other: Adgangskode - pass: - other: Adgangskode - old_pass: - other: Current password - original_text: - other: Dette indlæg - email_or_password_wrong_error: - other: E-mail og adgangskode stemmer ikke overens. - error: - common: - invalid_url: - other: Ugyldig URL. - status_invalid: - other: Invalid status. - password: - space_invalid: - other: Adgangskoden må ikke indeholde mellemrum. - admin: - cannot_update_their_password: - other: Du kan ikke ændre din adgangskode. - cannot_edit_their_profile: - other: Du kan ikke ændre din profil. - cannot_modify_self_status: - other: Du kan ikke ændre din status. - email_or_password_wrong: - other: E-mail og adgangskode stemmer ikke overens. - answer: - not_found: - other: Svar ikke fundet. - cannot_deleted: - other: Ingen tilladelser til at slette. - cannot_update: - other: Ingen tilladelse til at opdatere. - question_closed_cannot_add: - other: Spørgsmål er lukket og kan ikke tilføjes. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Kommentar er ikke tilladt at redigere. - not_found: - other: Kommentar ikke fundet. - cannot_edit_after_deadline: - other: Kommentaren er for gammel til at blive redigeret. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: Email eksisterer allerede. - need_to_be_verified: - other: E-mail skal bekræftes. - verify_url_expired: - other: Email bekræftet URL er udløbet. Send venligst e-mailen igen. - illegal_email_domain_error: - other: E-mail er ikke tilladt fra dette e-mail-domæne. Brug venligst et andet. - lang: - not_found: - other: Sprog-fil kunne ikke findes. - object: - captcha_verification_failed: - other: Captcha er forkert. - disallow_follow: - other: Du har ikke tilladelse til at følge. - disallow_vote: - other: Du har ikke tilladelse til at stemme. - disallow_vote_your_self: - other: Du kan ikke stemme på dit eget indlæg. - not_found: - other: Objekt ikke fundet. - verification_failed: - other: Verifikation mislykkedes. - email_or_password_incorrect: - other: E-mail og adgangskode stemmer ikke overens. - old_password_verification_failed: - other: Den gamle adgangskodebekræftelse mislykkedes - new_password_same_as_previous_setting: - other: Den nye adgangskode er den samme som den foregående. - already_deleted: - other: Dette indlæg er blevet slettet. - meta: - object_not_found: - other: Metaobjekt ikke fundet - question: - already_deleted: - other: Dette indlæg er blevet slettet. - under_review: - other: Dit indlæg afventer gennemgang. Det vil være synligt, når det er blevet godkendt. - not_found: - other: Spørgsmål ikke fundet. - cannot_deleted: - other: Ingen tilladelser til at slette. - cannot_close: - other: Ingen tilladelse til at lukke. - cannot_update: - other: Ingen tilladelse til at opdatere. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Omdømmelse rang opfylder ikke betingelsen. - vote_fail_to_meet_the_condition: - other: Tak for feedback. Du skal mindst have {{.Rank}} ry for at afgive en stemme. - no_enough_rank_to_operate: - other: Du skal mindst {{.Rank}} omdømme for at gøre dette. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Rapport ikke fundet. - tag: - already_exist: - other: Tag findes allerede. - not_found: - other: Tag blev ikke fundet. - recommend_tag_not_found: - other: Anbefal tag eksisterer ikke. - recommend_tag_enter: - other: Indtast mindst et påkrævet tag. - not_contain_synonym_tags: - other: Må ikke indeholde synonym tags. - cannot_update: - other: Ingen tilladelse til at opdatere. - is_used_cannot_delete: - other: Du kan ikke slette et tag, der er i brug. - cannot_set_synonym_as_itself: - other: Du kan ikke indstille synonymet for det nuværende tag som sig selv. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: Fra-navnet kan ikke være en e-mail-adresse. - theme: - not_found: - other: Tema ikke fundet. - revision: - review_underway: - other: Kan ikke redigere i øjeblikket, der er en version i revisionskøen. - no_permission: - other: Ingen tilladelse til at revidere. - user: - external_login_missing_user_id: - other: Den tredjepartsplatform giver ikke et unikt UserID, så du kan ikke logge ind, kontakt venligst webstedsadministratoren. - external_login_unbinding_forbidden: - other: Angiv en adgangskode til din konto, før du fjerner dette login. - email_or_password_wrong: - other: - other: E-mail og adgangskode stemmer ikke overens. - not_found: - other: Bruger ikke fundet. - suspended: - other: Brugeren er suspenderet. - username_invalid: - other: Brugernavn er ugyldigt. - username_duplicate: - other: Brugernavn er allerede i brug. - set_avatar: - other: Avatar sæt mislykkedes. - cannot_update_your_role: - other: Du kan ikke ændre din rolle. - not_allowed_registration: - other: Webstedet er ikke åbent for registrering. - not_allowed_login_via_password: - other: I øjeblikket er det ikke tilladt at logge ind via adgangskode. - access_denied: - other: Adgang nægtet - page_access_denied: - other: Du har ikke adgang til denne side. - add_bulk_users_format_error: - other: "Fejl {{.Field}} format nær '{{.Content}}' i linje {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "Antallet af brugere du tilføjer på én gang skal være i intervallet 1 -{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Kunne ikke læse konfigurationen - database: - connection_failed: - other: Database forbindelse mislykkedes - create_table_failed: - other: Tabellen kunne ikke oprettes - install: - create_config_failed: - other: Kan ikke oprette filen config.yaml. - upload: - unsupported_file_format: - other: Ikke understøttet filformat. - site_info: - config_not_found: - other: Site config ikke fundet. - badge: - object_not_found: - other: Badge object not found - reason: - spam: - name: - other: spam - desc: - other: Dette indlæg er en annonce eller vandalisme. Det er ikke nyttigt eller relevant for det aktuelle emne. - rude_or_abusive: - name: - other: uhøflig eller misbrug - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - a_duplicate: - name: - other: en duplikering - desc: - other: Dette spørgsmål er blevet stillet før og har allerede et svar. - placeholder: - other: Indtast linket til eksisterende spørgsmål - not_a_answer: - name: - other: ikke et svar - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." - no_longer_needed: - name: - other: ikke længere nødvendigt - desc: - other: Denne kommentar er forældet, samtale-agtig eller ikke relevant for dette indlæg. - something: - name: - other: noget andet - desc: - other: Dette indlæg kræver personalets opmærksomhed af en anden grund, som ikke er nævnt ovenfor. - placeholder: - other: Lad os vide specifikt, hvad du er bekymret over - community_specific: - name: - other: en fællesskabsspecifik årsag - desc: - other: Dette spørgsmål opfylder ikke en fællesskabsretningslinje. - not_clarity: - name: - other: kræver detaljer eller klarhed - desc: - other: Dette spørgsmål indeholder i øjeblikket flere spørgsmål i én. Det bør kun fokusere på ét problem. - looks_ok: - name: - other: ser OK ud - desc: - other: Dette indlæg er godt som er og ikke lav kvalitet. - needs_edit: - name: - other: har brug for redigering, og jeg gjorde det - desc: - other: Forbedre og ret selv problemer med dette indlæg. - needs_close: - name: - other: skal lukkes - desc: - other: Et lukket spørgsmål kan ikke besvares, men du kan stadig redigere, stemme og kommentere. - needs_delete: - name: - other: skal slettes - desc: - other: Dette indlæg bliver slettet. - question: - close: - duplicate: - name: - other: spam - desc: - other: Dette spørgsmål er blevet stillet før og har allerede et svar. - guideline: - name: - other: en fællesskabsspecifik årsag - desc: - other: Dette spørgsmål opfylder ikke en fællesskabsretningslinje. - multiple: - name: - other: kræver detaljer eller klarhed - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: noget andet - desc: - other: Dette indlæg kræver en anden grund som ikke er nævnt ovenfor. - operation_type: - asked: - other: spurgt - answered: - other: besvaret - modified: - other: ændret - deleted_title: - other: Slettet spørgsmål - questions_title: - other: Spørgsmål - tag: - tags_title: - other: Tags - no_description: - other: Tag har ingen beskrivelse. - notification: - action: - update_question: - other: opdateret spørgsmål - answer_the_question: - other: besvaret spørgsmål - update_answer: - other: opdateret svar - accept_answer: - other: accepteret svar - comment_question: - other: kommenteret spørgsmål - comment_answer: - other: kommenteret svar - reply_to_you: - other: svarede dig - mention_you: - other: nævnte dig - your_question_is_closed: - other: Dit spørgsmål er blevet lukket - your_question_was_deleted: - other: Dit spørgsmål er blevet slettet - your_answer_was_deleted: - other: Dit svar er blevet slettet - your_comment_was_deleted: - other: Din kommentar er slettet - up_voted_question: - other: op-stemt spørgsmål - down_voted_question: - other: ned-stemt spørgsmål - up_voted_answer: - other: op-stemt svar - down_voted_answer: - other: ned-stemt svar - up_voted_comment: - other: op-stemt kommentar - invited_you_to_answer: - other: inviterede dig til at svare - earned_badge: - other: You've earned the "{{.BadgeName}}" badge - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Bekræft din nye e-mailadresse" - body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} besvarede dit spørgsmål" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} inviterede dig til at svare" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} kommenterede dit indlæg" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_question: - title: - other: "[{{.SiteName}}] Nyt spørgsmål: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Nulstilling af adgangskode" - body: - other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - register: - title: - other: "[{{.SiteName}}] Bekræft din nye konto" - body: - other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - test: - title: - other: "[{{.SiteName}}] Test E-Mail" - body: - other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: - upvote: - other: stem op - upvoted: - other: stemt op - downvote: - other: stem ned - downvoted: - other: stemt ned - accept: - other: acceptér - accepted: - other: accepteret - edit: - other: rediger - review: - queued_post: - other: Indlæg i kø - flagged_post: - other: Anmeldt indlæg - suggested_post_edit: - other: Foreslåede redigeringer - reaction: - tooltip: - other: "{{ .Names }} og {{ .Count }} mere..." - badge: - default_badges: - autobiographer: - name: - other: Autobiographer - desc: - other: Filled out profile information. - certified: - name: - other: Certified - desc: - other: Completed our new user tutorial. - editor: - name: - other: Editor - desc: - other: First post edit. - first_flag: - name: - other: First Flag - desc: - other: First flagged a post. - first_upvote: - name: - other: First Upvote - desc: - other: First up voted a post. - first_link: - name: - other: First Link - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: First Share - desc: - other: First shared a post. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Leave 5 comments. - new_user_of_the_month: - name: - other: New User of the Month - desc: - other: Outstanding contributions in their first month. - read_guidelines: - name: - other: Read Guidelines - desc: - other: Read the [community guidelines]. - reader: - name: - other: Reader - desc: - other: Read every answers in a topic with more than 10 answers. - welcome: - name: - other: Welcome - desc: - other: Received a up vote. - nice_share: - name: - other: Nice Share - desc: - other: Shared a post with 25 unique visitors. - good_share: - name: - other: Good Share - desc: - other: Shared a post with 300 unique visitors. - great_share: - name: - other: Great Share - desc: - other: Shared a post with 1000 unique visitors. - out_of_love: - name: - other: Out of Love - desc: - other: Used 50 up votes in a day. - higher_love: - name: - other: Higher Love - desc: - other: Used 50 up votes in a day 5 times. - crazy_in_love: - name: - other: Crazy in Love - desc: - other: Used 50 up votes in a day 20 times. - promoter: - name: - other: Promoter - desc: - other: Invited a user. - campaigner: - name: - other: Campaigner - desc: - other: Invited 3 basic users. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: Thank You - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Active member for a year, posted at least once. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Sådan formaterer du - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Forrige - next: Næste - page_title: - question: Spørgsmål - questions: Spørgsmål - tag: Tag - tags: Tags - tag_wiki: tag wiki - create_tag: Opret tag - edit_tag: Rediger tag - ask_a_question: Create Question - edit_question: Rediger spørgsmål - edit_answer: Rediger Svar - search: Søg - posts_containing: Indlæg som indeholder - settings: Indstillinger - notifications: Notifikationer - login: Log Ind - sign_up: Tilmeld dig - account_recovery: Konto-gendannelse - account_activation: Aktivering af konto - confirm_email: Bekræft e-mail - account_suspended: Konto suspenderet - admin: Administrator - change_email: Ændre E-Mail - install: Answer Installation - upgrade: Answer Opgradering - maintenance: Vedligeholdelse af websted - users: Brugere - oauth_callback: Behandler - http_404: HTTP Fejl 404 - http_50X: Http Fejl 500 - http_403: HTTP Fejl 403 - logout: Log Ud - posts: Posts - notifications: - title: Notifikationer - inbox: Indbakke - achievement: Bedrifter - new_alerts: Nye adviseringer - all_read: Markér alle som læst - show_more: Vis mere - someone: Nogen - inbox_type: - all: Alle - posts: Indlæg - invites: Invitationer - votes: Stemmer - answer: Answer - question: Question - badge_award: Badge - suspended: - title: Din konto er blevet suspenderet - until_time: "Din konto blev suspenderet indtil {{ time }}." - forever: Denne bruger blev suspenderet for evigt. - end: Du opfylder ikke en fællesskabsretningslinje. - contact_us: Kontakt os - editor: - blockquote: - text: Citatblok - bold: - text: Fed - chart: - text: Diagram - flow_chart: Flow- diagram - sequence_diagram: Sekvensdiagram - class_diagram: Klassediagram - state_diagram: Tilstands-diagram - entity_relationship_diagram: Enheds-forhold-diagram - user_defined_diagram: Brugerdefineret diagram - gantt_chart: Gantt- diagram - pie_chart: Cirkeldiagram - code: - text: Kode-eksempel - add_code: Tilføj kodeeksempel - form: - fields: - code: - label: Kode - msg: - empty: Kode skal udfyldes. - language: - label: Sprog - placeholder: Automatisk detektering - btn_cancel: Annuller - btn_confirm: Tilføj - formula: - text: Formel - options: - inline: Indlejret formel - block: Formel blok - heading: - text: Overskrift - options: - h1: Overskrift 1 - h2: Overskrift 2 - h3: Overskrift 3 - h4: Overskrift 4 - h5: Overskrift 5 - h6: Overskrift 6 - help: - text: Hjælp - hr: - text: Vandret streg - image: - text: Billede - add_image: Tilføj billede - tab_image: Upload billede - form_image: - fields: - file: - label: Billedfil - btn: Vælg billede - msg: - empty: Filen skal udfyldes. - only_image: Kun billedfiler er tilladt. - max_size: File size cannot exceed {{size}} MB. - desc: - label: Beskriveslse - tab_url: Billede-URL - form_url: - fields: - url: - label: Billede-URL - msg: - empty: Billede-URL skal udfyldes. - name: - label: Beskriveslse - btn_cancel: Annuller - btn_confirm: Tilføj - uploading: Uploader - indent: - text: Indrykning - outdent: - text: Udrykning - italic: - text: Fremhævning - link: - text: Link - add_link: Tilføj link - form: - fields: - url: - label: URL - msg: - empty: URL må ikke være tom. - name: - label: Beskriveslse - btn_cancel: Annuller - btn_confirm: Tilføj - ordered_list: - text: Nummereret liste - unordered_list: - text: Punktliste - table: - text: Tabel - heading: Overskrift - cell: Celle - file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: Jeg lukker dette indlæg fordi... - btn_cancel: Annuller - btn_submit: Indsend - remark: - empty: skal udfyldes. - msg: - empty: Vælg en grund. - report_modal: - flag_title: Jeg markerer for at rapportere dette indlæg som... - close_title: Jeg lukker dette indlæg fordi... - review_question_title: Gennemgå spørgsmål - review_answer_title: Gennemgå svar - review_comment_title: Gennemgå kommentar - btn_cancel: Annuller - btn_submit: Indsend - remark: - empty: skal udfyldes. - msg: - empty: Vælg en grund. - not_a_url: URL-format er forkert. - url_not_match: URL oprindelsen matcher ikke det aktuelle websted. - tag_modal: - title: Opret et nyt tag - form: - fields: - display_name: - label: Visnings-navn - msg: - empty: Visnings-navn skal udfyldes. - range: Visnings-navn på op til 35 tegn. - slug_name: - label: URL-slug - desc: URL slug op til 35 tegn. - msg: - empty: URL slug må ikke være tom. - range: URL slug op til 35 tegn. - character: URL slug indeholder ikke tilladte tegn. - desc: - label: Beskriveslse - revision: - label: Revision - edit_summary: - label: Rediger resumé - placeholder: >- - Forklar kort dine ændringer (korrigeret stavning, fast grammatik, forbedret formatering) - btn_cancel: Annuller - btn_submit: Indsend - btn_post: Send nyt tag - tag_info: - created_at: Oprettet - edited_at: Redigeret - history: Historik - synonyms: - title: Synonymer - text: Følgende tags vil blive genmappet til - empty: Ingen synonymer fundet. - btn_add: Tilføj et synonym - btn_edit: Rediger - btn_save: Gem - synonyms_text: Følgende tags vil blive genmappet til - delete: - title: Slet dette tag - tip_with_posts: >- -

        Vi tillader ikke at slette tag med indlæg.

        Fjern venligst dette tag fra indlæggene først.

        - tip_with_synonyms: >- -

        Vi tillader ikke at slette tag med indlæg.

        Fjern venligst dette tag fra indlæggene først.

        - tip: Er du sikker på, at du vil slette? - close: Luk - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Rediger tag - default_reason: Rediger tag - default_first_reason: Tilføj tag - btn_save_edits: Gem ændringer - btn_cancel: Annuller - dates: - long_date: MMM D - long_date_with_year: "D MMMM, YYYY" - long_date_with_time: "MMM D, ÅÅÅÅ [at] HH:mm" - now: nu - x_seconds_ago: "{{count}}s siden" - x_minutes_ago: "{{count}}s siden" - x_hours_ago: "{{count}}t siden" - hour: time - day: dag - hours: timer - days: dag - month: month - months: months - year: year - reaction: - heart: hjerte - smile: smil - frown: rynke panden - btn_label: tilføj eller fjern reaktioner - undo_emoji: fortryd {{ emoji }} reaktion - react_emoji: reager med {{ emoji }} - unreact_emoji: ikke reager med {{ emoji }} - comment: - btn_add_comment: Tilføj kommentar - reply_to: Svar til - btn_reply: Svar - btn_edit: Rediger - btn_delete: Slet - btn_flag: Anmeld - btn_save_edits: Gem ændringer - btn_cancel: Annuller - show_more: "{{count}} flere kommentarer" - tip_question: >- - Brug kommentarer til at bede om mere information eller foreslå forbedringer. Undgå at besvare spørgsmål i kommentarer. - tip_answer: >- - Brug kommentarer til at svare andre brugere eller give dem besked om ændringer. Hvis du tilføjer nye oplysninger, skal du redigere dit indlæg i stedet for at kommentere. - tip_vote: Det tilføjer noget nyttigt til indlægget - edit_answer: - title: Rediger Svar - default_reason: Rediger svar - default_first_reason: Tilføj svar - form: - fields: - revision: - label: Revision - answer: - label: Svar - feedback: - characters: indhold skal være mindst 6 tegn. - edit_summary: - label: Rediger resumé - placeholder: >- - Forklar kort dine ændringer (korrigeret stavning, fast grammatik, forbedret formatering) - btn_save_edits: Gem ændringer - btn_cancel: Annuller - tags: - title: Tags - sort_buttons: - popular: Populære - name: Navn - newest: Nyeste - button_follow: Følg - button_following: Følger - tag_label: spørgsmål - search_placeholder: Filtrer efter tag-navn - no_desc: Tag har ingen beskrivelse. - more: Mere - wiki: Wiki - ask: - title: Create Question - edit_title: Rediger spørgsmål - default_reason: Rediger spørgsmål - default_first_reason: Create question - similar_questions: Lignende spørgsmål - form: - fields: - revision: - label: Revision - title: - label: Titel - placeholder: What's your topic? Be specific. - msg: - empty: Titel må ikke være tom. - range: Titel på op til 150 tegn - body: - label: Brødtekst - msg: - empty: Brødtekst skal udfyldes. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Tags - msg: - empty: Tags må ikke være tom. - answer: - label: Svar - msg: - empty: Svar må ikke være tomt. - edit_summary: - label: Rediger resumé - placeholder: >- - Forklar kort dine ændringer (korrigeret stavning, fast grammatik, forbedret formatering) - btn_post_question: Indsend dit spørgsmål - btn_save_edits: Gem ændringer - answer_question: Besvar dit eget spørgsmål - post_question&answer: Send dit spørgsmål og svar - tag_selector: - add_btn: Tilføj tag - create_btn: Opret et nyt tag - search_tag: Søg tag - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: Ingen tags matchede - tag_required_text: Påkrævet tag (mindst én) - header: - nav: - question: Spørgsmål - tag: Tags - user: Brugere - badges: Badges - profile: Profil - setting: Indstillinger - logout: Log Ud - admin: Administrator - review: Gennemgå - bookmark: Bogmærker - moderation: Moderering - search: - placeholder: Søg - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Skift - loading: indlæser... - pic_auth_code: - title: Captcha - placeholder: Skriv teksten ovenfor - msg: - empty: Captcha må ikke være tomt. - inactive: - first: >- - Du er næsten færdig! Vi har sendt en aktiveringsmail til {{mail}}. Følg venligst instruktionerne i mailen for at aktivere din konto. - info: "Hvis det ikke ankommer, tjek din spam-mappe." - another: >- - Vi har sendt endnu en aktiverings-e-mail til dig på {{mail}}. Det kan tage nogen få minutter før den når frem; kontrollér også din spam-mappe. - btn_name: Send aktiverings-e-mail igen - change_btn_name: Ændre e-mail - msg: - empty: skal udfyldes. - resend_email: - url_label: Er du sikker på, at du vil sende aktiveringse-mailen? - url_text: Du kan også give aktiveringslinket ovenfor til brugeren. - login: - login_to_continue: Log ind for at fortsætte - info_sign: Har du ikke en konto? <1>Tilmeld dig - info_login: Har du allerede en konto? <1>Log ind - agreements: Ved at registrere dig accepterer du <1>privacy policy og <3>terms of service . - forgot_pass: Glemt adgangskode? - name: - label: Navn - msg: - empty: Navn må ikke være tomt. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: E-mail - msg: - empty: E-mail skal udfyldes. - password: - label: Adgangskode - msg: - empty: Adgangskoden skal udfyldes. - different: De indtastede adgangskoder er ikke ens - account_forgot: - page_title: Glemt adgangskode - btn_name: Send mig gendannelsesmail - send_success: >- - Hvis en konto matcher {{mail}}, vil du modtage en e-mail med instruktioner om, hvordan du nulstiller din adgangskode. - email: - label: E-mail - msg: - empty: E-mail skal udfyldes. - change_email: - btn_cancel: Annuller - btn_update: Opdater e-mailadresse - send_success: >- - Hvis en konto matcher {{mail}}, vil du modtage en e-mail med instruktioner om, hvordan du nulstiller din adgangskode. - email: - label: Ny e-mail - msg: - empty: E-mail skal udfyldes. - oauth: - connect: Forbind med {{ auth_name }} - remove: Fjern {{ auth_name }} - oauth_bind_email: - subtitle: Tilføj en gendannelsese-mail til din konto. - btn_update: Opdater e-mailadresse - email: - label: E-mail - msg: - empty: E-mail skal udfyldes. - modal_title: Email eksisterer allerede. - modal_content: Denne e-mailadresse er allerede registreret. Er du sikker på, at du vil oprette forbindelse til den eksisterende konto? - modal_cancel: Ændre e-mail - modal_confirm: Opret forbindelse til den eksisterende konto - password_reset: - page_title: Nulstil adgangskode - btn_name: Nulstil min adgangskode - reset_success: >- - Du har ændret din adgangskode. Du vil blive omdirigeret til siden log ind. - link_invalid: >- - Beklager, dette link til nulstilling af adgangskode er ikke længere gyldigt. Måske er din adgangskode allerede nulstillet? - to_login: Fortsæt til log-ind siden - password: - label: Adgangskode - msg: - empty: Adgangskoden skal udfyldes. - length: Længden skal være mellem 8 og 32 tegn - different: De indtastede adgangskoder er ikke ens - password_confirm: - label: Bekræft den nye adgangskode - settings: - page_title: Indstillinger - goto_modify: Gå til at ændre - nav: - profile: Profil - notification: Notifikationer - account: Konto - interface: Grænseflade - profile: - heading: Profil - btn_name: Gem - display_name: - label: Visnings-navn - msg: Visnings-navn skal udfyldes. - msg_range: Display name must be 2-30 characters in length. - username: - label: Brugernavn - caption: Man kan nævne dig som "@username". - msg: Brugernavn skal udfyldes. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profilbillede - gravatar: Gravatar - gravatar_text: Du kan ændre billede på - custom: Brugerdefineret - custom_text: Du kan uploade dit billede. - default: System - msg: Upload en avatar - bio: - label: Om mig - website: - label: Websted - placeholder: "https://example.com" - msg: Forkert format på websted - location: - label: Placering - placeholder: "By, land" - notification: - heading: Email-notifikationer - turn_on: Slå til - inbox: - label: Notifikationer i indbakken - description: Svar på dine spørgsmål, kommentarer, invitationer og mere. - all_new_question: - label: Alle nye spørgsmål - description: Få besked om alle nye spørgsmål. Op til 50 spørgsmål om ugen. - all_new_question_for_following_tags: - label: Alle nye spørgsmål til følgende tags - description: Få besked om nye spørgsmål til følgende tags. - account: - heading: Konto - change_email_btn: Ændre e-mail - change_pass_btn: Skift adgangskode - change_email_info: >- - Vi har sendt en e-mail til denne adresse. Følg venligst bekræftelsesinstruktionerne. - email: - label: E-mail - new_email: - label: Ny e-mail - msg: Ny e-mail skal udfyldes. - pass: - label: Nuværende adgangskode - msg: Adgangskoden skal udfyldes. - password_title: Adgangskode - current_pass: - label: Nuværende adgangskode - msg: - empty: Nuværende adgangskode skal udfyldes. - length: Længden skal være mellem 8 og 32 tegn. - different: De to indtastede adgangskoder er ikke ens. - new_pass: - label: Ny adgangskode - pass_confirm: - label: Bekræft den nye adgangskode - interface: - heading: Grænseflade - lang: - label: Grænseflade sprog - text: Brugergrænseflade sprog. Det vil ændres, når du opdaterer siden. - my_logins: - title: Mine log ind - label: Log ind eller tilmeld dig på dette websted ved hjælp af disse konti. - modal_title: Fjern login - modal_content: Er du sikker på, at du vil fjerne dette login fra din konto? - modal_confirm_btn: Slet - remove_success: Fjernet - toast: - update: opdatering gennemført - update_password: Adgangskoden er ændret. - flag_success: Tak for at anmelde. - forbidden_operate_self: Forbudt at operere på dig selv - review: Din revision vil blive vist efter gennemgang. - sent_success: Sendt - related_question: - title: Related - answers: svar - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Inviter personer - desc: Invitér personer, som du tror, kan svare. - invite: Inviter til at svare - add: Tilføj personer - search: Søg personer - question_detail: - action: Handling - created: Created - Asked: Spurgt - asked: spurgt - update: Ændret - Edited: Edited - edit: redigeret - commented: kommenteret - Views: Set - Follow: Følg - Following: Følger - follow_tip: Følg dette spørgsmål for at modtage notifikationer - answered: besvaret - closed_in: Lukket om - show_exist: Vis eksisterende spørgsmål. - useful: Nyttigt - question_useful: Det er nyttigt og klart - question_un_useful: Det er uklart eller ikke nyttigt - question_bookmark: Bogmærk dette spørgsmål - answer_useful: Det er nyttigt - answer_un_useful: Det er ikke nyttigt - answers: - title: Svar - score: Bedømmelse - newest: Nyeste - oldest: Ældste - btn_accept: Acceptér - btn_accepted: Accepteret - write_answer: - title: Dit Svar - edit_answer: Redigér mit eksisterende svar - btn_name: Indsend dit svar - add_another_answer: Tilføj endnu et svar - confirm_title: Fortsæt med at svare - continue: Forsæt - confirm_info: >- -

        Er du sikker på, at du vil tilføje et andet svar?

        Du kan i stedet bruge redigeringslinket til at forfine og forbedre dit eksisterende svar.

        - empty: Svar skal udfyldes. - characters: indhold skal være mindst 6 tegn. - tips: - header_1: Tak for dit svar - li1_1: Vær sikker på at besvare spørgsmålet. Giv oplysninger og del din forskning. - li1_2: Begrund eventuelle udsagn med referencer eller personlige erfaringer. - header_2: Men undgå... - li2_1: Spørger om hjælp, søger afklaring, eller reagerer på andre svar. - reopen: - confirm_btn: Genåbn - title: Genåbn dette indlæg - content: Er du sikker på, at du vil genåbne? - list: - confirm_btn: Liste - title: Sæt dette indlæg på listen - content: Er du sikker på du vil sætte på listen? - unlist: - confirm_btn: Fjern fra listen - title: Fjern dette indlæg fra listen - content: Er du sikker på at du vil fjerne fra listen? - pin: - title: Fastgør dette indlæg - content: Er du sikker på, at du ønsker at fastgøre globalt? Dette indlæg vises øverst på alle indlægs-lister. - confirm_btn: Fastgør - delete: - title: Slet dette indlæg - question: >- - Vi anbefaler ikke, at sletter spørgsmål med svar, fordi det fratager fremtidige læsere denne viden.

        Gentaget sletning af besvarede spørgsmål kan resultere i, at din konto bliver blokeret fra at spørge. Er du sikker på, at du ønsker at slette? - answer_accepted: >- -

        Vi anbefaler ikke at slette accepteret svar fordi det fratager fremtidige læsere denne viden.

        Gentagen sletning af accepterede svar kan resultere i, at din konto bliver blokeret fra besvarelse. Er du sikker på, at du ønsker at slette? - other: Er du sikker på, at du vil slette? - tip_answer_deleted: Dette svar er blevet slettet - undelete_title: Genopret dette indlæg - undelete_desc: Er du sikker på du ønsker at genoprette? - btns: - confirm: Bekræft - cancel: Annuller - edit: Rediger - save: Gem - delete: Slet - undelete: Genopret - list: Sæt på liste - unlist: Fjern fra liste - unlisted: Fjernet fra liste - login: Log ind - signup: Opret konto - logout: Log Ud - verify: Verificér - create: Create - approve: Godkend - reject: Afvis - skip: Spring Over - discard_draft: Kassér udkast - pinned: Fastgjort - all: Alle - question: Spørgsmål - answer: Svar - comment: Kommentar - refresh: Genopfrisk - resend: Send igen - deactivate: Deaktiver - active: Aktiv - suspend: Suspendér - unsuspend: Ophæv suspendering - close: Luk - reopen: Genåbn - ok: Ok - light: Lys - dark: Mørk - system_setting: Systemindstilling - default: Standard - reset: Nulstil - tag: Tag - post_lowercase: indlæg - filter: Filtrer - ignore: Ignorér - submit: Indsend - normal: Normal - closed: Lukket - deleted: Slettet - deleted_permanently: Deleted permanently - pending: Ventende - more: Mere - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Søgeresultater - keywords: Nøgleord - options: Muligheder - follow: Følg - following: Følger - counts: "{{count}} Resultater" - counts_loading: "... Results" - more: Mere - sort_btns: - relevance: Relevans - newest: Nyeste - active: Aktiv - score: Bedømmelse - more: Mere - tips: - title: Avancerede Søgetips - tag: "<1>[tag] søgning med et tag" - user: "<1>user:username søgning efter forfatter" - answer: "<1>answers:0 ubesvarede spørgsmål" - score: "<1>score:3 indlæg med 3+ score" - question: "<1>is:question søgespørgsmål" - is_answer: "<1>is:answer søgesvar" - empty: Vi kunne ikke finde noget.
        Prøv forskellige eller mindre specifikke søgeord. - share: - name: Del - copy: Kopiér link - via: Del indlæg via... - copied: Kopieret - facebook: Del på Facebook - twitter: Share to X - cannot_vote_for_self: Du kan ikke stemme på dit eget indlæg. - modal_confirm: - title: Fejl... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Din nye konto er bekræftet. Du vil blive omdirigeret til hjemmesiden. - link: Fortsæt til startside - oops: Hovsa! - invalid: Linket, du brugte, virker ikke længere. - confirm_new_email: Din e-mail er blevet opdateret. - confirm_new_email_invalid: >- - Beklager, dette bekræftelseslink er ikke længere gyldigt. Måske blev din e-mail allerede ændret? - unsubscribe: - page_title: Afmeld - success_title: Afmelding Lykkedes - success_desc: Du er blevet fjernet fra denne abonnentliste og vil ikke modtage yderligere e-mails fra os. - link: Skift indstillinger - question: - following_tags: Følger Tags - edit: Rediger - save: Gem - follow_tag_tip: Følg tags for at udvælge dine spørgsmål. - hot_questions: Populære Spørgsmål - all_questions: Alle Spørgsmål - x_questions: "{{ count }} Spørgsmål" - x_answers: "{{ count }} svar" - x_posts: "{{ count }} Posts" - questions: Spørgsmål - answers: Svar - newest: Nyeste - active: Aktiv - hot: Populært - frequent: Frequent - recommend: Recommend - score: Bedømmelse - unanswered: Ubesvaret - modified: ændret - answered: besvaret - asked: spurgt - closed: lukket - follow_a_tag: Følg et tag - more: Mere - personal: - overview: Oversigt - answers: Svar - answer: svar - questions: Spørgsmål - question: spørgsmål - bookmarks: Bogmærker - reputation: Omdømme - comments: Kommentarer - votes: Stemmer - badges: Badges - newest: Nyeste - score: Bedømmelse - edit_profile: Rediger profil - visited_x_days: "Besøgte {{ count }} dage" - viewed: Set - joined: Tilmeldt - comma: "," - last_login: Set - about_me: Om Mig - about_me_empty: "// Hej, Verden!" - top_answers: Populære Svar - top_questions: Populære Spørgsmål - stats: Statistik - list_empty: Ingen indlæg fundet.
        Måske vil du vælge en anden fane? - content_empty: No posts found. - accepted: Accepteret - answered: besvaret - asked: spurgt - downvoted: nedstemt - mod_short: MOD - mod_long: Moderatorer - x_reputation: omdømme - x_votes: stemmer modtaget - x_answers: svar - x_questions: spørgsmål - recent_badges: Recent Badges - install: - title: Installation - next: Næste - done: Udført - config_yaml_error: Kan ikke oprette filen config.yaml. - lang: - label: Vælg et sprog - db_type: - label: Database type - db_username: - label: Brugernavn - placeholder: rod - msg: Brugernavn skal udfyldes. - db_password: - label: Adgangskode - placeholder: rod - msg: Adgangskoden skal udfyldes. - db_host: - label: Database host - placeholder: "db:3306" - msg: Database host skal udfyldes. - db_name: - label: Database navn - placeholder: answer - msg: Databasenavn skal udfyldes. - db_file: - label: Databasefil - placeholder: /data/answer.db - msg: Databasefil skal udfyldes. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Opret config.yaml - label: Filen config.yaml blev oprettet. - desc: >- - Du kan manuelt oprette filen <1>config.yaml i mappen <1>/var/wwww/xxx/ og indsætte følgende tekst i den. - info: Når du har gjort det, skal du klikke på "Næste" knappen. - site_information: Websted Information - admin_account: Administrator Konto - site_name: - label: Websted navn - msg: Websted-navn skal udfyldes. - msg_max_length: Webstedsnavn kan ikke være længere end 30 tegn. - site_url: - label: Websted URL - text: Adressen på dit websted. - msg: - empty: Webstedets URL skal udfyldes. - incorrect: Websteds URL forkert format. - max_length: WebstedsURL skal højst være 512 tegn. - contact_email: - label: Kontakt e-mail - text: E-mailadresse på nøglekontakt ansvarlig for dette websted. - msg: - empty: Kontakt-e-mail skal udfyldes. - incorrect: Ugyldig kontakt e-mail adresse. - login_required: - label: Privat - switch: Log ind påkrævet - text: Kun brugere som er logget ind har adgang til dette fællesskab. - admin_name: - label: Navn - msg: Navn skal udfyldes. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Adgangskode - text: >- - Du skal bruge denne adgangskode for at logge ind. Opbevar den et sikkert sted. - msg: Adgangskoden skal udfyldes. - msg_min_length: Adgangskoden skal være mindst 8 tegn. - msg_max_length: Adgangskoden skal højst udgøre 32 tegn. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: E-mail - text: Du skal bruge denne e-mail for at logge ind. - msg: - empty: E-mail skal udfyldes. - incorrect: Ugyldig e-mail adresse. - ready_title: Dit websted er klar - ready_desc: >- - Hvis du nogensinde har lyst til at ændre flere indstillinger, kan du besøge <1>admin-sektion; find det i site-menuen. - good_luck: "Hav det sjovt, og held og lykke!" - warn_title: Advarsel - warn_desc: >- - Filen <1>config.yaml findes allerede. Hvis du har brug for at nulstille en af konfigurationselementerne i denne fil, så slet den først. - install_now: Du kan prøve <1>at installere nu. - installed: Allerede installeret - installed_desc: >- - Du synes allerede at være installeret. For at geninstallere skal du først rydde dine gamle databasetabeller. - db_failed: Database forbindelse mislykkedes - db_failed_desc: >- - Det betyder enten, at databaseinformationen i din <1>config. aml fil er forkert eller at kontakt med databaseserveren ikke kunne etableres. Dette kan betyde, at din værts databaseserver er nede. - counts: - views: visninger - votes: stemmer - answers: svar - accepted: Accepteret - page_error: - http_error: HTTP Fejl {{ code }} - desc_403: Du har ikke adgang til denne side. - desc_404: Denne side findes desværre ikke. - desc_50X: Der skete en fejl på serveren og den kunne ikke fuldføre din anmodning. - back_home: Tilbage til forsiden - page_maintenance: - desc: "Vi laver vedligeholdelse, men er snart tilbage igen." - nav_menus: - dashboard: Kontrolpanel - contents: Indhold - questions: Spørgsmål - answers: Svar - users: Brugere - badges: Badges - flags: Anmeldelser - settings: Indstillinger - general: Generelt - interface: Brugerflade - smtp: SMTP - branding: Branding - legal: Jura - write: Skriv - terms: Terms - tos: Betingelser for brug - privacy: Privatliv - seo: SEO - customize: Tilpas - themes: Temaer - login: Log Ind - privileges: Rettigheder - plugins: Plugins - installed_plugins: Installerede Plugins - apperance: Appearance - website_welcome: Velkommen til {{site_name}} - user_center: - login: Log Ind - qrcode_login_tip: Brug {{ agentName }} til at scanne QR-koden og logge ind. - login_failed_email_tip: Log ind mislykkedes, tillad denne app at få adgang til dine e-mail-oplysninger, før du prøver igen. - badges: - modal: - title: Congratulations - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - admin: - admin_header: - title: Administrator - dashboard: - title: Kontrolpanel - welcome: Velkommen til Administration! - site_statistics: Statistik for webstedet - questions: "Spørgsmål:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "Svar:" - comments: "Kommentarer:" - votes: "Stemmer:" - users: "Brugere:" - flags: "Anmeldelser:" - reviews: "Gennemgange:" - site_health: Websteds sundhed - version: "Version:" - https: "HTTPS:" - upload_folder: "Upload mappe:" - run_mode: "Kørselstilstand:" - private: Privat - public: Offentlig - smtp: "SMTP:" - timezone: "Tidszone:" - system_info: System information - go_version: "Go version:" - database: "Database:" - database_size: "Database størrelse:" - storage_used: "Anvendt lagerplads:" - uptime: "Oppetid:" - links: Links - plugins: Plugins - github: GitHub - blog: Blog - contact: Kontakt os - forum: Forum - documents: Dokumenter - feedback: Tilbagemelding - support: Support - review: Gennemgå - config: Konfiguration - update_to: Opdatér til - latest: Seneste - check_failed: Tjek mislykkedes - "yes": "Ja" - "no": "Nej" - not_allowed: Ikke tilladt - allowed: Tilladt - enabled: Aktiveret - disabled: Deaktiveret - writable: Skrivbar - not_writable: Ikke skrivbar - flags: - title: Anmeldelser - pending: Ventende - completed: Gennemført - flagged: Anmeldt - flagged_type: Anmeldt{{ type }} - created: Oprettet - action: Handling - review: Gennemgå - user_role_modal: - title: Skift brugerrolle til... - btn_cancel: Annuller - btn_submit: Indsend - new_password_modal: - title: Angiv ny adgangskode - form: - fields: - password: - label: Adgangskode - text: Brugeren vil blive logget ud og skal logge ind igen. - msg: Adgangskoden skal være på 8- 32 tegn. - btn_cancel: Annuller - btn_submit: Indsend - edit_profile_modal: - title: Rediger profil - form: - fields: - display_name: - label: Visnings-navn - msg_range: Display name must be 2-30 characters in length. - username: - label: Brugernavn - msg_range: Username must be 2-30 characters in length. - email: - label: E-mail - msg_invalid: Ugyldig E-Mail Adresse. - edit_success: Redigering lykkedes - btn_cancel: Annuller - btn_submit: Indsend - user_modal: - title: Tilføj ny bruger - form: - fields: - users: - label: Masse-tilføj bruger - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Adskil “navn, e-mail, adgangskode” med kommaer. Én bruger pr. linje. - msg: "Indtast venligst brugerens e-mail, en pr. linje." - display_name: - label: Visnings-navn - msg: Display name must be 2-30 characters in length. - email: - label: E-mail - msg: E-mail er ugyldig. - password: - label: Adgangskode - msg: Adgangskoden skal være 8- 32 tegn. - btn_cancel: Annuller - btn_submit: Indsend - users: - title: Brugere - name: Navn - email: E-mail - reputation: Omdømme - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Status - role: Rolle - action: Handling - change: Ændre - all: Alle - staff: Ansatte - more: Mere - inactive: Inaktiv - suspended: Suspenderet - deleted: Slettet - normal: Normal - Moderator: Moderator - Admin: Administrator - User: Bruger - filter: - placeholder: "Filtrer efter navn, user:id" - set_new_password: Angiv ny adgangskode - edit_profile: Rediger profil - change_status: Ændre status - change_role: Ændre rolle - show_logs: Vis logfiler - add_user: Tilføj bruger - deactivate_user: - title: Deaktiver bruger - content: En inaktiv bruger skal bekræfte deres e-mail igen. - delete_user: - title: Slet denne bruger - content: Er du sikker på, at du vil slette denne bruger? Dette er permanent! - remove: Fjern deres indhold - label: Fjern alle spørgsmål, svar, kommentarer osv. - text: Tjek ikke dette, hvis du kun ønsker at slette brugerens konto. - suspend_user: - title: Suspendér denne bruger - content: En suspenderet bruger kan ikke logge ind. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Spørgsmål - unlisted: Fjernet fra liste - post: Indlæg - votes: Stemmer - answers: Svar - created: Oprettet - status: Status - action: Handling - change: Ændre - pending: Ventende - filter: - placeholder: "Filtrer efter titel, question:id" - answers: - page_title: Svar - post: Indlæg - votes: Stemmer - created: Oprettet - status: Status - action: Handling - change: Ændre - filter: - placeholder: "Filtrer efter titel, answer:id" - general: - page_title: Generelt - name: - label: Websted navn - msg: Websted-navn skal udfyldes. - text: "Navnet på dette websted, som bruges i title-tagget." - site_url: - label: Websted URL - msg: Websted-URL skal udfyldes. - validate: Angiv et gyldigt URL. - text: Adressen på dit websted. - short_desc: - label: Kort beskrivelse af websted - msg: Kort beskrivelse af websted skal udfyldes. - text: "Kort beskrivelse, som anvendt i title-tag på hjemmesiden." - desc: - label: Websted beskrivelse - msg: Webstedsbeskrivelse skal udfyldes. - text: "Beskriv dette websted i en sætning, som bruges i meta description tagget." - contact_email: - label: Kontakt e-mail - msg: Kontakt-e-mail skal udfyldes. - validate: Kontakt-e-mail er ugyldig. - text: E-mailadresse på nøglekontakt ansvarlig for dette websted. - check_update: - label: Opdatering af software - text: Søg automatisk efter opdateringer - interface: - page_title: Brugerflade - language: - label: Brugerflade sprog - msg: Brugerflade-sprog skal udfyldes. - text: Brugergrænseflade sprog. Det vil ændres, når du opdaterer siden. - time_zone: - label: Tidszone - msg: Tidszone skal udfyldes. - text: Vælg en by i samme tidszone som dig selv. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: Fra e-mail - msg: Fra e-mail skal udfyldes. - text: E-mail-adressen som e-mails sendes fra. - from_name: - label: Fra navn - msg: Fra navn skal udfyldes. - text: Navnet som e-mails sendes fra. - smtp_host: - label: SMTP host - msg: SMTP host skal udfyldes. - text: Din mail-server. - encryption: - label: Kryptering - msg: Kryptering skal udfyldes. - text: For de fleste servere er SSL den anbefalede indstilling. - ssl: SSL - tls: TLS - none: Ingen - smtp_port: - label: SMTP port - msg: SMTP port skal være nummer 1 ~ 65535. - text: Porten til din mailserver. - smtp_username: - label: SMTP brugernavn - msg: SMTP brugernavn skal udfyldes. - smtp_password: - label: SMTP adgangskode - msg: SMTP adgangskode skal udfyldes. - test_email_recipient: - label: Test e-mail modtagere - text: Angiv e-mail-adresse, der vil modtage test-beskedder. - msg: Test e-mail modtagere er ugyldige - smtp_authentication: - label: Aktiver autentificering - title: SMTP autentificering - msg: SMTP autentificering skal udfyldes. - "yes": "Ja" - "no": "Nej" - branding: - page_title: Branding - logo: - label: Logo - msg: Logo skal udfyldes. - text: Logoet billede øverst til venstre på dit websted. Brug et bredt rektangulært billede med en højde på 56 og et breddeforhold større end 3:1. Hvis efterladt tom, vil webstedets titeltekst blive vist. - mobile_logo: - label: Mobil logo - text: Logoet bruges på mobile version af dit websted. Brug et bredt rektangulært billede med en højde på 56. Hvis efterladt tom, vil billedet fra indstillingen "logo" blive brugt. - square_icon: - label: Kvadratisk ikon - msg: Kvadratisk ikon skal udfyldes. - text: Billede brugt som basis for metadata-ikoner. Bør være større end 512x512. - favicon: - label: Favicon - text: En favicon til dit websted. For at fungere korrekt over en CDN skal det være en png. Vil blive ændret til 32x32. Hvis efterladt tomt, vil "firkantet ikon" blive brugt. - legal: - page_title: Jura - terms_of_service: - label: Betingelser for brug - text: "Du kan tilføje servicevilkår her. Hvis du allerede har et dokument hostet et andet sted, så angiv den fulde URL her." - privacy_policy: - label: Privatlivspolitik - text: "Du kan tilføje privatlivspolitik indhold her. Hvis du allerede har et dokument hostet et andet sted, så angiv den fulde URL her." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Skriv - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Skriv svar - label: Hver bruger kan kun skrive et svar for det samme spørgsmål - text: "Slå fra for at give brugerne mulighed for at skrive flere svar på det samme spørgsmål, hvilket kan forårsage svar at være ufokuseret." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Anbefal tags - text: "Anbefal tags vil som standard blive vist i dropdown-listen." - msg: - contain_reserved: "anbefalede tags kan ikke indeholde reserverede tags" - required_tag: - title: Angiv påkrævede tags - label: Sæt “Anbefal tags” som påkrævede tags - text: "Hvert nyt spørgsmål skal have mindst et anbefalet tag." - reserved_tags: - label: Reserverede tags - text: "Reserverede tags kan kun bruges af moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: SEO - permalink: - label: Permalink - text: Brugerdefinerede URL-strukturer kan forbedre brugervenlighed og fremadrettet kompatibilitet af dine links. - robots: - label: robots.txt - text: Dette vil permanent tilsidesætte eventuelle relaterede webstedsindstillinger. - themes: - page_title: Temaer - themes: - label: Temaer - text: Vælg et eksisterende tema. - color_scheme: - label: Farveskema - navbar_style: - label: Navbar background style - primary_color: - label: Primær farve - text: Ændre farver, der bruges af dine temaer - css_and_html: - page_title: CSS og HTML - custom_css: - label: Brugerdefineret CSS - text: > - - head: - label: Head - text: > - - header: - label: Overskrift - text: > - - footer: - label: Sidefod - text: Dette indsættes før </body>. - sidebar: - label: Sidebjælke - text: Dette vil indsætte i sidebjælken. - login: - page_title: Log Ind - membership: - title: Medlemskab - label: Tillad nye registreringer - text: Slå fra for at forhindre at nogen opretter en ny konto. - email_registration: - title: E-mail-registrering - label: Tillad e-mail registrering - text: Slå fra for at forhindre, at der oprettes en ny konto via e-mail. - allowed_email_domains: - title: Tilladte e-mail-domæner - text: E-mail-domæner som brugere skal registrere konti med. Et domæne pr. linje. Ignoreres når tomt. - private: - title: Privat - label: Log ind påkrævet - text: Kun brugere som er logget ind har adgang til dette fællesskab. - password_login: - title: Adgangskode log ind - label: Tillad e-mail og adgangskode login - text: "ADVARSEL: Hvis du slår fra, kan du muligvis ikke logge ind, hvis du ikke tidligere har konfigureret en anden loginmetode." - installed_plugins: - title: Installerede Plugins - plugin_link: Plugins udvider og udvider funktionaliteten. Du kan finde plugins i <1>Plugin Repository. - filter: - all: Alle - active: Aktiv - inactive: Inaktiv - outdated: Forældet - plugins: - label: Plugins - text: Vælg et eksisterende plugin. - name: Navn - version: Version - status: Status - action: Handling - deactivate: Deaktiver - activate: Aktivér - settings: Indstillinger - settings_users: - title: Brugere - avatar: - label: Standard avatar - text: For brugere uden en brugerdefineret avatar. - gravatar_base_url: - label: Gravatar base-URL - text: URL for Gravatar-udbyderens API-base. Ignoreres når tom. - profile_editable: - title: Profil redigerbar - allow_update_display_name: - label: Tillad brugere at ændre deres visningsnavn - allow_update_username: - label: Tillad brugere at ændre deres brugernavn - allow_update_avatar: - label: Tillad brugere at ændre deres profilbillede - allow_update_bio: - label: Tillad brugere at ændre deres om-mig - allow_update_website: - label: Tillad brugere at ændre deres hjemmeside - allow_update_location: - label: Tillad brugere at ændre deres placering - privilege: - title: Rettigheder - level: - label: Omdømme påkrævet niveau - text: Vælg det omdømme der kræves for rettighederne - msg: - should_be_number: input skal være et tal - number_larger_1: tal skal være lig med eller større end 1 - badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate - filter: - placeholder: Filter by name, badge:id - group: Group - inactive: Inactive - name: Name - show_logs: Show logs - status: Status - title: Badges - form: - optional: (valgfrit) - empty: skal udfyldes - invalid: er ugyldigt - btn_submit: Gem - not_found_props: "Nødvendig egenskab {{ key }} ikke fundet." - select: Vælg - page_review: - review: Gennemgå - proposed: foreslået - question_edit: Rediger spørgsmål - answer_edit: Svar redigér - tag_edit: Tag redigér - edit_summary: Rediger resumé - edit_question: Rediger spørgsmål - edit_answer: Rediger svar - edit_tag: Rediger tag - empty: Ingen gennemgangsopgaver tilbage. - approve_revision_tip: Godkender du denne revision? - approve_flag_tip: Godkender du denne anmeldelse? - approve_post_tip: Godkender du dette indlæg? - approve_user_tip: Godkender du denne bruger? - suggest_edits: Foreslåede redigeringer - flag_post: Anmeld indlæg - flag_user: Anmeld bruger - queued_post: Indlæg i kø - queued_user: Brugere i kø - filter_label: Type - reputation: omdømme - flag_post_type: Anmeld dette indlæg som {{ type }}. - flag_user_type: Anmeldte dette indlæg som {{ type }}. - edit_post: Rediger opslag - list_post: Sæt indlæg på liste - unlist_post: Fjern indlæg fra liste - timeline: - undeleted: genskabt - deleted: slettet - downvote: stem ned - upvote: stem op - accept: acceptér - cancelled: annulleret - commented: kommenteret - rollback: tilbagerul - edited: redigeret - answered: besvaret - asked: spurgt - closed: lukket - reopened: genåbnet - created: oprettet - pin: fastgjort - unpin: frigjort - show: sat på liste - hide: fjernet fra liste - title: "Historik for" - tag_title: "Tidslinje for" - show_votes: "Vis stemmer" - n_or_a: Ikke Relevant - title_for_question: "Tidslinje for" - title_for_answer: "Tidslinje for svar på {{ title }} af {{ author }}" - title_for_tag: "Tidslinje for tag" - datetime: Datetime - type: Type - by: Af - comment: Kommentar - no_data: "Vi kunne ikke finde noget." - users: - title: Brugere - users_with_the_most_reputation: Brugere med det højeste omdømme scorer denne uge - users_with_the_most_vote: Brugere, der stemte mest i denne uge - staffs: Vores fællesskabs personale - reputation: omdømme - votes: stemmer - prompt: - leave_page: Er du sikker på, at du vil forlade siden? - changes_not_save: Dine ændringer er muligvis ikke gemt. - draft: - discard_confirm: Er du sikker på, at du vil kassere dit udkast? - messages: - post_deleted: Dette indlæg er blevet slettet. - post_cancel_deleted: This post has been undeleted. - post_pin: Dette indlæg er blevet fastgjort. - post_unpin: Dette indlæg er blevet frigjort. - post_hide_list: Dette indlæg er blevet skjult fra listen. - post_show_list: Dette indlæg er blevet vist på listen. - post_reopen: Dette indlæg er blevet genåbnet. - post_list: Dette indlæg er blevet listet. - post_unlist: Dette indlæg er blevet aflistet. - post_pending: Dit indlæg afventer gennemgang. Dette er en forhåndsvisning, det vil være synligt, når det er blevet godkendt. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/de_DE.yaml b/data/i18n/de_DE.yaml deleted file mode 100644 index 3e89b8d16..000000000 --- a/data/i18n/de_DE.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Erfolgreich. - unknown: - other: Unbekannter Fehler. - request_format_error: - other: Format der Anfrage ist ungültig. - unauthorized_error: - other: Nicht autorisiert. - database_error: - other: Datenbank-Fehler. - forbidden_error: - other: Verboten. - duplicate_request_error: - other: Doppelte Einreichung. - action: - report: - other: Melden - edit: - other: Bearbeiten - delete: - other: Löschen - close: - other: Schließen - reopen: - other: Wieder öffnen - forbidden_error: - other: Verboten. - pin: - other: Anpinnen - hide: - other: Von Liste nehmen - unpin: - other: Loslösen - show: - other: Liste - invite_someone_to_answer: - other: Bearbeiten - undelete: - other: Wiederherstellen - merge: - other: Zusammenführen - role: - name: - user: - other: Benutzer - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Standard ohne speziellen Zugriff. - admin: - other: Habe die volle Berechtigung, auf die Seite zuzugreifen. - moderator: - other: Hat Zugriff auf alle Beiträge außer Admin-Einstellungen. - privilege: - level_1: - description: - other: Level 1 (weniger Reputation für privates Team, Gruppen) - level_2: - description: - other: Level 2 (niedrige Reputation für Startup-Community) - level_3: - description: - other: Level 3 (hohe Reputation für eine reife Community) - level_custom: - description: - other: Benutzerdefinierter Level - rank_question_add_label: - other: Fragen stellen - rank_answer_add_label: - other: Antwort schreiben - rank_comment_add_label: - other: Kommentar schreiben - rank_report_add_label: - other: Melden - rank_comment_vote_up_label: - other: Kommentar upvoten - rank_link_url_limit_label: - other: Mehr als 2 Links gleichzeitig posten - rank_question_vote_up_label: - other: Frage upvoten - rank_answer_vote_up_label: - other: Antwort upvoten - rank_question_vote_down_label: - other: Frage downvoten - rank_answer_vote_down_label: - other: Antwort downvoten - rank_invite_someone_to_answer_label: - other: Jemanden zum Antworten einladen - rank_tag_add_label: - other: Neuen Tag erstellen - rank_tag_edit_label: - other: Tag-Beschreibung bearbeiten (muss überprüft werden) - rank_question_edit_label: - other: Frage eines anderen bearbeiten (muss überarbeitet werden) - rank_answer_edit_label: - other: Antwort eines anderen bearbeiten (muss überarbeitet werden) - rank_question_edit_without_review_label: - other: Frage eines anderen ohne Überprüfung bearbeiten - rank_answer_edit_without_review_label: - other: Antwort eines anderen ohne Überprüfung bearbeiten - rank_question_audit_label: - other: Frageänderungen überprüfen - rank_answer_audit_label: - other: Bearbeitete Antworten überprüfen - rank_tag_audit_label: - other: Tag-Bearbeitungen überprüfen - rank_tag_edit_without_review_label: - other: Tag-Beschreibung ohne Überprüfung bearbeiten - rank_tag_synonym_label: - other: Tag-Synonyme verwalten - email: - other: E-Mail - e_mail: - other: E-Mail - password: - other: Passwort - pass: - other: Passwort - old_pass: - other: Aktuelles Passwort - original_text: - other: Dieser Beitrag - email_or_password_wrong_error: - other: E-Mail und Passwort stimmen nicht überein. - error: - common: - invalid_url: - other: Ungültige URL. - status_invalid: - other: Ungültiger Status. - password: - space_invalid: - other: Passwort darf keine Leerzeichen enthalten. - admin: - cannot_update_their_password: - other: Du kannst dein Passwort nicht ändern. - cannot_edit_their_profile: - other: Du kannst dein Profil nicht bearbeiten. - cannot_modify_self_status: - other: Du kannst deinen Status nicht ändern. - email_or_password_wrong: - other: E-Mail und Password stimmen nicht überein. - answer: - not_found: - other: Antwort nicht gefunden. - cannot_deleted: - other: Keine Berechtigung zum Löschen. - cannot_update: - other: Keine Berechtigung zum Aktualisieren. - question_closed_cannot_add: - other: Fragen sind geschlossen und können nicht hinzugefügt werden. - content_cannot_empty: - other: Die Antwort darf nicht leer sein. - comment: - edit_without_permission: - other: Kommentar kann nicht bearbeitet werden. - not_found: - other: Kommentar wurde nicht gefunden. - cannot_edit_after_deadline: - other: Die Kommentarzeit war zu lang, um sie zu ändern. - content_cannot_empty: - other: Der Kommentar darf nicht leer sein. - email: - duplicate: - other: E-Mail existiert bereits. - need_to_be_verified: - other: E-Mail muss überprüft werden. - verify_url_expired: - other: Die verifizierbare E-Mail-URL ist abgelaufen, bitte sende die E-Mail erneut. - illegal_email_domain_error: - other: E-Mails sind von dieser E-Mail-Domäne nicht erlaubt. Bitte verwende eine andere. - lang: - not_found: - other: Sprachdatei nicht gefunden. - object: - captcha_verification_failed: - other: Captcha ist falsch. - disallow_follow: - other: Es ist dir nicht erlaubt zu folgen. - disallow_vote: - other: Es ist dir nicht erlaubt abzustimmen. - disallow_vote_your_self: - other: Du kannst nicht für deinen eigenen Beitrag stimmen. - not_found: - other: Objekt nicht gefunden. - verification_failed: - other: Verifizierung fehlgeschlagen. - email_or_password_incorrect: - other: E-Mail und Passwort stimmen nicht überein. - old_password_verification_failed: - other: Die Überprüfung des alten Passworts ist fehlgeschlagen - new_password_same_as_previous_setting: - other: Das neue Passwort ist das gleiche wie das vorherige Passwort. - already_deleted: - other: Dieser Beitrag wurde gelöscht. - meta: - object_not_found: - other: Metaobjekt nicht gefunden - question: - already_deleted: - other: Dieser Beitrag wurde gelöscht. - under_review: - other: Ihr Beitrag wartet auf Überprüfung. Er wird sichtbar sein, nachdem er genehmigt wurde. - not_found: - other: Frage nicht gefunden. - cannot_deleted: - other: Keine Berechtigung zum Löschen. - cannot_close: - other: Keine Berechtigung zum Schließen. - cannot_update: - other: Keine Berechtigung zum Aktualisieren. - content_cannot_empty: - other: Der Inhalt darf nicht leer sein. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Ansehenssrang erfüllt die Bedingung nicht. - vote_fail_to_meet_the_condition: - other: Danke für dein Feedback. Du brauchst mindestens {{.Rank}} Ansehen, um eine Stimme abzugeben. - no_enough_rank_to_operate: - other: Dafür brauchst du mindestens {{.Rank}} Ansehen. - report: - handle_failed: - other: Bearbeiten der Meldung fehlgeschlagen. - not_found: - other: Meldung nicht gefunden. - tag: - already_exist: - other: Tag existiert bereits. - not_found: - other: Tag nicht gefunden. - recommend_tag_not_found: - other: Das Tag "Empfehlen" ist nicht vorhanden. - recommend_tag_enter: - other: Bitte gib mindestens einen erforderlichen Tag ein. - not_contain_synonym_tags: - other: Sollte keine Synonym-Tags enthalten. - cannot_update: - other: Keine Berechtigung zum Aktualisieren. - is_used_cannot_delete: - other: Du kannst keinen Tag löschen, der in Gebrauch ist. - cannot_set_synonym_as_itself: - other: Du kannst das Synonym des aktuellen Tags nicht als sich selbst festlegen. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: Der Absendername kann keine E-Mail-Adresse sein. - theme: - not_found: - other: Design nicht gefunden. - revision: - review_underway: - other: Kann derzeit nicht bearbeitet werden, es existiert eine Version in der Überprüfungswarteschlange. - no_permission: - other: Keine Berechtigung zum Überarbeiten. - user: - external_login_missing_user_id: - other: Die Plattform des Drittanbieters stellt keine eindeutige UserID zur Verfügung, sodass du dich nicht anmelden kannst. Bitte wende dich an den Administrator der Website. - external_login_unbinding_forbidden: - other: Bitte setze ein Login-Passwort für dein Konto, bevor du dieses Login entfernst. - email_or_password_wrong: - other: - other: E-Mail und Passwort stimmen nicht überein. - not_found: - other: Benutzer nicht gefunden. - suspended: - other: Benutzer wurde gesperrt. - username_invalid: - other: Benutzername ist ungültig. - username_duplicate: - other: Benutzername wird bereits verwendet. - set_avatar: - other: Avatar setzen fehlgeschlagen. - cannot_update_your_role: - other: Du kannst deine Rolle nicht ändern. - not_allowed_registration: - other: Derzeit ist die Seite nicht für die Anmeldung geöffnet. - not_allowed_login_via_password: - other: Zurzeit ist es auf der Seite nicht möglich, sich mit einem Passwort anzumelden. - access_denied: - other: Zugriff verweigert - page_access_denied: - other: Du hast keinen Zugriff auf diese Seite. - add_bulk_users_format_error: - other: "Fehler {{.Field}}-Format in der Nähe von '{{.Content}}' in Zeile {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "Die Anzahl der Benutzer, die du auf einmal hinzufügst, sollte im Bereich von 1-{{.MaxAmount}} liegen." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Lesekonfiguration fehlgeschlagen - database: - connection_failed: - other: Datenbankverbindung fehlgeschlagen - create_table_failed: - other: Tabelle erstellen fehlgeschlagen - install: - create_config_failed: - other: Kann die config.yaml-Datei nicht erstellen. - upload: - unsupported_file_format: - other: Dateiformat nicht unterstützt. - site_info: - config_not_found: - other: Seiten-Konfiguration nicht gefunden. - badge: - object_not_found: - other: Abzeichen-Objekt nicht gefunden - reason: - spam: - name: - other: Spam - desc: - other: Dieser Beitrag ist eine Werbung oder Vandalismus. Er ist nicht nützlich oder relevant für das aktuelle Thema. - rude_or_abusive: - name: - other: unhöflich oder beleidigend - desc: - other: "Eine vernünftige Person würde diesen Inhalt im respektvoll diskutierten Diskurs für unangemessen halten." - a_duplicate: - name: - other: ein Duplikat - desc: - other: Diese Frage wurde schon einmal gestellt und hat bereits eine Antwort. - placeholder: - other: Gib den Link zur bestehenden Frage ein - not_a_answer: - name: - other: keine Antwort - desc: - other: "Die Antwort versucht nicht, die Frage zu beantworten. Sie sollte entweder bearbeitet, kommentiert, als weitere Frage gestellt oder ganz gelöscht werden." - no_longer_needed: - name: - other: nicht mehr benötigt - desc: - other: Dieser Kommentar ist veraltet oder nicht relevant für diesen Beitrag. - something: - name: - other: anderer Grund - desc: - other: Dieser Beitrag erfordert die Aufmerksamkeit der Temmitglieder aus einem anderen, oben nicht genannten Grund. - placeholder: - other: Lass uns wissen, worüber du dir Sorgen machst - community_specific: - name: - other: ein Community-spezifischer Grund - desc: - other: Diese Frage entspricht nicht den Gemeinschaftsrichtlinien. - not_clarity: - name: - other: benötigt Details oder Klarheit - desc: - other: Diese Frage enthält derzeit mehrere Fragen in einer. Sie sollte sich auf ein einziges Problem konzentrieren. - looks_ok: - name: - other: sieht OK aus - desc: - other: Dieser Beitrag ist gut so wie er ist und nicht von schlechter Qualität. - needs_edit: - name: - other: muss bearbeitet werden, und ich habe es getan - desc: - other: Verbessere und korrigiere Probleme mit diesem Beitrag selbst. - needs_close: - name: - other: muss geschlossen werden - desc: - other: Eine geschlossene Frage kann nicht beantwortet werden, aber du kannst sie trotzdem bearbeiten, abstimmen und kommentieren. - needs_delete: - name: - other: muss gelöscht werden - desc: - other: Dieser Beitrag wird gelöscht. - question: - close: - duplicate: - name: - other: Spam - desc: - other: Diese Frage ist bereits gestellt worden und hat bereits eine Antwort. - guideline: - name: - other: ein Community-spezifischer Grund - desc: - other: Diese Frage entspricht nicht einer Gemeinschaftsrichtlinie. - multiple: - name: - other: benötigt Details oder Klarheit - desc: - other: Diese Frage enthält derzeit mehrere Fragen in einer. Sie sollte sich auf ein einziges Problem konzentrieren. - other: - name: - other: etwas anderes - desc: - other: Dieser Beitrag erfordert einen anderen Grund, der oben nicht aufgeführt ist. - operation_type: - asked: - other: gefragt - answered: - other: beantwortet - modified: - other: geändert - deleted_title: - other: Gelöschte Frage - questions_title: - other: Fragen - tag: - tags_title: - other: Schlagwörter - no_description: - other: Diese Kategorie hat keine Beschreibung. - notification: - action: - update_question: - other: aktualisierte Frage - answer_the_question: - other: beantwortete Frage - update_answer: - other: aktualisierte Antwort - accept_answer: - other: akzeptierte Antwort - comment_question: - other: kommentierte Frage - comment_answer: - other: kommentierte Antwort - reply_to_you: - other: hat Ihnen geantwortet - mention_you: - other: hat dich erwähnt - your_question_is_closed: - other: Deine Frage wurde geschlossen - your_question_was_deleted: - other: Deine Frage wurde gelöscht - your_answer_was_deleted: - other: Deine Antwort wurde gelöscht - your_comment_was_deleted: - other: Dein Kommentar wurde gelöscht - up_voted_question: - other: positiv bewertete Frage - down_voted_question: - other: negativ bewertete Frage - up_voted_answer: - other: positiv bewertete Antwort - down_voted_answer: - other: negativ bewertete Antwort - up_voted_comment: - other: positiv bewerteter Kommentar - invited_you_to_answer: - other: hat dich eingeladen, zu antworten - earned_badge: - other: Du hast das "{{.BadgeName}}" Abzeichen verdient - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Bestätige deine neue E-Mail-Adresse" - body: - other: "Bestätigen Sie Ihre neue E-Mail-Adresse für {{.SiteName}} indem Sie auf den folgenden Link klicken:
        \n{{.ChangeEmailUrl}}

        \n\nWenn Sie diese Änderung nicht angefordert haben bitte diese E-Mail ignorieren.

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, Bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht angezeigt wird." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} hat deine Frage beantwortet" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \n\nAuf {{.SiteName}} anschauen

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht angezeigt wird.

        \n\nAbmelden" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} hat dich eingeladen zu antworten" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Ich denke, Sie kennen die Antwort.

        \n {{.SiteName}}

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, Bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht angezeigt wird.

        \n\nAbmelden" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} hat deinen Beitrag kommentiert" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \n\nAuf {{.SiteName}} anschauen

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, Bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht angezeigt wird.

        \n\nAbmelden" - new_question: - title: - other: "[{{.SiteName}}] Neue Frage: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nHinweis: Dies ist eine automatische Systemnachricht, bitte antworten Sie nicht darauf. Antworten werden nicht gelesen oder bearbeitet.

        \n\nBenachrichtigung abbestellen" - pass_reset: - title: - other: "[{{.SiteName }}] Passwort zurücksetzen" - body: - other: "Jemand bat darum, Ihr Passwort auf {{.SiteName}}zurückzusetzen.

        \n\nWenn Sie es nicht waren, können Sie diese E-Mail sicher ignorieren.

        \n\nKlicken Sie auf den folgenden Link, um ein neues Passwort auszuwählen:
        \n{{.PassResetUrl}}\n\n

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, Bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht angezeigt wird." - register: - title: - other: "[{{.SiteName}}] Bestätige dein neues Konto" - body: - other: "Willkommen in {{.SiteName}}!

        \n\nKlicken Sie auf den folgenden Link, um Ihr neues Konto zu bestätigen und zu aktivieren:
        \n{{.RegisterUrl}}

        \n\nWenn der obige Link nicht anklickbar ist kopieren und in die Adressleiste Ihres Webbrowsers einfügen.\n

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, Bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht sichtbar ist." - test: - title: - other: "[{{.SiteName}}] Test-E-Mail" - body: - other: "Dies ist eine Test-E-Mail.\n

        \n\n--
        \nHinweis: Dies ist eine automatische System-E-Mail, Bitte antworten Sie nicht auf diese Nachricht, da Ihre Antwort nicht angezeigt wird." - action_activity_type: - upvote: - other: positiv bewerten - upvoted: - other: positiv bewertet - downvote: - other: negativ bewerten - downvoted: - other: negativ bewertet - accept: - other: akzeptieren - accepted: - other: akzeptiert - edit: - other: bearbeiten - review: - queued_post: - other: Post in der Warteschlange - flagged_post: - other: Beiträge gemeldet - suggested_post_edit: - other: Änderungsvorschläge - reaction: - tooltip: - other: "{{ .Names }} Und {{ .Count }} mehr..." - badge: - default_badges: - autobiographer: - name: - other: Autobiograph - desc: - other: Gefüllt mit Profil Informationen. - certified: - name: - other: Zertifiziert - desc: - other: Erledigte unser neues Benutzerhandbuch. - editor: - name: - other: Editor - desc: - other: Erster Beitrag bearbeiten. - first_flag: - name: - other: Erste Meldung - desc: - other: Erste Meldung eines Beitrags. - first_upvote: - name: - other: Erster Upvote - desc: - other: Erste Like eines Beitrags. - first_link: - name: - other: Erster Link - desc: - other: Hat erstmals einen Link zu einem anderen Beitrag hinzugefügt. - first_reaction: - name: - other: Erste Reaktion - desc: - other: Zuerst reagierte auf den Beitrag. - first_share: - name: - other: Erstes Teilen - desc: - other: Zuerst einen Beitrag geteilt. - scholar: - name: - other: Gelehrter - desc: - other: Hat eine Frage gestellt und eine Antwort akzeptiert. - commentator: - name: - other: Kommentator - desc: - other: Hinterlassen Sie 5 Kommentare. - new_user_of_the_month: - name: - other: Neuer Benutzer des Monats - desc: - other: Ausstehende Beiträge in ihrem ersten Monat. - read_guidelines: - name: - other: Lesen Sie die Richtlinien - desc: - other: Lesen Sie die [Community-Richtlinien]. - reader: - name: - other: Leser - desc: - other: Lesen Sie alle Antworten in einem Thema mit mehr als 10 Antworten. - welcome: - name: - other: Willkommen - desc: - other: Du hast eine positive Abstimmung erhalten. - nice_share: - name: - other: Schöne teilen - desc: - other: Hat einen Beitrag mit 25 einzigartigen Besuchern freigegeben. - good_share: - name: - other: Gut geteilt - desc: - other: Hat einen Beitrag mit 300 einzigartigen Besuchern freigegeben. - great_share: - name: - other: Großartiges Teilen - desc: - other: Hat einen Beitrag mit 1000 einzigartigen Besuchern freigegeben. - out_of_love: - name: - other: Aus Liebe - desc: - other: Hat an einem Tag 50 Upvotes verwendet. - higher_love: - name: - other: Höhere Liebe - desc: - other: Hat an einem Tag 50 Upvotes 5 Mal verwendet. - crazy_in_love: - name: - other: Im siebten Himmel - desc: - other: Hat an einem Tag 50 Upvotes 20 Mal verwendet. - promoter: - name: - other: Förderer - desc: - other: Hat einen Benutzer eingeladen. - campaigner: - name: - other: Kampagnenleiter - desc: - other: Lade 3 einfache Benutzer ein. - champion: - name: - other: Champion - desc: - other: Hat 5 Mitglieder eingeladen. - thank_you: - name: - other: Vielen Dank - desc: - other: Beitrag mit 20 Upvotes und 10 abgegebenen Upvotes. - gives_back: - name: - other: Feedback geben - desc: - other: Beitrag mit 100 Upvotes und 100 abgegebenen Upvotes. - empathetic: - name: - other: Einfühlsam - desc: - other: Beitrag mit 500 Upvotes und 1000 abgegebenen Upvotes. - enthusiast: - name: - other: Enthusiast - desc: - other: Besucht 10 aufeinander folgende Tage. - aficionado: - name: - other: Aficionado - desc: - other: Besucht 100 aufeinander folgende Tage. - devotee: - name: - other: Anhänger - desc: - other: 365 aufeinander folgende Tage besucht. - anniversary: - name: - other: Jahrestag - desc: - other: Aktives Mitglied für ein Jahr, mindestens einmal veröffentlicht. - appreciated: - name: - other: Gewertschätzt - desc: - other: Erhalten 1 up vote für 20 posts. - respected: - name: - other: Respektiert - desc: - other: Erhalten 2 up vote für 100 posts. - admired: - name: - other: Bewundert - desc: - other: 5 upvotes für 300 posts erhalten. - solved: - name: - other: Gelöst - desc: - other: Eine Antwort wurde akzeptiert. - guidance_counsellor: - name: - other: Anleitungsberater - desc: - other: 10 Antworten wurden akzeptiert. - know_it_all: - name: - other: Alleswisser - desc: - other: 50 Antworten wurden akzeptiert. - solution_institution: - name: - other: Lösungsfinder - desc: - other: 150 Antworten wurden akzeptiert. - nice_answer: - name: - other: Nette Antwort - desc: - other: Die Antwortpunktzahl beträgt mehr als 10 Punkte. - good_answer: - name: - other: Gute Antwort - desc: - other: Die Antwortpunktzahl beträgt mehr als 25 Punkte. - great_answer: - name: - other: Großartige Antwort - desc: - other: Die Antwortpunktzahl beträgt mehr als 50 Punkte. - nice_question: - name: - other: Schöne Frage - desc: - other: Fragenpunktzahl von 10 oder mehr. - good_question: - name: - other: Gute Frage - desc: - other: Fragen mit 25 oder mehr Punkten. - great_question: - name: - other: Große Frage - desc: - other: Frage mit 50 oder mehr Punkten. - popular_question: - name: - other: Populäre Frage - desc: - other: Frage mit 500 Ansichten. - notable_question: - name: - other: Bemerkenswerte Frage - desc: - other: Frage mit 1.000 Ansichten. - famous_question: - name: - other: Erstklassige Frage - desc: - other: Frage mit 5.000 Ansichten. - popular_link: - name: - other: Populärer Link - desc: - other: Hat einen externen Link mit 50 Klicks gepostet. - hot_link: - name: - other: Heißer Link - desc: - other: Geschrieben einen externen Link mit 300 Klicks. - famous_link: - name: - other: Berühmter Link - desc: - other: Geschrieben einen externen Link mit 100 Klicks. - default_badge_groups: - getting_started: - name: - other: Erste Schritte - community: - name: - other: Gemeinschaft - posting: - name: - other: Freigeben -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Wie man formatiert - desc: >- -
        • einen Beitrag erwähnen: #post_id

        • um Links

          <https://url.com>

          [Titel](https://url.com)
        • Zwischen den Absätzen Zeilenumbrüche einfügen

        • _italic_ oder **fett**

        • Code um 4 Leerzeichen einrücken

        • Zitat durch Setzen von > am Anfang der Zeile

        • Backtick-Escapes `wie _this_`

        • Codeumrandungen mit Backticks `

          `
          Code hier
          ``
        - pagination: - prev: Zurück - next: Weiter - page_title: - question: Frage - questions: Fragen - tag: Schlagwort - tags: Schlagwörter - tag_wiki: tag Wiki - create_tag: Tag erstellen - edit_tag: Tag bearbeiten - ask_a_question: Create Question - edit_question: Frage bearbeiten - edit_answer: Antwort bearbeiten - search: Suchen - posts_containing: Beiträge enthalten - settings: Einstellungen - notifications: Benachrichtigungen - login: Anmelden - sign_up: Registrieren - account_recovery: Konto-Wiederherstellung - account_activation: Account Aktivierung - confirm_email: Bestätigungs-E-Mail - account_suspended: Konto gesperrt - admin: Verwaltung - change_email: E-Mails ändern - install: Installation beantworten - upgrade: Antwort-Upgrade - maintenance: Website-Wartung - users: Benutzer - oauth_callback: In Bearbeitung - http_404: HTTP-Fehler 404 - http_50X: HTTP-Fehler 500 - http_403: HTTP Fehler 403 - logout: Ausloggen - posts: Posts - notifications: - title: Benachrichtigungen - inbox: Posteingang - achievement: Erfolge - new_alerts: Neue Benachrichtigungen - all_read: Alle als gelesen markieren - show_more: Mehr anzeigen - someone: Jemand - inbox_type: - all: Alle - posts: Beiträge - invites: Einladungen - votes: Abstimmungen - answer: Antwort - question: Frage - badge_award: Abzeichen - suspended: - title: Dein Konto wurde gesperrt - until_time: "Dein Konto wurde bis zum {{ time }} gesperrt." - forever: Dieser Benutzer wurde für immer gesperrt. - end: Du erfüllst keine Community-Richtlinie. - contact_us: Kontaktiere uns - editor: - blockquote: - text: Blockzitat - bold: - text: Stark - chart: - text: Bestenliste - flow_chart: Flussdiagramm - sequence_diagram: Sequenzdiagramm - class_diagram: Klassen Diagramm - state_diagram: Zustandsdiagramm - entity_relationship_diagram: Entitätsbeziehungsdiagramm - user_defined_diagram: Benutzerdefiniertes Diagramm - gantt_chart: Gantt-Diagramm - pie_chart: Kuchendiagramm - code: - text: Code Beispiel - add_code: Code-Beispiel hinzufügen - form: - fields: - code: - label: Code - msg: - empty: Code kann nicht leer sein. - language: - label: Sprache - placeholder: Automatische Erkennung - btn_cancel: Abbrechen - btn_confirm: Hinzufügen - formula: - text: Formel - options: - inline: Inline Formel - block: Block Formel - heading: - text: Überschrift - options: - h1: Überschrift 1 - h2: Überschrift 2 - h3: Überschrift 3 - h4: Überschrift 4 - h5: Überschrift 5 - h6: Überschrift 6 - help: - text: Hilfe - hr: - text: Horizontale Richtlinie - image: - text: Bild - add_image: Bild hinzufügen - tab_image: Bild hochladen - form_image: - fields: - file: - label: Bilddatei - btn: Bild auswählen - msg: - empty: Datei darf nicht leer sein. - only_image: Nur Bilddateien sind erlaubt. - max_size: Dateigröße darf {{size}} MB nicht überschreiten. - desc: - label: Beschreibung - tab_url: Bild URL - form_url: - fields: - url: - label: Bild URL - msg: - empty: Bild-URL darf nicht leer sein. - name: - label: Beschreibung - btn_cancel: Abbrechen - btn_confirm: Hinzufügen - uploading: Hochladen - indent: - text: Einzug - outdent: - text: Ausrücken - italic: - text: Hervorhebung - link: - text: Hyperlink - add_link: Hyperlink hinzufügen - form: - fields: - url: - label: URL - msg: - empty: URL darf nicht leer sein. - name: - label: Beschreibung - btn_cancel: Abbrechen - btn_confirm: Hinzufügen - ordered_list: - text: Nummerierte Liste - unordered_list: - text: Aufzählungsliste - table: - text: Tabelle - heading: Überschrift - cell: Zelle - file: - text: Datei anhängen - not_supported: "Diesen Dateityp nicht unterstützen. Versuchen Sie es erneut mit {{file_type}}." - max_size: "Dateigröße anhängen darf {{size}} MB nicht überschreiten." - close_modal: - title: Ich schließe diesen Beitrag als... - btn_cancel: Abbrechen - btn_submit: Senden - remark: - empty: Kann nicht leer sein. - msg: - empty: Bitte wähle einen Grund aus. - report_modal: - flag_title: Ich melde diesen Beitrag als... - close_title: Ich schließe diesen Beitrag wegen ... - review_question_title: Frage prüfen - review_answer_title: Antwort prüfen - review_comment_title: Kommentar prüfen - btn_cancel: Abbrechen - btn_submit: Senden - remark: - empty: Kann nicht leer sein. - msg: - empty: Bitte wähle einen Grund aus. - not_a_url: URL hat ein falsches Format. - url_not_match: URL-Ursprung stimmt nicht mit der aktuellen Website überein. - tag_modal: - title: Neuen Tag erstellen - form: - fields: - display_name: - label: Anzeigename - msg: - empty: Anzeigename darf nicht leer sein. - range: Anzeige des Namens mit bis zu 35 Zeichen. - slug_name: - label: URL-Slug - desc: 'Muss den Zeichensatz "a-z", "0-9", "+ # - " verwenden.' - msg: - empty: URL-Slug darf nicht leer sein. - range: URL-Slug mit bis zu 35 Zeichen. - character: URL-Slug enthält nicht erlaubten Zeichensatz. - desc: - label: Beschreibung - revision: - label: Version - edit_summary: - label: Zusammenfassung bearbeiten - placeholder: >- - Erkläre kurz deine Änderungen (korrigierte Rechtschreibung, korrigierte Grammatik, verbesserte Formatierung) - btn_cancel: Abbrechen - btn_submit: Senden - btn_post: Neuen Tag erstellen - tag_info: - created_at: Erstellt - edited_at: Bearbeitet - history: Verlauf - synonyms: - title: Synonyme - text: Die folgenden Tags werden neu zugeordnet zu - empty: Keine Synonyme gefunden. - btn_add: Synonym hinzufügen - btn_edit: Bearbeiten - btn_save: Speichern - synonyms_text: Die folgenden Tags werden neu zugeordnet zu - delete: - title: Diesen Tag löschen - tip_with_posts: >- -

        Wir erlauben es nicht, Tags mit Beiträgenzu löschen.

        Bitte entfernen Sie dieses Tag zuerst aus den Beiträgen.

        - tip_with_synonyms: >- -

        Wir erlauben nicht Tags mit Synonymenzu löschen.

        Bitte entfernen Sie zuerst die Synonyme von diesem Schlagwort.

        - tip: Bist du sicher, dass du löschen möchtest? - close: Schließen - merge: - title: Tags zusammenführen - source_tag_title: Quell-Tag - source_tag_description: Das Quell-Tag und seine zugehörigen Daten werden dem Ziel-Tag zugeordnet. - target_tag_title: Ziel-Tag - target_tag_description: Ein Synonym zwischen diesen beiden Tags wird nach dem Zusammenführen erstellt. - no_results: Keine zusammenpassenden Tags gefunden - btn_submit: Absenden - btn_close: Schließen - edit_tag: - title: Tag bearbeiten - default_reason: Tag bearbeiten - default_first_reason: Tag hinzufügen - btn_save_edits: Änderungen speichern - btn_cancel: Abbrechen - dates: - long_date: DD. MMM - long_date_with_year: "DD. MMM YYYY" - long_date_with_time: "DD. MMM YYYY [at] HH:mm" - now: Gerade eben - x_seconds_ago: "Vor {{count}}s" - x_minutes_ago: "Vor {{count}}m" - x_hours_ago: "Vor {{count}}h" - hour: Stunde - day: tag - hours: Stunden - days: Tage - month: month - months: months - year: year - reaction: - heart: Herz - smile: Lächeln - frown: Stirnrunzeln - btn_label: Reaktionen hinzufügen oder entfernen - undo_emoji: '{{ emoji }} Reaktion rückgängig machen' - react_emoji: mit {{ emoji }} reagieren - unreact_emoji: '{{ emoji }} Reaktion entfernen' - comment: - btn_add_comment: Einen Kommentar hinzufügen - reply_to: Antwort an - btn_reply: Antwort - btn_edit: Bearbeiten - btn_delete: Löschen - btn_flag: Melden - btn_save_edits: Änderungen speichern - btn_cancel: Abbrechen - show_more: "{{count}} mehr Kommentare" - tip_question: >- - Verwende Kommentare, um nach weiteren Informationen zu fragen oder Verbesserungen vorzuschlagen. Vermeide es, Fragen in Kommentaren zu beantworten. - tip_answer: >- - Verwende Stellungsnahmen, um anderen Nutzern zu antworten oder sie über Änderungen zu informieren. Wenn du neue Informationen hinzufügst, bearbeite deinen Beitrag, anstatt zu kommentieren. - tip_vote: Es fügt dem Beitrag etwas Nützliches hinzu - edit_answer: - title: Antwort bearbeiten - default_reason: Antwort bearbeiten - default_first_reason: Antwort hinzufügen - form: - fields: - revision: - label: Version - answer: - label: Antwort - feedback: - characters: der Inhalt muss mindestens 6 Zeichen lang sein. - edit_summary: - label: Zusammenfassung bearbeiten - placeholder: >- - Erkläre kurz deine Änderungen (korrigierte Rechtschreibung, korrigierte Grammatik, verbesserte Formatierung) - btn_save_edits: Änderungen speichern - btn_cancel: Abbrechen - tags: - title: Schlagwörter - sort_buttons: - popular: Beliebt - name: Name - newest: Neueste - button_follow: Folgen - button_following: Folgend - tag_label: fragen - search_placeholder: Nach Tagnamen filtern - no_desc: Der Tag hat keine Beschreibung. - more: Mehr - wiki: Wiki - ask: - title: Create Question - edit_title: Frage bearbeiten - default_reason: Frage bearbeiten - default_first_reason: Create question - similar_questions: Ähnliche Fragen - form: - fields: - revision: - label: Version - title: - label: Titel - placeholder: What's your topic? Be specific. - msg: - empty: Der Titel darf nicht leer sein. - range: Titel bis zu 150 Zeichen - body: - label: Körper - msg: - empty: Körper darf nicht leer sein. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Stichworte - msg: - empty: Tags dürfen nicht leer sein. - answer: - label: Antwort - msg: - empty: Antwort darf nicht leer sein. - edit_summary: - label: Zusammenfassung bearbeiten - placeholder: >- - Erkläre kurz deine Änderungen (korrigierte Rechtschreibung, korrigierte Grammatik, verbesserte Formatierung) - btn_post_question: Poste deine Frage - btn_save_edits: Änderungen speichern - answer_question: Eigene Frage beantworten - post_question&answer: Poste deine Frage und Antwort - tag_selector: - add_btn: Schlagwort hinzufügen - create_btn: Neuen Tag erstellen - search_tag: Tag suchen - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: Keine Tags gefunden - tag_required_text: Benötigter Tag (mindestens eins) - header: - nav: - question: Fragen - tag: Schlagwörter - user: Benutzer - badges: Abzeichen - profile: Profil - setting: Einstellungen - logout: Ausloggen - admin: Administrator - review: Überprüfung - bookmark: Lesezeichen - moderation: Moderation - search: - placeholder: Suchen - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Ändern - loading: wird geladen... - pic_auth_code: - title: Captcha - placeholder: Gib den Text oben ein - msg: - empty: Captcha darf nicht leer sein. - inactive: - first: >- - Du bist fast fertig! Wir haben eine Aktivierungsmail an {{mail}} geschickt. Bitte folge den Anweisungen in der Mail, um dein Konto zu aktivieren. - info: "Wenn sie nicht ankommt, überprüfe deinen Spam-Ordner." - another: >- - Wir haben dir eine weitere Aktivierungs-E-Mail an {{mail}} geschickt. Es kann ein paar Minuten dauern, bis sie ankommt; überprüfe daher deinen Spam-Ordner. - btn_name: Aktivierungs Mail erneut senden - change_btn_name: E-Mail ändern - msg: - empty: Kann nicht leer sein. - resend_email: - url_label: Bist du sicher, dass du die Aktivierungs-E-Mail erneut senden willst? - url_text: Du kannst auch den Aktivierungslink oben an den Nutzer weitergeben. - login: - login_to_continue: Anmelden, um fortzufahren - info_sign: Du verfügst noch nicht über ein Konto? Registrieren - info_login: Du hast bereits ein Konto? <1>Anmelden - agreements: Wenn du dich registrierst, stimmst du der <1>Datenschutzrichtlinie und den <3>Nutzungsbedingungen zu. - forgot_pass: Passwort vergessen? - name: - label: Name - msg: - empty: Der Name darf nicht leer sein. - range: Der Name muss zwischen 2 und 30 Zeichen lang sein. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: E-Mail - msg: - empty: E-Mail-Feld darf nicht leer sein. - password: - label: Passwort - msg: - empty: Passwort-Feld darf nicht leer sein. - different: Die beiden eingegebenen Passwörter stimmen nicht überein - account_forgot: - page_title: Dein Passwort vergessen - btn_name: Schicke mir eine E-Mail zur Wiederherstellung - send_success: >- - Wenn ein Konto mit {{mail}} übereinstimmt, solltest du in Kürze eine E-Mail mit Anweisungen erhalten, wie du dein Passwort zurücksetzen kannst. - email: - label: E-Mail - msg: - empty: E-Mail darf nicht leer sein. - change_email: - btn_cancel: Stornieren - btn_update: E-Mail Adresse aktualisieren - send_success: >- - Wenn ein Konto mit {{mail}} übereinstimmt, solltest du in Kürze eine E-Mail mit Anweisungen erhalten, wie du dein Passwort zurücksetzen kannst. - email: - label: Neue E-Mail - msg: - empty: E-Mail darf nicht leer sein. - oauth: - connect: Mit {{ auth_name }} verbinden - remove: '{{ auth_name }} entfernen' - oauth_bind_email: - subtitle: Wiederherstellungs-E-Mail zu deinem Konto hinzufügen. - btn_update: E-Mail aktualisieren - email: - label: E-Mail - msg: - empty: E-Mail darf nicht leer sein. - modal_title: E-Mail existiert bereits. - modal_content: Diese E-Mail ist bereits registriert. Bist du sicher, dass du dich mit dem bestehenden Konto verbinden möchtest? - modal_cancel: E-Mail ändern - modal_confirm: Mit dem bestehenden Konto verbinden - password_reset: - page_title: Passwort zurücksetzen - btn_name: Setze mein Passwort zurück - reset_success: >- - Du hast dein Passwort erfolgreich geändert; du wirst zur Anmeldeseite weitergeleitet. - link_invalid: >- - Dieser Link zum Zurücksetzen des Passworts ist leider nicht mehr gültig. Vielleicht ist dein Passwort bereits zurückgesetzt? - to_login: Weiter zur Anmeldeseite - password: - label: Passwort - msg: - empty: Passwort kann nicht leer sein. - length: Die Länge muss zwischen 8 und 32 liegen - different: Die auf beiden Seiten eingegebenen Passwörter sind inkonsistent - password_confirm: - label: Neues Passwort bestätigen - settings: - page_title: Einstellungen - goto_modify: Zum Ändern - nav: - profile: Profil - notification: Benachrichtigungen - account: Konto - interface: Benutzeroberfläche - profile: - heading: Profil - btn_name: Speichern - display_name: - label: Anzeigename - msg: Anzeigename darf nicht leer sein. - msg_range: Der Anzeigename muss zwischen 2 und 30 Zeichen lang sein. - username: - label: Nutzername - caption: Leute können dich als "@Benutzername" erwähnen. - msg: Benutzername darf nicht leer sein. - msg_range: Der Benutzername muss zwischen 2 und 30 Zeichen lang sein. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profilbild - gravatar: Gravatar - gravatar_text: Du kannst das Bild ändern auf - custom: Benutzerdefiniert - custom_text: Du kannst dein Bild hochladen. - default: System - msg: Bitte lade einen Avatar hoch - bio: - label: Über mich - website: - label: Webseite - placeholder: "https://example.com" - msg: Website falsches Format - location: - label: Standort - placeholder: "Stadt, Land" - notification: - heading: E-Mail-Benachrichtigungen - turn_on: Aktivieren - inbox: - label: Posteingangsbenachrichtigungen - description: Antworten auf deine Fragen, Kommentare, Einladungen und mehr. - all_new_question: - label: Alle neuen Fragen - description: Lass dich über alle neuen Fragen benachrichtigen. Bis zu 50 Fragen pro Woche. - all_new_question_for_following_tags: - label: Alle neuen Fragen für folgende Tags - description: Lass dich über neue Fragen zu folgenden Tags benachrichtigen. - account: - heading: Konto - change_email_btn: E-Mail ändern - change_pass_btn: Passwort ändern - change_email_info: >- - Wir haben eine E-Mail an diese Adresse geschickt. Bitte befolge die Anweisungen zur Bestätigung. - email: - label: E-Mail - new_email: - label: Neue E-Mail - msg: Neue E-Mail darf nicht leer sein. - pass: - label: Aktuelles Passwort - msg: Passwort kann nicht leer sein. - password_title: Passwort - current_pass: - label: Aktuelles Passwort - msg: - empty: Das aktuelle Passwort darf nicht leer sein. - length: Die Länge muss zwischen 8 und 32 liegen. - different: Die beiden eingegebenen Passwörter stimmen nicht überein. - new_pass: - label: Neues Passwort - pass_confirm: - label: Neues Passwort bestätigen - interface: - heading: Benutzeroberfläche - lang: - label: Sprache der Benutzeroberfläche - text: Sprache der Benutzeroberfläche. Sie ändert sich, wenn du die Seite aktualisierst. - my_logins: - title: Meine Anmeldungen - label: Melde dich mit diesen Konten an oder registriere dich auf dieser Seite. - modal_title: Login entfernen - modal_content: Bist du sicher, dass du dieses Login aus deinem Konto entfernen möchtest? - modal_confirm_btn: Entfernen - remove_success: Erfolgreich entfernt - toast: - update: Aktualisierung erfolgreich - update_password: Das Kennwort wurde erfolgreich geändert. - flag_success: Danke fürs Markieren. - forbidden_operate_self: Verboten, an sich selbst zu operieren - review: Deine Überarbeitung wird nach der Überprüfung angezeigt. - sent_success: Erfolgreich gesendet - related_question: - title: Related - answers: antworten - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Frage jemanden - desc: Lade Leute ein, von denen du glaubst, dass sie die Antwort wissen könnten. - invite: Zur Antwort einladen - add: Personen hinzufügen - search: Personen suchen - question_detail: - action: Aktion - created: Created - Asked: Gefragt - asked: gefragt - update: Geändert - Edited: Edited - edit: bearbeitet - commented: kommentiert - Views: Gesehen - Follow: Folgen - Following: Folgend - follow_tip: Folge dieser Frage, um Benachrichtigungen zu erhalten - answered: beantwortet - closed_in: Abgeschlossen in - show_exist: Bestehende Frage anzeigen. - useful: Nützlich - question_useful: Es ist nützlich und klar - question_un_useful: Es ist unklar oder nicht nützlich - question_bookmark: Lesezeichen für diese Frage - answer_useful: Es ist nützlich - answer_un_useful: Es ist nicht nützlich - answers: - title: Antworten - score: Punkte - newest: Neueste - oldest: Älteste - btn_accept: Akzeptieren - btn_accepted: Akzeptiert - write_answer: - title: Deine Antwort - edit_answer: Meine existierende Antwort bearbeiten - btn_name: Poste deine Antwort - add_another_answer: Weitere Antwort hinzufügen - confirm_title: Antworten fortsetzen - continue: Weitermachen - confirm_info: >- -

        Bist du sicher, dass du eine weitere Antwort hinzufügen willst?

        Du könntest stattdessen den Bearbeiten-Link verwenden, um deine existierende Antwort zu verfeinern und zu verbessern.

        - empty: Antwort darf nicht leer sein. - characters: der Inhalt muss mindestens 6 Zeichen lang sein. - tips: - header_1: Danke für deine Antwort - li1_1: Bitte stelle sicher, dass du die Frage beantwortest. Gib Details an und erzähle von deiner Recherche. - li1_2: Untermauere alle Aussagen, die du erstellst, mit Referenzen oder persönlichen Erfahrungen. - header_2: Aber vermeide... - li2_1: Bitte um Hilfe, um Klarstellung oder um Antwort auf andere Antworten. - reopen: - confirm_btn: Wieder öffnen - title: Diesen Beitrag erneut öffnen - content: Bist du sicher, dass du wieder öffnen willst? - list: - confirm_btn: Liste - title: Diesen Beitrag auflisten - content: Möchten Sie diesen Beitrag wirklich in der Liste anzeigen? - unlist: - confirm_btn: Von Liste nehmen - title: Diesen Beitrag von der Liste nehmen - content: Möchten Sie diesen Beitrag wirklich aus der Liste ausblenden? - pin: - title: Diesen Beitrag anpinnen - content: Bist du sicher, dass du den Beitrag global anheften möchtest? Dieser Beitrag wird in allen Beitragslisten ganz oben erscheinen. - confirm_btn: Anheften - delete: - title: Diesen Beitrag löschen - question: >- - Wir raten davon ab, Fragen mit Antworten zu löschen, weil dadurch zukünftigen Lesern dieses Wissen vorenthalten wird.

        Wiederholtes Löschen von beantworteten Fragen kann dazu führen, dass dein Konto für Fragen gesperrt wird. Bist du sicher, dass du löschen möchtest? - answer_accepted: >- -

        Wir empfehlen nicht, akzeptierte Antworten zu löschen, denn dadurch wird zukünftigen Lesern dieses Wissen vorenthalten.

        Das wiederholte Löschen von akzeptierten Antworten kann dazu führen, dass dein Konto für die Beantwortung gesperrt wird. Bist du sicher, dass du löschen möchtest? - other: Bist du sicher, dass du löschen möchtest? - tip_answer_deleted: Diese Antwort wurde gelöscht - undelete_title: Diesen Beitrag wiederherstellen - undelete_desc: Bist du sicher, dass du die Löschung umkehren willst? - btns: - confirm: Bestätigen - cancel: Abbrechen - edit: Bearbeiten - save: Speichern - delete: Löschen - undelete: Wiederherstellen - list: Liste - unlist: Verstecken - unlisted: Versteckt - login: Einloggen - signup: Registrieren - logout: Ausloggen - verify: Überprüfen - create: Erstellen - approve: Genehmigen - reject: Ablehnen - skip: Überspringen - discard_draft: Entwurf verwerfen - pinned: Angeheftet - all: Alle - question: Frage - answer: Antwort - comment: Kommentar - refresh: Aktualisieren - resend: Erneut senden - deactivate: Deaktivieren - active: Aktiv - suspend: Sperren - unsuspend: Entsperren - close: Schließen - reopen: Wieder öffnen - ok: Okay - light: Hell - dark: Dunkel - system_setting: System-Einstellung - default: Standard - reset: Zurücksetzen - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignorieren - submit: Absenden - normal: Normal - closed: Geschlossen - deleted: Gelöscht - deleted_permanently: Dauerhaft gelöscht - pending: Ausstehend - more: Mehr - view: Betrachten - card: Karte - compact: Kompakt - display_below: Unten anzeigen - always_display: Immer anzeigen - or: oder - back_sites: Zurück zur Website - search: - title: Suchergebnisse - keywords: Schlüsselwörter - options: Optionen - follow: Folgen - following: Folgend - counts: "{{count}} Ergebnisse" - counts_loading: "... Results" - more: Mehr - sort_btns: - relevance: Relevanz - newest: Neueste - active: Aktiv - score: Punktzahl - more: Mehr - tips: - title: Erweiterte Suchtipps - tag: "<1>[tag] Suche mit einem Tag" - user: "<1>user:username Suche nach Autor" - answer: "<1>Antworten:0 unbeantwortete Fragen" - score: "<1>score:3 Beiträge mit einer 3+ Punktzahl" - question: "<1>is:question Suchfragen" - is_answer: "<1>ist:answer Suchantworten" - empty: Wir konnten nichts finden.
        Versuche es mit anderen oder weniger spezifischen Keywords. - share: - name: Teilen - copy: Link kopieren - via: Beitrag teilen über... - copied: Kopiert - facebook: Auf Facebook teilen - twitter: Auf X teilen - cannot_vote_for_self: Du kannst nicht für deinen eigenen Beitrag stimmen. - modal_confirm: - title: Fehler... - delete_permanently: - title: Endgültig löschen - content: Sind Sie sicher, dass Sie den Inhalt endgültig löschen möchten? - account_result: - success: Dein neues Konto ist bestätigt; du wirst zur Startseite weitergeleitet. - link: Weiter zur Startseite - oops: Hoppla! - invalid: Der Link, den Sie verwendet haben, funktioniert nicht mehr. - confirm_new_email: Deine E-Mail wurde aktualisiert. - confirm_new_email_invalid: >- - Dieser Bestätigungslink ist leider nicht mehr gültig. Vielleicht wurde deine E-Mail-Adresse bereits geändert? - unsubscribe: - page_title: Abonnement entfernen - success_title: Erfolgreich vom Abo abgemeldet - success_desc: Du wurdest erfolgreich aus der Abonnentenliste gestrichen und wirst keine weiteren E-Mails von uns erhalten. - link: Einstellungen ändern - question: - following_tags: Folgende Tags - edit: Bearbeiten - save: Speichern - follow_tag_tip: Folge den Tags, um deine Liste mit Fragen zu erstellen. - hot_questions: Angesagte Fragen - all_questions: Alle Fragen - x_questions: "{{ count }} Fragen" - x_answers: "{{ count }} Antworten" - x_posts: "{{ count }} Posts" - questions: Fragen - answers: Antworten - newest: Neueste - active: Aktiv - hot: Heiß - frequent: Häufig - recommend: Empfehlen - score: Punktzahl - unanswered: Unbeantwortet - modified: geändert - answered: beantwortet - asked: gefragt - closed: schließen - follow_a_tag: Einem Tag folgen - more: Mehr - personal: - overview: Übersicht - answers: Antworten - answer: antwort - questions: Fragen - question: frage - bookmarks: Lesezeichen - reputation: Ansehen - comments: Kommentare - votes: Stimmen - badges: Abzeichen - newest: Neueste - score: Punktzahl - edit_profile: Profil bearbeiten - visited_x_days: "{{ count }} Tage besucht" - viewed: Gesehen - joined: Beigetreten - comma: "," - last_login: Gesehen - about_me: Über mich - about_me_empty: "// Hallo Welt !" - top_answers: Top-Antworten - top_questions: Top-Fragen - stats: Statistiken - list_empty: Keine Beiträge gefunden.
        Vielleicht möchtest du einen anderen Reiter auswählen? - content_empty: Keine Posts gefunden. - accepted: Akzeptiert - answered: antwortete - asked: gefragt - downvoted: negativ bewertet - mod_short: MOD - mod_long: Moderatoren - x_reputation: ansehen - x_votes: Stimmen erhalten - x_answers: Antworten - x_questions: Fragen - recent_badges: Neueste Abzeichen - install: - title: Installation - next: Nächste - done: Erledigt - config_yaml_error: Die Datei config.yaml kann nicht erstellt werden. - lang: - label: Bitte wähle eine Sprache - db_type: - label: Datenbank-Engine - db_username: - label: Nutzername - placeholder: wurzel - msg: Benutzername darf nicht leer sein. - db_password: - label: Passwort - placeholder: wurzel - msg: Passwort kann nicht leer sein. - db_host: - label: Datenbank-Host - placeholder: "db:3306" - msg: Datenbank-Host darf nicht leer sein. - db_name: - label: Datenbankname - placeholder: antworten - msg: Der Datenbankname darf nicht leer sein. - db_file: - label: Datenbank-Datei - placeholder: /data/answer.Weder noch - msg: Datenbankdatei kann nicht leer sein. - ssl_enabled: - label: SSL aktivieren - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL-Modus - ssl_root_cert: - placeholder: SSL-Root-Zertifikat Pfad - msg: Pfad zum Ssl-Root-Zertifikat darf nicht leer sein - ssl_cert: - placeholder: SSL-Zertifikat Pfad - msg: Pfad zum SSL-Zertifikat darf nicht leer sein - ssl_key: - placeholder: SSL-Key Pfad - msg: Der Pfad zum SSL-Key darf nicht leer sein - config_yaml: - title: config.yaml erstellen - label: Die erstellte config.yaml-Datei. - desc: >- - Du kannst die Datei <1>config.yaml manuell im Verzeichnis <1>/var/wwww/xxx/ erstellen und den folgenden Text dort einfügen. - info: Nachdem du das getan hast, klickst du auf die Schaltfläche "Weiter". - site_information: Standortinformationen - admin_account: Administratorkonto - site_name: - label: Seitenname - msg: Standortname darf nicht leer sein. - msg_max_length: Der Name der Website darf maximal 30 Zeichen lang sein. - site_url: - label: Seiten-URL - text: Die Adresse deiner Website. - msg: - empty: Die Website-URL darf nicht leer sein. - incorrect: Falsches Format der Website-URL. - max_length: Die URL der Website darf maximal 512 Zeichen lang sein. - contact_email: - label: Kontakt E-Mail - text: E-Mail-Adresse des Hauptkontakts, der für diese Website verantwortlich ist. - msg: - empty: Kontakt-E-Mail kann nicht leer sein. - incorrect: Falsches Format der Kontakt-E-Mail. - login_required: - label: Privat - switch: Anmeldung erforderlich - text: Nur eingeloggte Benutzer können auf diese Community zugreifen. - admin_name: - label: Name - msg: Der Name darf nicht leer sein. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Der Name muss zwischen 2 und 30 Zeichen lang sein. - admin_password: - label: Passwort - text: >- - Du brauchst dieses Passwort, um dich einzuloggen. Bitte bewahre es an einem sicheren Ort auf. - msg: Passwort kann nicht leer sein. - msg_min_length: Passwort muss mindestens 8 Zeichen lang sein. - msg_max_length: Das Passwort darf maximal 32 Zeichen lang sein. - admin_confirm_password: - label: "Passwort bestätigen" - text: "Bitte geben Sie Ihr Passwort erneut ein, um es zu bestätigen." - msg: "Passwortbestätigung stimmt nicht überein!" - admin_email: - label: E-Mail - text: Du brauchst diese E-Mail, um dich einzuloggen. - msg: - empty: E-Mail darf nicht leer sein. - incorrect: E-Mail falsches Format. - ready_title: Ihre Seite ist bereit - ready_desc: >- - Wenn du noch mehr Einstellungen ändern möchtest, besuche den <1>Admin-Bereich; du findest ihn im Seitenmenü. - good_luck: "Viel Spaß und viel Glück!" - warn_title: Warnung - warn_desc: >- - Die Datei <1>config.yaml existiert bereits. Wenn du einen der Konfigurationspunkte in dieser Datei zurücksetzen musst, lösche sie bitte zuerst. - install_now: Du kannst versuchen, <1>jetzt zu installieren. - installed: Bereits installiert - installed_desc: >- - Du scheinst es bereits installiert zu haben. Um neu zu installieren, lösche bitte zuerst deine alten Datenbanktabellen. - db_failed: Datenbankverbindung fehlgeschlagen - db_failed_desc: >- - Das bedeutet entweder, dass die Datenbankinformationen in deiner <1>config.yaml Datei falsch sind oder dass der Kontakt zum Datenbankserver nicht hergestellt werden konnte. Das könnte bedeuten, dass der Datenbankserver deines Hosts ausgefallen ist. - counts: - views: Ansichten - votes: Stimmen - answers: Antworten - accepted: Akzeptiert - page_error: - http_error: HTTP Fehler {{ code }} - desc_403: Du hast keine Berechtigung, auf diese Seite zuzugreifen. - desc_404: Leider existiert diese Seite nicht. - desc_50X: Der Server ist auf einen Fehler gestoßen und konnte deine Anfrage nicht vollständig abschließen. - back_home: Zurück zur Startseite - page_maintenance: - desc: "Wir werden gewartet, wir sind bald wieder da." - nav_menus: - dashboard: Dashboard - contents: Inhalt - questions: Fragen - answers: Antworten - users: Benutzer - badges: Abzeichen - flags: Meldungen - settings: Einstellungen - general: Allgemein - interface: Benutzeroberfläche - smtp: SMTP - branding: Branding - legal: Rechtliches - write: Schreiben - terms: Terms - tos: Nutzungsbedingungen - privacy: Privatsphäre - seo: SEO - customize: Anpassen - themes: Themen - login: Anmeldung - privileges: Berechtigungen - plugins: Erweiterungen (Plugins) - installed_plugins: Installierte Plugins - apperance: Erscheinungsbild - website_welcome: Willkommen auf {{site_name}} - user_center: - login: Anmelden - qrcode_login_tip: Bitte verwende {{ agentName }}, um den QR-Code zu scannen und dich einzuloggen. - login_failed_email_tip: Anmeldung ist fehlgeschlagen. Bitte erlaube dieser App, auf deine E-Mail-Informationen zuzugreifen, bevor du es erneut versuchst. - badges: - modal: - title: Glückwunsch - content: Sie haben sich ein neues Abzeichen verdient. - close: Schließen - confirm: Abzeichen ansehen - title: Abzeichen - awarded: Verliehen - earned_×: Verdiente ×{{ number }} - ×_awarded: "verliehen {{ number }} " - can_earn_multiple: Du kannst das mehrmals verdienen. - earned: Verdient - admin: - admin_header: - title: Administrator - dashboard: - title: Dashboard - welcome: Willkommen im Admin Bereich! - site_statistics: Website-Statistiken - questions: "Fragen:" - resolved: "Belöst:" - unanswered: "Nicht beantwortet:" - answers: "Antworten:" - comments: "Kommentare:" - votes: "Stimmen:" - users: "Nutzer:" - flags: "Meldungen:" - reviews: "Rezension:" - site_health: Gesundheit der Website - version: "Version:" - https: "HTTPS:" - upload_folder: "Hochladeverzeichnis:" - run_mode: "Betriebsmodus:" - private: Privat - public: Öffentlich - smtp: "SMTP:" - timezone: "Zeitzone:" - system_info: Systeminformationen - go_version: "Go Version:" - database: "Datenbank:" - database_size: "Datenbankgröße:" - storage_used: "Verwendeter Speicher:" - uptime: "Betriebszeit:" - links: Links - plugins: Plugins - github: GitHub - blog: Blog - contact: Kontakt - forum: Forum - documents: Dokumentation - feedback: Rückmeldung - support: Unterstützung - review: Überprüfung - config: Konfig - update_to: Aktualisieren zu - latest: Aktuell - check_failed: Prüfung fehlgeschlagen - "yes": "Ja" - "no": "Nein" - not_allowed: Nicht erlaubt - allowed: Erlaubt - enabled: Aktiviert - disabled: Deaktiviert - writable: Schreibbar - not_writable: Nicht schreibbar - flags: - title: Meldungen - pending: Ausstehend - completed: Abgeschlossen - flagged: Gekennzeichnet - flagged_type: '{{ type }} gemeldet' - created: Erstellt - action: Aktion - review: Überprüfung - user_role_modal: - title: Benutzerrolle ändern zu... - btn_cancel: Abbrechen - btn_submit: Senden - new_password_modal: - title: Neues Passwort festlegen - form: - fields: - password: - label: Passwort - text: Der Nutzer wird abgemeldet und muss sich erneut anmelden. - msg: Das Passwort muss mindestens 8-32 Zeichen lang sein. - btn_cancel: Abbrechen - btn_submit: Senden - edit_profile_modal: - title: Profil bearbeiten - form: - fields: - display_name: - label: Anzeigename - msg_range: Der Anzeigename muss zwischen 2 und 30 Zeichen lang sein. - username: - label: Nutzername - msg_range: Der Benutzername muss 2-30 Zeichen lang sein. - email: - label: E-Mail - msg_invalid: Ungültige E-Mail-Adresse. - edit_success: Erfolgreich bearbeitet - btn_cancel: Abbrechen - btn_submit: Absenden - user_modal: - title: Neuen Benutzer hinzufügen - form: - fields: - users: - label: Masse Benutzer hinzufügen - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Trenne "Name, E-Mail, Passwort" mit Kommas. Ein Benutzer pro Zeile. - msg: "Bitte gib die E-Mail des Nutzers ein, eine pro Zeile." - display_name: - label: Anzeigename - msg: Der Anzeigename muss zwischen 2 und 30 Zeichen lang sein. - email: - label: E-Mail - msg: Die E-Mail ist nicht gültig. - password: - label: Passwort - msg: Das Passwort muss mindestens 8-32 Zeichen lang sein. - btn_cancel: Abbrechen - btn_submit: Senden - users: - title: Benutzer - name: Name - email: E-Mail - reputation: Ansehen - created_at: Angelegt am - delete_at: Löschzeit - suspend_at: Sperrzeit - suspend_until: Suspend until - status: Status - role: Rolle - action: Aktion - change: Ändern - all: Alle - staff: Teammitglieder - more: Mehr - inactive: Inaktiv - suspended: Gesperrt - deleted: Gelöscht - normal: Normal - Moderator: Moderation - Admin: Administrator - User: Benutzer - filter: - placeholder: "Nach Namen, user:id filtern" - set_new_password: Neues Passwort festlegen - edit_profile: Profil bearbeiten - change_status: Status ändern - change_role: Rolle wechseln - show_logs: Protokolle anzeigen - add_user: Benutzer hinzufügen - deactivate_user: - title: Benutzer deaktivieren - content: Ein inaktiver Nutzer muss seine E-Mail erneut bestätigen. - delete_user: - title: Diesen Benutzer löschen - content: Bist du sicher, dass du diesen Benutzer löschen willst? Das ist dauerhaft! - remove: Ihren Inhalt entfernen - label: Alle Fragen, Antworten, Kommentare, etc. entfernen - text: Aktiviere diese Option nicht, wenn du nur das Benutzerkonto löschen möchtest. - suspend_user: - title: Diesen Benutzer sperren - content: Ein gesperrter Benutzer kann sich nicht einloggen. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Fragen - unlisted: Nicht gelistet - post: Beitrag - votes: Stimmen - answers: Antworten - created: Erstellt - status: Status - action: Aktion - change: Ändern - pending: Ausstehend - filter: - placeholder: "Filtern nach Titel, Frage:Id" - answers: - page_title: Antworten - post: Beitrag - votes: Stimmen - created: Erstellt - status: Status - action: Aktion - change: Ändern - filter: - placeholder: "Filtern nach Titel, Antwort: id" - general: - page_title: Allgemein - name: - label: Seitenname - msg: Der Site-Name darf nicht leer sein. - text: "Der Name dieser Website, wie er im Titel-Tag verwendet wird." - site_url: - label: Seiten-URL - msg: Die Website-Url darf nicht leer sein. - validate: Bitte gib eine gültige URL ein. - text: Die Adresse deiner Website. - short_desc: - label: Kurze Seitenbeschreibung - msg: Die kurze Website-Beschreibung darf nicht leer sein. - text: "Kurze Beschreibung, wie im Titel-Tag auf der Homepage verwendet." - desc: - label: Seitenbeschreibung - msg: Die Websitebeschreibung darf nicht leer sein. - text: "Beschreibe diese Seite in einem Satz, wie er im Meta Description Tag verwendet wird." - contact_email: - label: Kontakt E-Mail - msg: Kontakt-E-Mail darf nicht leer sein. - validate: Kontakt-E-Mail ist ungültig. - text: E-Mail-Adresse des Hauptkontakts, der für diese Website verantwortlich ist. - check_update: - label: Softwareaktualisierungen - text: Automatisch auf Updates prüfen - interface: - page_title: Benutzeroberfläche - language: - label: Interface Sprache - msg: Sprache der Benutzeroberfläche darf nicht leer sein. - text: Sprache der Benutzeroberfläche. Sie ändert sich, wenn du die Seite aktualisierst. - time_zone: - label: Zeitzone - msg: Die Zeitzone darf nicht leer sein. - text: Wähle eine Stadt in der gleichen Zeitzone wie du. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: Von E-Mail - msg: Von E-Mail darf nicht leer sein. - text: Die E-Mail-Adresse, von der E-Mails gesendet werden. - from_name: - label: Von Name - msg: Absendername darf nicht leer sein. - text: Der Name, von dem E-Mails gesendet werden. - smtp_host: - label: SMTP-Host - msg: Der SMTP-Host darf nicht leer sein. - text: Dein Mailserver. - encryption: - label: Verschlüsselung - msg: Verschlüsselung darf nicht leer sein. - text: Für die meisten Server ist SSL die empfohlene Option. - ssl: SSL - tls: TLS - none: Keine - smtp_port: - label: SMTP-Port - msg: SMTP-Port muss Nummer 1 ~ 65535 sein. - text: Der Port zu deinem Mailserver. - smtp_username: - label: SMTP-Benutzername - msg: Der SMTP-Benutzername darf nicht leer sein. - smtp_password: - label: SMTP-Kennwort - msg: Das SMTP-Passwort darf nicht leer sein. - test_email_recipient: - label: Test-E-Mail-Empfänger - text: Gib die E-Mail-Adresse an, an die Testsendungen gesendet werden sollen. - msg: Test-E-Mail-Empfänger ist ungültig - smtp_authentication: - label: Authentifizierung aktivieren - title: SMTP-Authentifizierung - msg: Die SMTP-Authentifizierung darf nicht leer sein. - "yes": "Ja" - "no": "Nein" - branding: - page_title: Branding - logo: - label: Logo - msg: Logo darf nicht leer sein. - text: Das Logobild oben links auf deiner Website. Verwende ein breites rechteckiges Bild mit einer Höhe von 56 und einem Seitenverhältnis von mehr als 3:1. Wenn du es leer lässt, wird der Text des Website-Titels angezeigt. - mobile_logo: - label: Mobiles Logo - text: Das Logo wird auf der mobilen Version deiner Website verwendet. Verwende ein breites rechteckiges Bild mit einer Höhe von 56. Wenn du nichts angibst, wird das Bild aus der Einstellung "Logo" verwendet. - square_icon: - label: Quadratisches Symbol - msg: Quadratisches Symbol darf nicht leer sein. - text: Bild, das als Basis für Metadatensymbole verwendet wird. Sollte idealerweise größer als 512x512 sein. - favicon: - label: Favicon - text: Ein Favicon für deine Website. Um korrekt über ein CDN zu funktionieren, muss es ein png sein. Es wird auf 32x32 verkleinert. Wenn du es leer lässt, wird das "quadratische Symbol" verwendet. - legal: - page_title: Rechtliches - terms_of_service: - label: Nutzungsbedingungen - text: "Du kannst hier Inhalte zu den Nutzungsbedingungen hinzufügen. Wenn du bereits ein Dokument hast, das anderswo gehostet wird, gib hier die vollständige URL an." - privacy_policy: - label: Datenschutzbestimmungen - text: "Du kannst hier Inhalte zur Datenschutzerklärung hinzufügen. Wenn du bereits ein Dokument hast, das anderswo gehostet wird, gib hier die vollständige URL an." - external_content_display: - label: Externer Inhalt - text: "Inhalte umfassen Bilder, Videos und Medien, die von externen Websites eingebettet sind." - always_display: Externen Inhalt immer anzeigen - ask_before_display: Vor der Anzeige externer Inhalte fragen - write: - page_title: Schreiben - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Antwort bearbeiten - label: Jeder Benutzer kann für jede Frage nur eine Antwort schreiben - text: "Schalten Sie aus, um es Benutzern zu ermöglichen, mehrere Antworten auf dieselbe Frage zu schreiben, was dazu führen kann, dass Antworten nicht im Fokus stehen." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Empfohlene Tags - text: "Empfohlene Tags werden standardmäßig in der Dropdown-Liste angezeigt." - msg: - contain_reserved: "empfohlene Tags dürfen keine reservierten Tags enthalten" - required_tag: - title: Benötigte Tags festlegen - label: '"Empfohlene Tags" als erforderliche Tags festlegen' - text: "Jede neue Frage muss mindestens ein Empfehlungs-Tag haben." - reserved_tags: - label: Reservierte Tags - text: "Reservierte Tags können nur vom Moderator verwendet werden." - image_size: - label: Maximale Bildgröße (MB) - text: "Die maximale Bildladegröße." - attachment_size: - label: Maximale Anhanggröße (MB) - text: "Die maximale Dateigröße für Dateianhänge." - image_megapixels: - label: Max. BildmePixel - text: "Maximale Anzahl an Megapixeln für ein Bild." - image_extensions: - label: Autorisierte Bilderweiterungen - text: "Eine Liste von Dateierweiterungen, die für die Anzeige von Bildern erlaubt sind, getrennt durch Kommata." - attachment_extensions: - label: Autorisierte Anhänge Erweiterungen - text: "Eine Liste von Dateierweiterungen, die für das Hochladen erlaubt sind, getrennt mit Kommas. WARNUNG: Erlaubt Uploads kann Sicherheitsprobleme verursachen." - seo: - page_title: SEO - permalink: - label: Dauerlink - text: Benutzerdefinierte URL-Strukturen können die Benutzerfreundlichkeit und die Vorwärtskompatibilität deiner Links verbessern. - robots: - label: robots.txt - text: Dadurch werden alle zugehörigen Site-Einstellungen dauerhaft überschrieben. - themes: - page_title: Themen - themes: - label: Themen - text: Wähle ein bestehendes Thema aus. - color_scheme: - label: Farbschema - navbar_style: - label: Hintergrundstil der Navigationsleiste - primary_color: - label: Primäre Farbe - text: Ändere die Farben, die von deinen Themes verwendet werden - css_and_html: - page_title: CSS und HTML - custom_css: - label: Benutzerdefinierte CSS - text: > - - head: - label: Kopf - text: > - - header: - label: Header - text: > - - footer: - label: Fusszeile - text: Dies wird vor eingefügt. - sidebar: - label: Seitenleiste - text: Dies wird in die Seitenleiste eingefügt. - login: - page_title: Anmeldung - membership: - title: Mitgliedschaft - label: Neuregistrierungen zulassen - text: Schalte sie ab, um zu verhindern, dass jemand ein neues Konto erstellt. - email_registration: - title: E-Mail Registrierung - label: E-Mail-Registrierung zulassen - text: Abschalten, um zu verhindern, dass jemand ein neues Konto per E-Mail erstellt. - allowed_email_domains: - title: Zugelassene E-Mail-Domänen - text: E-Mail-Domänen, bei denen die Nutzer Konten registrieren müssen. Eine Domäne pro Zeile. Wird ignoriert, wenn leer. - private: - title: Privatgelände - label: Anmeldung erforderlich - text: Nur angemeldete Benutzer können auf diese Community zugreifen. - password_login: - title: Passwort-Login - label: E-Mail-und Passwort-Login erlauben - text: "WARNUNG: Wenn du diese Option abschaltest, kannst du dich möglicherweise nicht mehr anmelden, wenn du zuvor keine andere Anmeldemethode konfiguriert hast." - installed_plugins: - title: Installierte Plugins - plugin_link: Plugins erweitern und ergänzen die Funktionalität. Du kannst Plugins im <1>Pluginverzeichnis finden. - filter: - all: Alle - active: Aktiv - inactive: Inaktiv - outdated: Veraltet - plugins: - label: Erweiterungen - text: Wähle ein bestehendes Plugin aus. - name: Name - version: Version - status: Status - action: Aktion - deactivate: Deaktivieren - activate: Aktivieren - settings: Einstellungen - settings_users: - title: Benutzer - avatar: - label: Standard-Avatar - text: Für Benutzer ohne einen eigenen Avatar. - gravatar_base_url: - label: Gravatar Base URL - text: URL der API-Basis des Gravatar-Anbieters. Wird ignoriert, wenn leer. - profile_editable: - title: Profil bearbeitbar - allow_update_display_name: - label: Benutzern erlauben, ihren Anzeigenamen zu ändern - allow_update_username: - label: Benutzern erlauben, ihren Benutzernamen zu ändern - allow_update_avatar: - label: Benutzern erlauben, ihr Profilbild zu ändern - allow_update_bio: - label: Benutzern erlauben, ihr Über mich zu ändern - allow_update_website: - label: Benutzern erlauben, ihre Website zu ändern - allow_update_location: - label: Benutzern erlauben, ihren Standort zu ändern - privilege: - title: Berechtigungen - level: - label: Benötigtes Reputations-Level - text: Wähle die für die Privilegien erforderliche Reputation aus - msg: - should_be_number: die Eingabe muss numerisch sein - number_larger_1: Zahl muss gleich oder größer als 1 sein - badges: - action: Aktion - active: Aktiv - activate: Aktivieren - all: Alle - awards: Verliehen - deactivate: Deaktivieren - filter: - placeholder: Nach Namen, Abzeichen:id filtern - group: Gruppe - inactive: Inaktiv - name: Name - show_logs: Protokolle anzeigen - status: Status - title: Abzeichen - form: - optional: (optional) - empty: kann nicht leer sein - invalid: ist ungültig - btn_submit: Speichern - not_found_props: "Erforderliche Eigenschaft {{ key }} nicht gefunden." - select: Auswählen - page_review: - review: Überprüfung - proposed: vorgeschlagen - question_edit: Frage bearbeiten - answer_edit: Antwort bearbeiten - tag_edit: Tag bearbeiten - edit_summary: Zusammenfassung bearbeiten - edit_question: Frage bearbeiten - edit_answer: Antwort bearbeiten - edit_tag: Tag bearbeiten - empty: Keine Überprüfungsaufgaben mehr übrig. - approve_revision_tip: Akzeptieren Sie diese Revision? - approve_flag_tip: Sind Sie mit diesem Bericht einverstanden? - approve_post_tip: Bestätigen Sie diesen Beitrag? - approve_user_tip: Bestätigen Sie diesen Benutzer? - suggest_edits: Änderungsvorschläge - flag_post: Beitrag melden - flag_user: Nutzer melden - queued_post: Beitrag in Warteschlange - queued_user: Benutzer in der Warteschlange - filter_label: Typ - reputation: ansehen - flag_post_type: Diesen Beitrag als {{ type }} markiert. - flag_user_type: Diesen Benutzer als {{ type }} markiert. - edit_post: Beitrag bearbeiten - list_post: Ausgestellte Beiträge - unlist_post: Versteckte Beiträge - timeline: - undeleted: ungelöscht - deleted: gelöscht - downvote: ablehnen - upvote: positiv bewerten - accept: akzeptieren - cancelled: abgebrochen - commented: kommentiert - rollback: zurückrollen - edited: bearbeitet - answered: antwortete - asked: gefragt - closed: geschlossen - reopened: wiedereröffnet - created: erstellt - pin: angeheftet - unpin: losgelöst - show: gelistet - hide: nicht gelistet - title: "Verlauf von" - tag_title: "Zeitleiste für" - show_votes: "Stimmen anzeigen" - n_or_a: Keine Angaben - title_for_question: "Zeitleiste für" - title_for_answer: "Zeitachse für die Antwort auf {{ title }} von {{ author }}" - title_for_tag: "Zeitachse für Tag" - datetime: Terminzeit - type: Typ - by: Von - comment: Kommentar - no_data: "Wir konnten nichts finden." - users: - title: Benutzer - users_with_the_most_reputation: Benutzer mit den höchsten Reputationspunkten dieser Woche - users_with_the_most_vote: Benutzer, die diese Woche am meisten gestimmt haben - staffs: Unsere Community Teammitglieder - reputation: Ansehen - votes: Stimmen - prompt: - leave_page: Bist du sicher, dass du die Seite verlassen willst? - changes_not_save: Deine Änderungen werden möglicherweise nicht gespeichert. - draft: - discard_confirm: Bist du sicher, dass du deinen Entwurf verwerfen willst? - messages: - post_deleted: Dieser Beitrag wurde gelöscht. - post_cancel_deleted: Dieser Beitrag wurde wiederhergestellt. - post_pin: Dieser Beitrag wurde angepinnt. - post_unpin: Dieser Beitrag wurde losgelöst. - post_hide_list: Dieser Beitrag wurde aus der Liste verborgen. - post_show_list: Dieser Beitrag wird in der Liste angezeigt. - post_reopen: Dieser Beitrag wurde wieder geöffnet. - post_list: Dieser Beitrag wurde angezeigt. - post_unlist: Dieser Beitrag wurde ausgeblendet. - post_pending: Dein Beitrag wartet auf eine Überprüfung. Dies ist eine Vorschau, sie wird nach der Genehmigung sichtbar sein. - post_closed: Dieser Beitrag wurde gelöscht. - answer_deleted: Diese Antwort wurde gelöscht. - answer_cancel_deleted: Diese Antwort wurde wiederhergestellt. - change_user_role: Die Rolle dieses Benutzers wurde geändert. - user_inactive: Dieser Benutzer ist bereits inaktiv. - user_normal: Dieser Benutzer ist bereits normal. - user_suspended: Dieser Nutzer wurde gesperrt. - user_deleted: Benutzer wurde gelöscht. - badge_activated: Dieses Abzeichen wurde aktiviert. - badge_inactivated: Dieses Abzeichen wurde deaktiviert. - users_deleted: Der Benutzer wurde gelöscht. - posts_deleted: Deine Frage wurde gelöscht. - answers_deleted: Deine Antwort wurde gelöscht. - copy: In die Zwischenablage kopieren - copied: Kopiert - external_content_warning: Externe Bilder/Medien werden nicht angezeigt. - - diff --git a/data/i18n/el_GR.yaml b/data/i18n/el_GR.yaml deleted file mode 100644 index 25c086f11..000000000 --- a/data/i18n/el_GR.yaml +++ /dev/null @@ -1,1384 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: Success. - unknown: - other: Unknown error. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - email: - other: Email - password: - other: Password - email_or_password_wrong_error: - other: Email and password do not match. - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - question: - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - rank: - fail_to_meet_the_condition: - other: Rank fail to meet the condition. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend Tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - smtp: - config_from_name_cannot_be_email: - other: The From Name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to Revision. - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - report: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude: - name: - other: rude or abusive - desc: - other: A reasonable person would find this content inappropriate for respectful discourse. - duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - not_answer: - name: - other: not an answer - desc: - other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. - not_need: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - other: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comments - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to {{site_name}} - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to {{site_name}} - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/en_US.yaml b/data/i18n/en_US.yaml deleted file mode 100644 index eac322dac..000000000 --- a/data/i18n/en_US.yaml +++ /dev/null @@ -1,2395 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end - -backend: - base: - success: - other: Success. - unknown: - other: Unknown error. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - forbidden_error: - other: Forbidden. - duplicate_request_error: - other: Duplicate submission. - action: - report: - other: Flag - edit: - other: Edit - delete: - other: Delete - close: - other: Close - reopen: - other: Reopen - forbidden_error: - other: Forbidden. - pin: - other: Pin - hide: - other: Unlist - unpin: - other: Unpin - show: - other: List - invite_someone_to_answer: - other: Edit - undelete: - other: Undelete - merge: - other: Merge - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - privilege: - level_1: - description: - other: Level 1 (less reputation required for private team, group) - level_2: - description: - other: Level 2 (low reputation required for startup community) - level_3: - description: - other: Level 3 (high reputation required for mature community) - level_custom: - description: - other: Custom Level - rank_question_add_label: - other: Ask question - rank_answer_add_label: - other: Write answer - rank_comment_add_label: - other: Write comment - rank_report_add_label: - other: Flag - rank_comment_vote_up_label: - other: Upvote comment - rank_link_url_limit_label: - other: Post more than 2 links at a time - rank_question_vote_up_label: - other: Upvote question - rank_answer_vote_up_label: - other: Upvote answer - rank_question_vote_down_label: - other: Downvote question - rank_answer_vote_down_label: - other: Downvote answer - rank_invite_someone_to_answer_label: - other: Invite someone to answer - rank_tag_add_label: - other: Create new tag - rank_tag_edit_label: - other: Edit tag description (need to review) - rank_question_edit_label: - other: Edit other's question (need to review) - rank_answer_edit_label: - other: Edit other's answer (need to review) - rank_question_edit_without_review_label: - other: Edit other's question without review - rank_answer_edit_without_review_label: - other: Edit other's answer without review - rank_question_audit_label: - other: Review question edits - rank_answer_audit_label: - other: Review answer edits - rank_tag_audit_label: - other: Review tag edits - rank_tag_edit_without_review_label: - other: Edit tag description without review - rank_tag_synonym_label: - other: Manage tag synonyms - email: - other: Email - e_mail: - other: Email - password: - other: Password - pass: - other: Password - old_pass: - other: Current password - original_text: - other: This post - email_or_password_wrong_error: - other: Email and password do not match. - error: - common: - invalid_url: - other: Invalid URL. - status_invalid: - other: Invalid status. - password: - space_invalid: - other: Password cannot contain spaces. - admin: - cannot_update_their_password: - other: You cannot modify your password. - cannot_edit_their_profile: - other: You cannot modify your profile. - cannot_modify_self_status: - other: You cannot modify your status. - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - question_closed_cannot_add: - other: Questions are closed and cannot be added. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - illegal_email_domain_error: - other: Email is not allowed from that email domain. Please use another one. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - already_deleted: - other: This post has been deleted. - meta: - object_not_found: - other: Meta object not found - question: - already_deleted: - other: This post has been deleted. - under_review: - other: Your post is awaiting review. It will be visible after it has been approved. - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Reputation rank fail to meet the condition. - vote_fail_to_meet_the_condition: - other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. - no_enough_rank_to_operate: - other: You need at least {{.Rank}} reputation to do this. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - already_exist: - other: Tag already exists. - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - is_used_cannot_delete: - other: You cannot delete a tag that is in use. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: The from name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to revise. - user: - external_login_missing_user_id: - other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. - external_login_unbinding_forbidden: - other: Please set a login password for your account before you remove this login. - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration. - not_allowed_login_via_password: - other: Currently the site is not allowed to login via password. - access_denied: - other: Access denied - page_access_denied: - other: You do not have access to this page. - add_bulk_users_format_error: - other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - site_info: - config_not_found: - other: Site config not found. - badge: - object_not_found: - other: Badge object not found - reason: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude_or_abusive: - name: - other: rude or abusive - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - a_duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - placeholder: - other: Enter the existing question link - not_a_answer: - name: - other: not an answer - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." - no_longer_needed: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - something: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - placeholder: - other: Let us know specifically what you are concerned about - community_specific: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - not_clarity: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - looks_ok: - name: - other: looks OK - desc: - other: This post is good as-is and not low quality. - needs_edit: - name: - other: needs edit, and I did it - desc: - other: Improve and correct problems with this post yourself. - needs_close: - name: - other: needs close - desc: - other: A closed question can't answer, but still can edit, vote and comment. - needs_delete: - name: - other: needs delete - desc: - other: This post will be deleted. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - deleted_title: - other: Deleted question - questions_title: - other: Questions - tag: - tags_title: - other: Tags - no_description: - other: The tag has no description. - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted - up_voted_question: - other: upvoted question - down_voted_question: - other: downvoted question - up_voted_answer: - other: upvoted answer - down_voted_answer: - other: downvoted answer - up_voted_comment: - other: upvoted comment - invited_you_to_answer: - other: invited you to answer - earned_badge: - other: You've earned the "{{.BadgeName}}" badge - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Confirm your new email address" - body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} answered your question" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_question: - title: - other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Password reset" - body: - other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - register: - title: - other: "[{{.SiteName}}] Confirm your new account" - body: - other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - test: - title: - other: "[{{.SiteName}}] Test Email" - body: - other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: - upvote: - other: upvote - upvoted: - other: upvoted - downvote: - other: downvote - downvoted: - other: downvoted - accept: - other: accept - accepted: - other: accepted - edit: - other: edit - review: - queued_post: - other: Queued post - flagged_post: - other: Flagged post - suggested_post_edit: - other: Suggested edits - reaction: - tooltip: - other: "{{ .Names }} and {{ .Count }} more..." - badge: - default_badges: - autobiographer: - name: - other: Autobiographer - desc: - other: Filled out profile information. - certified: - name: - other: Certified - desc: - other: Completed our new user tutorial. - editor: - name: - other: Editor - desc: - other: First post edit. - first_flag: - name: - other: First Flag - desc: - other: First flagged a post. - first_upvote: - name: - other: First Upvote - desc: - other: First up voted a post. - first_link: - name: - other: First Link - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: First Share - desc: - other: First shared a post. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Leave 5 comments. - new_user_of_the_month: - name: - other: New User of the Month - desc: - other: Outstanding contributions in their first month. - read_guidelines: - name: - other: Read Guidelines - desc: - other: Read the [community guidelines]. - reader: - name: - other: Reader - desc: - other: Read every answers in a topic with more than 10 answers. - welcome: - name: - other: Welcome - desc: - other: Received a up vote. - nice_share: - name: - other: Nice Share - desc: - other: Shared a post with 25 unique visitors. - good_share: - name: - other: Good Share - desc: - other: Shared a post with 300 unique visitors. - great_share: - name: - other: Great Share - desc: - other: Shared a post with 1000 unique visitors. - out_of_love: - name: - other: Out of Love - desc: - other: Used 50 up votes in a day. - higher_love: - name: - other: Higher Love - desc: - other: Used 50 up votes in a day 5 times. - crazy_in_love: - name: - other: Crazy in Love - desc: - other: Used 50 up votes in a day 20 times. - promoter: - name: - other: Promoter - desc: - other: Invited a user. - campaigner: - name: - other: Campaigner - desc: - other: Invited 3 basic users. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: Thank You - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Active member for a year, posted at least once. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting - -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • mention a post: #post_id

        • -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by - placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - create_tag: Create Tag - edit_tag: Edit Tag - ask_a_question: Create Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - oauth_callback: Processing - http_404: HTTP Error 404 - http_50X: HTTP Error 500 - http_403: HTTP Error 403 - logout: Log Out - posts: Posts - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - new_alerts: New alerts - all_read: Mark all as read - show_more: Show more - someone: Someone - inbox_type: - all: All - posts: Posts - invites: Invites - votes: Votes - answer: Answer - question: Question - badge_award: Badge - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - contact_us: Contact us - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image file - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed {{size}} MB. - desc: - label: Description - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered list - unordered_list: - text: Bulleted list - table: - text: Table - heading: Heading - cell: Cell - file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - not_a_url: URL format is incorrect. - url_not_match: URL origin does not match the current website. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description - revision: - label: Revision - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, - improved formatting) - btn_cancel: Cancel - btn_submit: Submit - btn_post: Post new tag - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - tip_with_posts: >- -

        We do not allow deleting tag with posts.

        -

        Please remove this tag from the posts first.

        - tip_with_synonyms: >- -

        We do not allow deleting tag with synonyms.

        -

        Please remove the synonyms from this tag first.

        - tip: Are you sure you wish to delete? - close: Close - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - default_first_reason: Add tag - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - hours: hours - days: days - month: month - months: months - year: year - reaction: - heart: heart - smile: smile - frown: frown - btn_label: add or remove reactions - undo_emoji: undo {{ emoji }} reaction - react_emoji: react with {{ emoji }} - unreact_emoji: unreact with {{ emoji }} - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: "{{count}} more comments" - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid - answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are - adding new information, edit your post instead of commenting. - tip_vote: It adds something useful to the post - edit_answer: - title: Edit Answer - default_reason: Edit answer - default_first_reason: Add answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, - improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: Newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - wiki: Wiki - ask: - title: Create Question - edit_title: Edit Question - default_reason: Edit question - default_first_reason: Create question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: What's your topic? Be specific. - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, - improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - badges: Badges - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - bookmark: Bookmarks - moderation: Moderation - search: - placeholder: Search - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. - Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might - take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - resend_email: - url_label: Are you sure you want to resend the activation email? - url_text: You can also give the activation link above to the user. - login: - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email - with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email - with instructions on how to reset your password shortly. - email: - label: New email - msg: - empty: Email cannot be empty. - oauth: - connect: Connect with {{ auth_name }} - remove: Remove {{ auth_name }} - oauth_bind_email: - subtitle: Add a recovery email to your account. - btn_update: Update email address - email: - label: Email - msg: - empty: Email cannot be empty. - modal_title: Email already existes. - modal_content: This email address already registered. Are you sure you want to connect to the existing account? - modal_cancel: Change email - modal_confirm: Connect to the existing account - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in - page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is - already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm new password - settings: - page_title: Settings - goto_modify: Go to modify - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile image - gravatar: Gravatar - gravatar_text: You can change image on - custom: Custom - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About me - website: - label: Website - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location - placeholder: "City, Country" - notification: - heading: Email Notifications - turn_on: Turn on - inbox: - label: Inbox notifications - description: Answers to your questions, comments, invites, and more. - all_new_question: - label: All new questions - description: Get notified of all new questions. Up to 50 questions per week. - all_new_question_for_following_tags: - label: All new questions for following tags - description: Get notified of new questions for following tags. - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation - instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - pass: - label: Current password - msg: Password cannot be empty. - password_title: Password - current_pass: - label: Current password - msg: - empty: Current password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New password - pass_confirm: - label: Confirm new password - interface: - heading: Interface - lang: - label: Interface language - text: User interface language. It will change when you refresh the page. - my_logins: - title: My logins - label: Log in or sign up on this site using these accounts. - modal_title: Remove login - modal_content: Are you sure you want to remove this login from your account? - modal_confirm_btn: Remove - remove_success: Removed successfully - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - sent_success: Sent successfully - related_question: - title: Related - answers: answers - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Invite People - desc: Invite people you think can answer. - invite: Invite to answer - add: Add people - search: Search people - question_detail: - action: Action - created: Created - Asked: Asked - asked: asked - update: Modified - Edited: Edited - edit: edited - commented: commented - Views: Viewed - Follow: Follow - Following: Following - follow_tip: Follow this question to receive notifications - answered: answered - closed_in: Closed in - show_exist: Show existing question. - useful: Useful - question_useful: It is useful and clear - question_un_useful: It is unclear or not useful - question_bookmark: Bookmark this question - answer_useful: It is useful - answer_un_useful: It is not useful - answers: - title: Answers - score: Score - newest: Newest - oldest: Oldest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - edit_answer: Edit my existing answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the - edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - tips: - header_1: Thanks for your answer - li1_1: Please be sure to answer the question. Provide details and share your research. - li1_2: Back up any statements you make with references or personal experience. - header_2: But avoid ... - li2_1: Asking for help, seeking clarification, or responding to other answers. - reopen: - confirm_btn: Reopen - title: Reopen this post - content: Are you sure you want to reopen? - list: - confirm_btn: List - title: List this post - content: Are you sure you want to list? - unlist: - confirm_btn: Unlist - title: Unlist this post - content: Are you sure you want to unlist? - pin: - title: Pin this post - content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. - confirm_btn: Pin - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because - doing so deprives future readers of this knowledge.

        Repeated deletion - of answered questions can result in your account being blocked from asking. - Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because - doing so deprives future readers of this knowledge.

        Repeated deletion - of accepted answers can result in your account being blocked from answering. - Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_answer_deleted: This answer has been deleted - undelete_title: Undelete this post - undelete_desc: Are you sure you wish to undelete? - btns: - confirm: Confirm - cancel: Cancel - edit: Edit - save: Save - delete: Delete - undelete: Undelete - list: List - unlist: Unlist - unlisted: Unlisted - login: Log in - signup: Sign up - logout: Log out - verify: Verify - create: Create - approve: Approve - reject: Reject - skip: Skip - discard_draft: Discard draft - pinned: Pinned - all: All - question: Question - answer: Answer - comment: Comment - refresh: Refresh - resend: Resend - deactivate: Deactivate - active: Active - suspend: Suspend - unsuspend: Unsuspend - close: Close - reopen: Reopen - ok: OK - light: Light - dark: Dark - system_setting: System setting - default: Default - reset: Reset - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignore - submit: Submit - normal: Normal - closed: Closed - deleted: Deleted - deleted_permanently: Deleted permanently - pending: Pending - more: More - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - counts_loading: "... Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post. - modal_confirm: - title: Error... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was - already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - x_posts: "{{ count }} Posts" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - frequent: Frequent - recommend: Recommend - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - badges: Badges - newest: Newest - score: Score - edit_profile: Edit profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - comma: "," - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - content_empty: No posts found. - accepted: Accepted - answered: answered - asked: asked - downvoted: downvoted - mod_short: MOD - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - recent_badges: Recent Badges - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please choose a language - db_type: - label: Database engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database host - placeholder: "db:3306" - msg: Database host cannot be empty. - db_name: - label: Database name - placeholder: answer - msg: Database name cannot be empty. - db_file: - label: Database file - placeholder: /data/answer.db - msg: Database file cannot be empty. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the - <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site name - msg: Site name cannot be empty. - msg_max_length: Site name must be at maximum 30 characters in length. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - max_length: Site URL must be at maximum 512 characters in length. - contact_email: - label: Contact email - text: Email address of key contact responsible for this site. - msg: - empty: Contact email cannot be empty. - incorrect: Contact email incorrect format. - login_required: - label: Private - switch: Login required - text: Only logged in users can access this community. - admin_name: - label: Name - msg: Name cannot be empty. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure - location. - msg: Password cannot be empty. - msg_min_length: Password must be at least 8 characters in length. - msg_max_length: Password must be at maximum 32 characters in length. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; - find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the - configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old - database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_error: - http_error: HTTP Error {{ code }} - desc_403: You don't have permission to access this page. - desc_404: Unfortunately, this page doesn't exist. - desc_50X: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - badges: Badges - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - terms: Terms - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - login: Login - privileges: Privileges - plugins: Plugins - installed_plugins: Installed Plugins - apperance: Appearance - website_welcome: Welcome to {{site_name}} - user_center: - login: Login - qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. - login_failed_email_tip: Login failed, please allow this app to access your email information before try again. - badges: - modal: - title: Congratulations - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site statistics - questions: "Questions:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - users: "Users:" - flags: "Flags:" - reviews: "Reviews:" - site_health: Site health - version: "Version:" - https: "HTTPS:" - upload_folder: "Upload folder:" - run_mode: "Running mode:" - private: Private - public: Public - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System info - go_version: "Go version:" - database: "Database:" - database_size: "Database size:" - storage_used: "Storage used:" - uptime: "Uptime:" - links: Links - plugins: Plugins - github: GitHub - blog: Blog - contact: Contact - forum: Forum - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - writable: Writable - not_writable: Not writable - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - flagged_type: Flagged {{ type }} - created: Created - action: Action - review: Review - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - edit_profile_modal: - title: Edit profile - form: - fields: - display_name: - label: Display name - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Invalid Email Address. - edit_success: Edited successfully - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - users: - label: Bulk add user - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separate “name, email, password” with commas. One user per line. - msg: "Please enter the user's email, one per line." - display_name: - label: Display name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - more: More - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - edit_profile: Edit profile - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - deactivate_user: - title: Deactivate user - content: An inactive user must re-validate their email. - delete_user: - title: Delete this user - content: Are you sure you want to delete this user? This is permanent! - remove: Remove their content - label: Remove all questions, answers, comments, etc. - text: Don’t check this if you wish to only delete the user’s account. - suspend_user: - title: Suspend this user - content: A suspended user can't log in. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Questions - unlisted: Unlisted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - pending: Pending - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short site description - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site description - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - check_update: - label: Software updates - text: Automatically check for updates - interface: - page_title: Interface - language: - label: Interface language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: From email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - tls: TLS - none: None - smtp_port: - label: SMTP port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test email recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile logo - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square icon - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Write - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Each user can only write one answer for the same question - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Recommend tags - text: "Recommend tags will show in the dropdown list by default." - msg: - contain_reserved: "recommended tags cannot contain reserved tags" - required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved tags - text: "Reserved tags can only be used by moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - color_scheme: - label: Color scheme - navbar_style: - label: Navbar background style - primary_color: - label: Primary color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as <link> - head: - label: Head - text: This will insert before </head> - header: - label: Header - text: This will insert after <body> - footer: - label: Footer - text: This will insert before </body>. - sidebar: - label: Sidebar - text: This will insert in sidebar. - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - email_registration: - title: Email registration - label: Allow email registration - text: Turn off to prevent anyone creating new account through email. - allowed_email_domains: - title: Allowed email domains - text: Email domains that users must register accounts with. One domain per line. Ignored when empty. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - password_login: - title: Password login - label: Allow email and password login - text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." - installed_plugins: - title: Installed Plugins - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. - filter: - all: All - active: Active - inactive: Inactive - outdated: Outdated - plugins: - label: Plugins - text: Select an existing plugin. - name: Name - version: Version - status: Status - action: Action - deactivate: Deactivate - activate: Activate - settings: Settings - settings_users: - title: Users - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - profile_editable: - title: Profile editable - allow_update_display_name: - label: Allow users to change their display name - allow_update_username: - label: Allow users to change their username - allow_update_avatar: - label: Allow users to change their profile image - allow_update_bio: - label: Allow users to change their about me - allow_update_website: - label: Allow users to change their website - allow_update_location: - label: Allow users to change their location - privilege: - title: Privileges - level: - label: Reputation required level - text: Choose the reputation required for the privileges - msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 - badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate - filter: - placeholder: Filter by name, badge:id - group: Group - inactive: Inactive - name: Name - show_logs: Show logs - status: Status - title: Badges - form: - optional: (optional) - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - select: Select - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - approve_revision_tip: Do you approve this revision? - approve_flag_tip: Do you approve this flag? - approve_post_tip: Do you approve this post? - approve_user_tip: Do you approve this user? - suggest_edits: Suggested edits - flag_post: Flag post - flag_user: Flag user - queued_post: Queued post - queued_user: Queued user - filter_label: Type - reputation: reputation - flag_post_type: Flagged this post as {{ type }}. - flag_user_type: Flagged this user as {{ type }}. - edit_post: Edit post - list_post: List post - unlist_post: Unlist post - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - pin: pinned - unpin: unpinned - show: listed - hide: unlisted - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores this week - users_with_the_most_vote: Users who voted the most this week - staffs: Our community staff - reputation: reputation - votes: votes - prompt: - leave_page: Are you sure you want to leave the page? - changes_not_save: Your changes may not be saved. - draft: - discard_confirm: Are you sure you want to discard your draft? - messages: - post_deleted: This post has been deleted. - post_cancel_deleted: This post has been undeleted. - post_pin: This post has been pinned. - post_unpin: This post has been unpinned. - post_hide_list: This post has been hidden from list. - post_show_list: This post has been shown to list. - post_reopen: This post has been reopened. - post_list: This post has been listed. - post_unlist: This post has been unlisted. - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/es_ES.yaml b/data/i18n/es_ES.yaml deleted file mode 100644 index 171c143d3..000000000 --- a/data/i18n/es_ES.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Completado. - unknown: - other: Error desconocido. - request_format_error: - other: Formato de la solicitud inválido. - unauthorized_error: - other: No autorizado. - database_error: - other: Error en el servidor de datos. - forbidden_error: - other: Prohibido. - duplicate_request_error: - other: Solicitud duplicada. - action: - report: - other: Reportar - edit: - other: Editar - delete: - other: Eliminar - close: - other: Cerrar - reopen: - other: Reabrir - forbidden_error: - other: Prohibido. - pin: - other: Fijar - hide: - other: Retirar - unpin: - other: Desfijar - show: - other: Lista - invite_someone_to_answer: - other: Editar - undelete: - other: Recuperar - merge: - other: Merge - role: - name: - user: - other: Usuario - admin: - other: Administrador - moderator: - other: Moderador - description: - user: - other: Predeterminado sin acceso especial. - admin: - other: Dispone de acceso total al sitio web y sus ajustes. - moderator: - other: Dispone de acceso a todas las publicaciones pero no a los ajustes de administrador. - privilege: - level_1: - description: - other: Nivel 1 (reputación menor requerida para un equipo privado, grupo) - level_2: - description: - other: Nivel 2 (reputación baja requerida para una comunidad de Startup) - level_3: - description: - other: Nivel 3 (reputación alta requerida para una comunidad madura) - level_custom: - description: - other: Nivel personalizado - rank_question_add_label: - other: Hacer una pregunta - rank_answer_add_label: - other: Escribir respuesta - rank_comment_add_label: - other: Escribir comentario - rank_report_add_label: - other: Reportar - rank_comment_vote_up_label: - other: Votar comentario a favor - rank_link_url_limit_label: - other: Publica más de 2 enlaces a la vez - rank_question_vote_up_label: - other: Votar pregunta a favor - rank_answer_vote_up_label: - other: Votar respuesta a favor - rank_question_vote_down_label: - other: Votar pregunta en contra - rank_answer_vote_down_label: - other: Votar respuesta en contra - rank_invite_someone_to_answer_label: - other: Invitar a alguien a responder - rank_tag_add_label: - other: Crear nueva etiqueta - rank_tag_edit_label: - other: Editar descripción de etiqueta (revisión necesaria) - rank_question_edit_label: - other: Editar pregunta ajena (revisión necesaria) - rank_answer_edit_label: - other: Editar respuesta ajena (revisión necesaria) - rank_question_edit_without_review_label: - other: Editar pregunta ajena sin revisión - rank_answer_edit_without_review_label: - other: Editar respuesta ajena sin revisión - rank_question_audit_label: - other: Revisar ediciones de pregunta - rank_answer_audit_label: - other: Revisar ediciones de respuesta - rank_tag_audit_label: - other: Revisar ediciones de etiqueta - rank_tag_edit_without_review_label: - other: Editar descripción de etiqueta sin revisión - rank_tag_synonym_label: - other: Administrar sinónimos de etiqueta - email: - other: Correo electrónico - e_mail: - other: Correo electrónico - password: - other: Contraseña - pass: - other: Contraseña - old_pass: - other: Current password - original_text: - other: Esta publicación - email_or_password_wrong_error: - other: Contraseña o correo incorrecto. - error: - common: - invalid_url: - other: URL no válido. - status_invalid: - other: Estado inválido. - password: - space_invalid: - other: La contraseña no puede contener espacios. - admin: - cannot_update_their_password: - other: No puede modificar su contraseña. - cannot_edit_their_profile: - other: No puede modificar su perfil. - cannot_modify_self_status: - other: No puede modificar su contraseña. - email_or_password_wrong: - other: Contraseña o correo incorrecto. - answer: - not_found: - other: Respuesta no encontrada. - cannot_deleted: - other: Sin permiso para eliminar. - cannot_update: - other: Sin permiso para actualizar. - question_closed_cannot_add: - other: Las preguntas están cerradas y no pueden añadirse. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Edición del comentario no permitida. - not_found: - other: Comentario no encontrado. - cannot_edit_after_deadline: - other: El tiempo del comentario ha sido demasiado largo para modificarlo. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: Correo electrónico ya en uso. - need_to_be_verified: - other: El correo debe ser verificado. - verify_url_expired: - other: La URL verificada del correo electrónico ha caducado. Por favor, vuelva a enviar el correo electrónico. - illegal_email_domain_error: - other: No está permitido el correo electrónico de ese dominio. Por favor utilice otro. - lang: - not_found: - other: Archivo de idioma no encontrado. - object: - captcha_verification_failed: - other: Captcha fallido. - disallow_follow: - other: No dispones de permiso para seguir. - disallow_vote: - other: No dispones de permiso para votar. - disallow_vote_your_self: - other: No puedes votar a tu propia publicación. - not_found: - other: Objeto no encontrado. - verification_failed: - other: Verificación fallida. - email_or_password_incorrect: - other: Contraseña o correo incorrecto. - old_password_verification_failed: - other: La verificación de la contraseña antigua falló - new_password_same_as_previous_setting: - other: La nueva contraseña es igual a la anterior. - already_deleted: - other: Esta publicación ha sido borrada. - meta: - object_not_found: - other: Meta objeto no encontrado - question: - already_deleted: - other: Esta publicación ha sido eliminada. - under_review: - other: Tu publicación está siendo revisada. Será visible una vez sea aprobada. - not_found: - other: Pregunta no encontrada. - cannot_deleted: - other: Sin permiso para eliminar. - cannot_close: - other: Sin permiso para cerrar. - cannot_update: - other: Sin permiso para actualizar. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: El rango de reputación no cumple la condición. - vote_fail_to_meet_the_condition: - other: Gracias por los comentarios. Necesitas al menos reputación {{.Rank}} para votar. - no_enough_rank_to_operate: - other: Necesitas al menos reputación {{.Rank}} para hacer esto. - report: - handle_failed: - other: Error en el manejador del reporte. - not_found: - other: Informe no encontrado. - tag: - already_exist: - other: La etiqueta ya existe. - not_found: - other: Etiqueta no encontrada. - recommend_tag_not_found: - other: La etiqueta recomendada no existe. - recommend_tag_enter: - other: Por favor, introduce al menos una de las etiquetas requeridas. - not_contain_synonym_tags: - other: No debe contener etiquetas sinónimas. - cannot_update: - other: Sin permiso para actualizar. - is_used_cannot_delete: - other: No puedes eliminar una etiqueta que está en uso. - cannot_set_synonym_as_itself: - other: No se puede establecer como sinónimo de una etiqueta la propia etiqueta. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: El nombre no puede ser una dirección de correo electrónico. - theme: - not_found: - other: Tema no encontrado. - revision: - review_underway: - other: No se puede editar actualmente, hay una versión en la cola de revisiones. - no_permission: - other: Sin permisos para ver. - user: - external_login_missing_user_id: - other: La plataforma de terceros no proporciona un UserID único, por lo que si no puede iniciar sesión, contacte al administrador del sitio. - external_login_unbinding_forbidden: - other: Por favor añada una contraseña de inicio de sesión a su cuenta antes de eliminar este método de acceso. - email_or_password_wrong: - other: - other: Contraseña o correo incorrecto. - not_found: - other: Usuario no encontrado. - suspended: - other: El usuario ha sido suspendido. - username_invalid: - other: Nombre de usuario no válido. - username_duplicate: - other: El nombre de usuario ya está en uso. - set_avatar: - other: Fallo al actualizar el avatar. - cannot_update_your_role: - other: No puedes modificar tu propio rol. - not_allowed_registration: - other: Actualmente el sitio no está abierto para el registro. - not_allowed_login_via_password: - other: Actualmente el sitio no está abierto para iniciar sesión por contraseña. - access_denied: - other: Acceso denegado - page_access_denied: - other: No tienes acceso a esta página. - add_bulk_users_format_error: - other: "Error {{.Field}} formato cerca de '{{.Content}}' en la línea {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "El número de usuarios que añadas a la vez debe estar en el rango de 1 a {{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Lectura de configuración fallida - database: - connection_failed: - other: Conexión a la base de datos fallida - create_table_failed: - other: Creación de tabla fallida - install: - create_config_failed: - other: No es posible crear el archivo config.yaml. - upload: - unsupported_file_format: - other: Formato de archivo no soportado. - site_info: - config_not_found: - other: Configuración del sitio no encontrada. - badge: - object_not_found: - other: Insignia no encontrada - reason: - spam: - name: - other: correo no deseado - desc: - other: Esta publicación es un anuncio, o vandalismo. No es útil o relevante para el tema actual. - rude_or_abusive: - name: - other: grosero u ofensivo - desc: - other: "Alguna persona podría considerar este contenido inapropiado para una discusión respetuosa." - a_duplicate: - name: - other: un duplicado - desc: - other: Esta pregunta ha sido hecha antes y ya ha sido resuelta. - placeholder: - other: Introduce el enlace de la pregunta existente - not_a_answer: - name: - other: no es una respuesta - desc: - other: "Esto fue publicado como respuesta pero no intenta responder a la pregunta. Podría ser una edición, un comentario, otra pregunta diferente o ser eliminado por completo." - no_longer_needed: - name: - other: ya no es necesario - desc: - other: Este comentario está desactualizado, es conversacional o no es relevante a esta publicación. - something: - name: - other: otro motivo - desc: - other: Esta publicación requiere revisión del personal por otro motivo no listado arriba. - placeholder: - other: Háganos saber qué le interesa en concreto - community_specific: - name: - other: un motivo determinado de la comunidad - desc: - other: Esta pregunta no cumple con una norma comunitaria. - not_clarity: - name: - other: requiere detalles o aclaraciones - desc: - other: Esta pregunta actualmente incluye múltiples preguntas en una. Debería enfocarse en una única cuestión. - looks_ok: - name: - other: parece correcto - desc: - other: Esta publicación es buena como es y no es de baja calidad. - needs_edit: - name: - other: necesita editarse, y lo hice - desc: - other: Mejora y corrige los problemas con esta publicación personalmente. - needs_close: - name: - other: necesita cerrar - desc: - other: Una pregunta cerrada no puede responderse, pero aún se puede editar, votar y comentar. - needs_delete: - name: - other: necesita eliminación - desc: - other: Esta publicación será eliminada. - question: - close: - duplicate: - name: - other: correo no deseado - desc: - other: La pregunta ya ha sido preguntada y resuelta previamente. - guideline: - name: - other: razón específica de la comunidad - desc: - other: Esta pregunta infringe alguna norma de la comunidad. - multiple: - name: - other: necesita más detalles o aclaraciónes - desc: - other: Esta pregunta incluye múltiples preguntas en una sola. Debería centrarse únicamente en un solo tema. - other: - name: - other: otra razón - desc: - other: Esta publicación requiere otra razón no listada arriba. - operation_type: - asked: - other: preguntada - answered: - other: respondida - modified: - other: modificada - deleted_title: - other: Pregunta eliminada - questions_title: - other: Preguntas - tag: - tags_title: - other: Etiquetas - no_description: - other: La etiqueta no tiene descripción. - notification: - action: - update_question: - other: pregunta actualizada - answer_the_question: - other: pregunta respondidas - update_answer: - other: respuesta actualizada - accept_answer: - other: respuesta aceptada - comment_question: - other: pregunta comentada - comment_answer: - other: respuesta comentada - reply_to_you: - other: te ha respondido - mention_you: - other: te ha mencionado - your_question_is_closed: - other: Tu pregunta ha sido cerrada - your_question_was_deleted: - other: Tu pregunta ha sido eliminada - your_answer_was_deleted: - other: Tu respuesta ha sido eliminada - your_comment_was_deleted: - other: Tu comentario ha sido eliminado - up_voted_question: - other: pregunta votada a favor - down_voted_question: - other: pregunta votada en contra - up_voted_answer: - other: respuesta votada a favor - down_voted_answer: - other: respuesta votada en contra - up_voted_comment: - other: comentario votado a favor - invited_you_to_answer: - other: te invitó a responder - earned_badge: - other: Ha ganado la insignia "{{.BadgeName}}" - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Confirma tu nueva dirección de correo" - body: - other: "Confirme su nueva dirección de correo electrónico para {{.SiteName}} haciendo clic en el siguiente enlace:
        \n{{.ChangeEmailUrl}}

        \n\nSi no solicitó este cambio, por favor, ignore este mensaje.

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} respondió tu pregunta" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nVerlo en {{.SiteName}}

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída.

        \n\nDarse de baja" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} te invitó a responder" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Es posible que conozca la respuesta.

        \nVerlo en {{.SiteName}}

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída.

        \n\nDarse de baja" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} comentó en tu publicación" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nVerlo en {{.SiteName}}

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída.

        \n\nDarse de baja" - new_question: - title: - other: "[{{.SiteName}}] Nueva pregunta: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Reestablecimiento de contraseña" - body: - other: "Se solicitó el restablecimiento de su contraseña en {{.SiteName}}.

        \n\nSi no lo solicitó, puede ignorar este mensaje.

        \n\nHaga clic en el siguiente enlace para generar una nueva contraseña:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída." - register: - title: - other: "[{{.SiteName}}] Confirma tu nueva cuenta" - body: - other: "¡Bienvenido a {{.SiteName}}!

        \n\nHaga clic en el siguiente enlace y active su nueva cuenta:
        \n{{.RegisterUrl}}

        \n\nSi no puede hacer clic en el enlace anterior, intente copiando y pegando el enlace en la barra de dirección en su navegador web.

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída." - test: - title: - other: "[{{.SiteName}}] Correo de prueba" - body: - other: "Este es un mensaje de prueba.\n

        \n\n--
        \nNota: Este es un mensaje automático, por favor, no responda a este mensaje ya que su respuesta no será leída." - action_activity_type: - upvote: - other: votar a favor - upvoted: - other: votado a favor - downvote: - other: voto negativo - downvoted: - other: votado en contra - accept: - other: aceptar - accepted: - other: aceptado - edit: - other: editar - review: - queued_post: - other: Publicación en cola - flagged_post: - other: Publicación marcada - suggested_post_edit: - other: Ediciones sugeridas - reaction: - tooltip: - other: "{{ .Names }} y {{ .Count }} más..." - badge: - default_badges: - autobiographer: - name: - other: Autobiógrafo - desc: - other: Completó la información de su perfil. - certified: - name: - other: Certificado - desc: - other: Completó nuestro nuevo tutorial de usuario. - editor: - name: - other: Editor - desc: - other: Primer mensaje editado. - first_flag: - name: - other: Primera Denuncia - desc: - other: Primer denuncia de un post. - first_upvote: - name: - other: Primer voto favorable - desc: - other: Primera vez que le doy un 'like' a un post. - first_link: - name: - other: Primer Enlace - desc: - other: First added a link to another post. - first_reaction: - name: - other: Primera reacción - desc: - other: Primero reaccionó al post. - first_share: - name: - other: Primer Compartir - desc: - other: Primero compartió un post. - scholar: - name: - other: Erudito - desc: - other: Hecha una pregunta y aceptada una respuesta. - commentator: - name: - other: Comentador - desc: - other: Deja 5 comentarios. - new_user_of_the_month: - name: - other: Nuevo usuario del mes - desc: - other: Contribuciones pendientes en su primer mes. - read_guidelines: - name: - other: Lea los lineamientos - desc: - other: Lea las [directrices de la comunidad]. - reader: - name: - other: Lector - desc: - other: Lee cada respuesta en un tema con más de 10 respuestas. - welcome: - name: - other: Bienvenido - desc: - other: Recibió un voto a favor. - nice_share: - name: - other: Buena Compartición - desc: - other: Compartió un post con 25 visitantes únicos. - good_share: - name: - other: Buena Compartida - desc: - other: Compartió un post con 300 visitantes únicos. - great_share: - name: - other: Excelente Compartida - desc: - other: Compartió un post con 1000 visitantes únicos. - out_of_love: - name: - other: Fuera del Amor - desc: - other: Utilizó 50 votos positivos en un día. - higher_love: - name: - other: Amor Más Alto - desc: - other: Utilizó 50 votos positivos en un día 5 veces. - crazy_in_love: - name: - other: Loco(a) por el Amor - desc: - other: Utilizó 50 votos positivos en un día 20 veces. - promoter: - name: - other: Promotor - desc: - other: Invitó a un usuario. - campaigner: - name: - other: Activista - desc: - other: Invitó a 3 usuarios básicos. - champion: - name: - other: Campeón - desc: - other: Invitado 5 miembros. - thank_you: - name: - other: Gracias - desc: - other: Tiene 20 publicaciones con votos positivos y dio 10 votos positivos. - gives_back: - name: - other: Da a Cambio - desc: - other: Tiene 100 publicaciones con votos positivos y dio 100 votos positivos. - empathetic: - name: - other: Empático - desc: - other: Tiene 500 publicaciones con votos positivos y dio 1000 votos positivos. - enthusiast: - name: - other: Entusiasta - desc: - other: Visita 10 días consecutivos. - aficionado: - name: - other: Aficionado - desc: - other: Visita 100 días consecutivos. - devotee: - name: - other: Devoto - desc: - other: Visita 365 días consecutivos. - anniversary: - name: - other: Aniversario - desc: - other: Miembro activo por un año, publicó al menos una vez. - appreciated: - name: - other: Apreciación - desc: - other: Recibió 1 voto positivo en 20 puestos. - respected: - name: - other: Respetado - desc: - other: Recibió 2 voto positivo en 100 puestos. - admired: - name: - other: Admirado - desc: - other: Recibió 5 voto positivo en 300 puestos. - solved: - name: - other: Resuelto - desc: - other: Tener una respuesta aceptada. - guidance_counsellor: - name: - other: Consejero de Orientación - desc: - other: Tener 10 respuestas aceptadas. - know_it_all: - name: - other: Sabelotodo - desc: - other: Tener 50 respuestas aceptadas. - solution_institution: - name: - other: Institución de Soluciones - desc: - other: Tener 150 respuestas aceptadas. - nice_answer: - name: - other: Buena Respuesta - desc: - other: Respuesta con una puntuación de 10 o más. - good_answer: - name: - other: Excelente Respuesta - desc: - other: Respuesta con una puntuación de 25 o más. - great_answer: - name: - other: Gran Respuesta - desc: - other: Respuesta con una puntuación de 50 o más. - nice_question: - name: - other: Buena Pregunta - desc: - other: Pregunta con una puntuación de 10 o más. - good_question: - name: - other: Excelente Pregunta - desc: - other: Pregunta con una puntuación de 25 o más. - great_question: - name: - other: Gran Pregunta - desc: - other: Pregunta con una puntuación de 50 o más. - popular_question: - name: - other: Pregunta popular - desc: - other: Pregunta con 500 puntos de vista. - notable_question: - name: - other: Pregunta Notable - desc: - other: Pregunta con 1,000 vistas. - famous_question: - name: - other: Pregunta Famosa - desc: - other: Pregunta con 5,000 vistas. - popular_link: - name: - other: Enlace Popular - desc: - other: Publicado un enlace externo con 50 clics. - hot_link: - name: - other: Enlace caliente - desc: - other: Publicado un enlace externo con 300 clics. - famous_link: - name: - other: Enlace familiar - desc: - other: Publicado un enlace externo con 100 clics. - default_badge_groups: - getting_started: - name: - other: Primeros pasos - community: - name: - other: Comunidad - posting: - name: - other: Publicación -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Cómo formatear - desc: >- -
        • menciona una publicación: #post_id

        • para hacer enlaces

          <https://url.com>

          [Título](https://url.com)
        • poner retornos entre párrafos

        • _italic_ o **negrita**

        • sangría del código con 4 espacios

        • cita colocando > al inicio de la línea

        • comillas invertidas se escapa `like _this_`

        • crear barreras de código con comillas invertidas `

          ```
          código aquí
          ```
        - pagination: - prev: Anterior - next: Siguiente - page_title: - question: Pregunta - questions: Preguntas - tag: Etiqueta - tags: Etiquetas - tag_wiki: wiki de Etiquetas - create_tag: Crear etiqueta - edit_tag: Editar etiqueta - ask_a_question: Create Question - edit_question: Editar Pregunta - edit_answer: Editar respuesta - search: Buscar - posts_containing: Publicaciones que contienen - settings: Ajustes - notifications: Notificaciones - login: Acceder - sign_up: Registrarse - account_recovery: Recuperación de la cuenta - account_activation: Activación de la cuenta - confirm_email: Confirmar correo electrónico - account_suspended: Cuenta suspendida - admin: Administrador - change_email: Modificar correo - install: Instalación de Answer - upgrade: Actualización de Answer - maintenance: Mantenimiento del sitio web - users: Usuarios - oauth_callback: Procesando - http_404: HTTP Error 404 - http_50X: HTTP Error 500 - http_403: HTTP Error 403 - logout: Cerrar sesión - posts: Posts - notifications: - title: Notificaciones - inbox: Buzón de entrada - achievement: Logros - new_alerts: Nuevas alertas - all_read: Marcar todo como leído - show_more: Mostrar más - someone: Alguien - inbox_type: - all: Todo - posts: Publicaciones - invites: Invitaciones - votes: Votos - answer: Respuesta - question: Pregunta - badge_award: Medalla - suspended: - title: Tu cuenta ha sido suspendida - until_time: "Tu cuenta ha sido suspendida hasta el {{ time }}." - forever: Este usuario ha sido suspendido indefinidamente. - end: Has infringido alguna norma de la comunidad. - contact_us: Contáctanos - editor: - blockquote: - text: Cita - bold: - text: Negrita - chart: - text: Gráfica - flow_chart: Diagrama de flujo - sequence_diagram: Diagrama de secuencia - class_diagram: Diagrama de clase - state_diagram: Diagrama de estado - entity_relationship_diagram: Diagrama de relación de entidad - user_defined_diagram: Diagrama definido por el usuario - gantt_chart: Diagrama de Gantt - pie_chart: Grafico de torta - code: - text: Código - add_code: Añadir código - form: - fields: - code: - label: Código - msg: - empty: Código no puede estar vacío. - language: - label: Idioma - placeholder: Detección automática - btn_cancel: Cancelar - btn_confirm: Añadir - formula: - text: Fórmula - options: - inline: Fórmula en línea - block: Bloque de fórmula - heading: - text: Encabezado - options: - h1: Encabezado 1 - h2: Encabezado 2 - h3: Encabezado 3 - h4: Encabezado 4 - h5: Encabezado 5 - h6: Encabezado 6 - help: - text: Ayuda - hr: - text: Regla horizontal - image: - text: Imagen - add_image: Añadir imagen - tab_image: Subir imagen - form_image: - fields: - file: - label: Archivo de imagen - btn: Seleccionar imagen - msg: - empty: El título no puede estar vacío. - only_image: Solo se permiten archivos de imagen. - max_size: El tamaño del archivo no puede exceder {{size}} MB. - desc: - label: Descripción - tab_url: URL de la imagen - form_url: - fields: - url: - label: URL de la imagen - msg: - empty: La URL de la imagen no puede estar vacía. - name: - label: Descripción - btn_cancel: Cancelar - btn_confirm: Añadir - uploading: Subiendo - indent: - text: Sangría - outdent: - text: Quitar sangría - italic: - text: Cursiva - link: - text: Enlace - add_link: Añadir enlace - form: - fields: - url: - label: Por sus siglas en ingles (Localizador Uniforme de recursos), dirección electrónica de un sitio web - msg: - empty: La dirección no puede estar vacía. - name: - label: Descripción - btn_cancel: Cancelar - btn_confirm: Añadir - ordered_list: - text: Lista numerada - unordered_list: - text: Lista con viñetas - table: - text: Tabla - heading: Encabezado - cell: Celda - file: - text: Adjuntar archivos - not_supported: "No soporta ese tipo de archivo. Inténtalo de nuevo con {{file_type}}." - max_size: "El tamaño de los archivos adjuntos no puede exceder {{size}} MB." - close_modal: - title: Estoy cerrando este post como... - btn_cancel: Cancelar - btn_submit: Enviar - remark: - empty: No puede estar en blanco. - msg: - empty: Por favor selecciona una razón. - report_modal: - flag_title: Estoy marcando para reportar este post de... - close_title: Estoy cerrando este post como... - review_question_title: Revisar pregunta - review_answer_title: Revisar respuesta - review_comment_title: Revisar comentario - btn_cancel: Cancelar - btn_submit: Enviar - remark: - empty: No puede estar en blanco. - msg: - empty: Por favor selecciona una razón. - not_a_url: El formato de la URL es incorrecto. - url_not_match: El origen de la URL no coincide con el sitio web actual. - tag_modal: - title: Crear nueva etiqueta - form: - fields: - display_name: - label: Nombre público - msg: - empty: El nombre a mostrar no puede estar vacío. - range: Nombre a mostrar con un máximo de 35 caracteres. - slug_name: - label: Ruta de la URL - desc: Slug de URL de hasta 35 caracteres. - msg: - empty: URL no puede estar vacío. - range: URL slug hasta 35 caracteres. - character: La URL amigable contiene caracteres no permitidos. - desc: - label: Descripción - revision: - label: Revisión - edit_summary: - label: Editar resumen - placeholder: >- - Explica brevemente los cambios (corrección ortográfica, mejora de formato) - btn_cancel: Cancelar - btn_submit: Enviar - btn_post: Publicar nueva etiqueta - tag_info: - created_at: Creado - edited_at: Editado - history: Historial - synonyms: - title: Sinónimos - text: Las siguientes etiquetas serán reasignadas a - empty: No se encontraron sinónimos. - btn_add: Añadir un sinónimo - btn_edit: Editar - btn_save: Guardar - synonyms_text: Las siguientes etiquetas serán reasignadas a - delete: - title: Eliminar esta etiqueta - tip_with_posts: >- -

        No permitimos eliminar etiquetas con publicaciones.

        Primero elimine esta etiqueta de las publicaciones.

        - tip_with_synonyms: >- -

        No permitimos eliminar etiqueta con sinónimos.

        Primero elimine los sinónimos de esta etiqueta.

        - tip: '¿Estás seguro de que deseas borrarlo?' - close: Cerrar - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Editar etiqueta - default_reason: Editar etiqueta - default_first_reason: Añadir etiqueta - btn_save_edits: Guardar cambios - btn_cancel: Cancelar - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [a las] HH:mm" - now: ahora - x_seconds_ago: "hace {{count}}s" - x_minutes_ago: "hace {{count}}m" - x_hours_ago: "hace {{count}}h" - hour: hora - day: día - hours: horas - days: días - month: month - months: months - year: year - reaction: - heart: corazón - smile: sonrisa - frown: frown - btn_label: añadir o eliminar reacciones - undo_emoji: deshacer reacción de {{ emoji }} - react_emoji: reaccionar con {{ emoji }} - unreact_emoji: desreaccionar con {{ emoji }} - comment: - btn_add_comment: Añadir comentario - reply_to: Responder a - btn_reply: Responder - btn_edit: Editar - btn_delete: Eliminar - btn_flag: Reportar - btn_save_edits: Guardar cambios - btn_cancel: Cancelar - show_more: "{{count}} comentarios más" - tip_question: >- - Utiliza los comentarios para pedir más información o sugerir mejoras y modificaciones. Evita responder preguntas en los comentarios. - tip_answer: >- - Usa comentarios para responder a otros usuarios o notificarles de cambios. Si estás añadiendo nueva información, edita tu publicación en vez de comentar. - tip_vote: Añade algo útil a la publicación - edit_answer: - title: Editar respuesta - default_reason: Editar respuesta - default_first_reason: Añadir respuesta - form: - fields: - revision: - label: Revisión - answer: - label: Respuesta - feedback: - characters: El contenido debe tener al menos 6 caracteres. - edit_summary: - label: Editar resumen - placeholder: >- - Explique brevemente sus cambios (ortografía corregida, gramática corregida, formato mejorado) - btn_save_edits: Guardar cambios - btn_cancel: Cancelar - tags: - title: Etiquetas - sort_buttons: - popular: Popular - name: Nombre - newest: Más reciente - button_follow: Seguir - button_following: Siguiendo - tag_label: preguntas - search_placeholder: Filtrar por nombre de etiqueta - no_desc: La etiqueta no tiene descripción. - more: Mas - wiki: Wiki - ask: - title: Create Question - edit_title: Editar pregunta - default_reason: Editar pregunta - default_first_reason: Create question - similar_questions: Preguntas similares - form: - fields: - revision: - label: Revisión - title: - label: Título - placeholder: What's your topic? Be specific. - msg: - empty: El título no puede estar vacío. - range: Título hasta 150 caracteres - body: - label: Cuerpo - msg: - empty: Cuerpo no puede estar vacío. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Etiquetas - msg: - empty: Se requiere al menos una etiqueta. - answer: - label: Respuesta - msg: - empty: La respuesta no puede estar vacía. - edit_summary: - label: Editar resumen - placeholder: >- - Explique brevemente sus cambios (ortografía corregida, gramática corregida, formato mejorado) - btn_post_question: Publica tu pregunta - btn_save_edits: Guardar cambios - answer_question: Responde a tu propia pregunta - post_question&answer: Publicar una pregunta y su respuesta - tag_selector: - add_btn: Añadir etiqueta - create_btn: Crear nueva etiqueta - search_tag: Buscar etiqueta - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: Ninguna etiqueta coincide - tag_required_text: Etiqueta requerida (al menos una) - header: - nav: - question: Preguntas - tag: Etiquetas - user: Usuarios - badges: Insignias - profile: Perfil - setting: Ajustes - logout: Cerrar sesión - admin: Administrador - review: Revisar - bookmark: Marcadores - moderation: Moderación - search: - placeholder: Buscar - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Cambiar - loading: cargando... - pic_auth_code: - title: Captcha - placeholder: Introduce el texto anterior - msg: - empty: El Captcha no puede estar vacío. - inactive: - first: >- - ¡Casi estás listo! Te hemos enviado un correo de activación a {{mail}}. Por favor, sigue las instrucciones en el correo para activar tu cuenta. - info: "Si no te ha llegado el correo, comprueba la carpeta de SPAM." - another: >- - Te hemos enviado otro correo de activación a {{mail}}. Puede tardar algunos minutos en llegar; asegúrate de revisar tu carpeta de SPAM. - btn_name: Reenviar correo de activación - change_btn_name: Cambiar correo - msg: - empty: No puede estar en blanco. - resend_email: - url_label: '¿Estás seguro de reenviar el correo de activación?' - url_text: También puedes dar el enlace de activación de arriba al usuario. - login: - login_to_continue: Inicia sesión para continuar - info_sign: '¿No tienes cuenta? <1>Regístrate' - info_login: '¿Ya tienes una cuenta? <1>Inicia sesión' - agreements: Al registrarte, aceptas la <1>política de privacidad y los <3>términos de servicio. - forgot_pass: '¿Has olvidado la contraseña?' - name: - label: Nombre - msg: - empty: El nombre no puede estar vacío. - range: El nombre debe tener entre 2 y 30 caracteres de largo. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: Correo electrónico - msg: - empty: El correo electrónico no puede estar vacío. - password: - label: Contraseña - msg: - empty: La contraseña no puede estar vacía. - different: Las contraseñas introducidas en ambos lados no coinciden - account_forgot: - page_title: Olvidaste Tu Contraseña - btn_name: Enviadme un correo electrónico de recuperación - send_success: >- - Si existe una cuenta con el correo {{mail}}, deberías de recibir un email con instrucciones sobre cómo recuperar tu contraseña próximamente. - email: - label: Correo electrónico - msg: - empty: El correo electrónico no puede estar vacío. - change_email: - btn_cancel: Cancelar - btn_update: Actualizar dirección de correo - send_success: >- - Si existe una cuenta con el correo {{mail}}, deberías de recibir un email con instrucciones sobre cómo recuperar tu contraseña próximamente. - email: - label: Nuevo correo - msg: - empty: El correo electrónico no puede estar vacío. - oauth: - connect: Conectar con {{ auth_name }} - remove: Eliminar {{ auth_name }} - oauth_bind_email: - subtitle: Añade un correo de recuperación a tu cuenta. - btn_update: Actualizar dirección de correo - email: - label: Correo - msg: - empty: El correo no puede estar vacío. - modal_title: El correo ya está en uso. - modal_content: Este correo electrónico ha sido registrado. ¿Estás seguro de conectarlo a la cuenta existente? - modal_cancel: Cambiar correo - modal_confirm: Conectarse a la cuenta existente - password_reset: - page_title: Restablecimiento de Contraseña - btn_name: Restablecer mi contraseña - reset_success: >- - Tu contraseña ha sido actualizada con éxito; vas a ser redirigido a la página de inicio de sesión. - link_invalid: >- - Lo sentimos, este enlace de restablecimiento de contraseña ya no es válido. ¿Tal vez tu contraseña ya está restablecida? - to_login: Continuar a la página de inicio de sesión - password: - label: Contraseña - msg: - empty: La contraseña no puede estar vacía. - length: La longitud debe ser de entre 8 y 32 caracteres - different: Las contraseñas introducidas en ambos lados no coinciden - password_confirm: - label: Confirmar nueva contraseña - settings: - page_title: Ajustes - goto_modify: Ir a modificar - nav: - profile: Perfil - notification: Notificaciones - account: Cuenta - interface: Interfaz - profile: - heading: Perfil - btn_name: Guardar - display_name: - label: Nombre público - msg: El nombre a mostrar no puede estar vacío. - msg_range: Display name must be 2-30 characters in length. - username: - label: Nombre de usuario - caption: La gente puede mencionarte con "@nombredeusuario". - msg: El nombre de usuario no puede estar vacío. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Imagen de perfil - gravatar: Gravatar - gravatar_text: Puedes cambiar la imagen en - custom: Propia - custom_text: Puedes subir tu propia imagen. - default: Sistema - msg: Por favor, sube una imagen - bio: - label: Sobre mí - website: - label: Sitio Web - placeholder: "https://example.com" - msg: Formato del sitio web incorrecto - location: - label: Ubicación - placeholder: "Ciudad, País" - notification: - heading: Notificaciones por correo - turn_on: Activar - inbox: - label: Notificaciones de bandeja - description: Respuestas a tus preguntas, comentarios, invitaciones, y más. - all_new_question: - label: Todas las preguntas nuevas - description: Recibe notificaciones de todas las preguntas nuevas. Hasta 50 preguntas por semana. - all_new_question_for_following_tags: - label: Todas las preguntas nuevas para las etiquetas siguientes - description: Recibe notificaciones de nuevas preguntas para las etiquetas siguientes. - account: - heading: Cuenta - change_email_btn: Cambiar correo electrónico - change_pass_btn: Cambiar contraseña - change_email_info: >- - Te hemos enviado un email a esa dirección. Por favor sigue las instrucciones de confirmación. - email: - label: Correo - new_email: - label: Nuevo correo - msg: El nuevo correo no puede estar vacío. - pass: - label: Contraseña actual - msg: La contraseña no puede estar vacía. - password_title: Contraseña - current_pass: - label: Contraseña actual - msg: - empty: La contraseña actual no puede estar vacía. - length: El largo necesita estar entre 8 y 32 caracteres. - different: Las contraseñas no coinciden. - new_pass: - label: Nueva contraseña - pass_confirm: - label: Confirmar nueva contraseña - interface: - heading: Interfaz - lang: - label: Idioma de Interfaz - text: Idioma de la interfaz de usuario. Cambiará cuando actualices la página. - my_logins: - title: Mis accesos - label: Inicia sesión o regístrate en este sitio usando estas cuentas. - modal_title: Eliminar acceso - modal_content: '¿Estás seguro de querer eliminar esta sesión de tu cuenta?' - modal_confirm_btn: Eliminar - remove_success: Eliminado con éxito - toast: - update: actualización correcta - update_password: Contraseña cambiada con éxito. - flag_success: Gracias por reportar. - forbidden_operate_self: No puedes modificar tu propio usuario - review: Tu revisión será visible luego de ser aprobada. - sent_success: Enviado con éxito - related_question: - title: Related - answers: respuestas - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Personas Preguntadas - desc: Selecciona personas que creas que sepan la respuesta. - invite: Invitar a responder - add: Añadir personas - search: Buscar personas - question_detail: - action: Acción - created: Created - Asked: Preguntada - asked: preguntada - update: Modificada - Edited: Edited - edit: editada - commented: comentado - Views: Visto - Follow: Seguir - Following: Siguiendo - follow_tip: Sigue esta pregunta para recibir notificaciones - answered: respondida - closed_in: Cerrado el - show_exist: Mostrar una pregunta existente. - useful: Útil - question_useful: Es útil y claro - question_un_useful: Es poco claro o no es útil - question_bookmark: Añadir esta pregunta a marcadores - answer_useful: Es útil - answer_un_useful: No es útil - answers: - title: Respuestas - score: Puntuación - newest: Más reciente - oldest: Más antiguo - btn_accept: Aceptar - btn_accepted: Aceptada - write_answer: - title: Tu respuesta - edit_answer: Editar mi respuesta existente - btn_name: Publica tu respuesta - add_another_answer: Añadir otra respuesta - confirm_title: Continuar a pregunta - continue: Continuar - confirm_info: >- -

        ¿Seguro que quieres añadir otra respuesta?

        Puedes utilizar el enlace de edición para detallar y mejorar tu respuesta existente en su lugar.

        - empty: La respuesta no puede estar vacía. - characters: el contenido debe tener al menos 6 caracteres. - tips: - header_1: Gracias por tu respuesta - li1_1: Asegúrate de responder la pregunta. Proporciona detalles y comparte tu investigación. - li1_2: Respalda cualquier declaración que hagas con referencias o experiencia personal. - header_2: Pero evita ... - li2_1: Pedir ayuda, pedir aclaraciones, o responder a otras respuestas. - reopen: - confirm_btn: Reabrir - title: Reabrir esta publicación - content: '¿Seguro que quieres reabrir esta publicación?' - list: - confirm_btn: Lista - title: Listar esta publicación - content: '¿Estás seguro de que quieres listar?' - unlist: - confirm_btn: Deslistar - title: No listar esta publicación - content: '¿Estás seguro de que quieres dejar de listar?' - pin: - title: Fijar esta publicación - content: '¿Estás seguro de querer fijar esto globalmente? Esta publicación aparecerá por encima de todas las listas de publicaciones.' - confirm_btn: Fijar - delete: - title: Eliminar esta publicación - question: >- - No recomendamos borrar preguntas con respuestas porque esto priva a los lectores futuros de este conocimiento.

        El borrado repetido de preguntas respondidas puede resultar en que tu cuenta se bloquee para hacer preguntas. ¿Estás seguro de que deseas borrarlo? - answer_accepted: >- -

        No recomendamos borrar la respuesta aceptada porque esto priva a los lectores futuros de este conocimiento.

        El borrado repetido de respuestas aceptadas puede resultar en que tu cuenta se bloquee para responder. ¿Estás seguro de que deseas borrarlo? - other: '¿Estás seguro de que deseas borrarlo?' - tip_answer_deleted: Esta respuesta ha sido eliminada - undelete_title: Restaurar esta publicación - undelete_desc: '¿Estás seguro de querer restaurar?' - btns: - confirm: Confirmar - cancel: Cancelar - edit: Editar - save: Guardar - delete: Eliminar - undelete: Restaurar - list: Lista - unlist: Deslistar - unlisted: Sin enumerar - login: Acceder - signup: Registrarse - logout: Cerrar sesión - verify: Verificar - create: Create - approve: Aprobar - reject: Rechazar - skip: Omitir - discard_draft: Descartar borrador - pinned: Fijado - all: Todo - question: Pregunta - answer: Respuesta - comment: Comentario - refresh: Actualizar - resend: Reenviar - deactivate: Desactivar - active: Activar - suspend: Suspender - unsuspend: Quitar suspensión - close: Cerrar - reopen: Reabrir - ok: Aceptar - light: Claro - dark: Oscuro - system_setting: Ajuste de sistema - default: Por defecto - reset: Reiniciar - tag: Etiqueta - post_lowercase: publicación - filter: Filtro - ignore: Ignorar - submit: Enviar - normal: Normal - closed: Cerrado - deleted: Eliminado - deleted_permanently: Deleted permanently - pending: Pendiente - more: Más - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Resultados de la búsqueda - keywords: Palabras claves - options: Opciones - follow: Seguir - following: Siguiendo - counts: "{{count}} Resultados" - counts_loading: "... Results" - more: Más - sort_btns: - relevance: Relevancia - newest: Más reciente - active: Activas - score: Puntuación - more: Mas - tips: - title: Consejos de búsqueda avanzada - tag: "<1>[tag] búsqueda por etiquetas" - user: "<1>user:username búsqueda por autor" - answer: "<1>answers:0 preguntas sin responder" - score: "<1>score:3 Publicaciones con un puntaje de 3 o más" - question: "<1>is:question buscar preguntas" - is_answer: "<1>is:answer buscar respuestas" - empty: No pudimos encontrar nada.
        Prueba a buscar con palabras diferentes o menos específicas. - share: - name: Compartir - copy: Copiar enlace - via: Compartir vía... - copied: Copiado - facebook: Compartir en Facebook - twitter: Share to X - cannot_vote_for_self: No puedes votar tu propia publicación. - modal_confirm: - title: Error... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Tu nueva cuenta ha sido confirmada, serás redirigido a la página de inicio. - link: Continuar a la página de inicio - oops: '¡Ups!' - invalid: El enlace que utilizaste ya no funciona. - confirm_new_email: Tu email ha sido actualizado. - confirm_new_email_invalid: >- - Lo siento, este enlace de confirmación ya no es válido. ¿Quizás ya se haya cambiado tu correo electrónico? - unsubscribe: - page_title: Desuscribir - success_title: Desuscrito con éxito - success_desc: Ha sido eliminado con éxito de esta lista de suscriptores y no recibirá más correos electrónicos nuestros. - link: Cambiar ajustes - question: - following_tags: Etiquetas seguidas - edit: Editar - save: Guardar - follow_tag_tip: Sigue etiquetas para personalizar tu lista de preguntas. - hot_questions: Preguntas del momento - all_questions: Todas las preguntas - x_questions: "{{ count }} Preguntas" - x_answers: "{{ count }} respuestas" - x_posts: "{{ count }} Posts" - questions: Preguntas - answers: Respuestas - newest: Más reciente - active: Activo - hot: Popular - frequent: Frecuente - recommend: Recomendar - score: Puntuación - unanswered: Sin respuesta - modified: modificada - answered: respondida - asked: preguntada - closed: cerrada - follow_a_tag: Seguir una etiqueta - more: Más - personal: - overview: Información general - answers: Respuestas - answer: respuesta - questions: Preguntas - question: pregunta - bookmarks: Guardadas - reputation: Reputación - comments: Comentarios - votes: Votos - badges: Insignias - newest: Más reciente - score: Puntuación - edit_profile: Editar perfil - visited_x_days: "Visitado {{ count }} días" - viewed: Visto - joined: Unido - comma: "," - last_login: Visto - about_me: Sobre mí - about_me_empty: "// ¡Hola Mundo!" - top_answers: Mejores respuestas - top_questions: Preguntas Principales - stats: Estadísticas - list_empty: No se encontraron publicaciones.
        ¿Quizás le gustaría seleccionar una pestaña diferente? - content_empty: No se han encontrado publicaciones. - accepted: Aceptada - answered: respondida - asked: preguntó - downvoted: votado negativamente - mod_short: MOD - mod_long: Moderadores - x_reputation: reputación - x_votes: votos recibidos - x_answers: respuestas - x_questions: preguntas - recent_badges: Insignias recientes - install: - title: Instalación - next: Próximo - done: Hecho - config_yaml_error: No se puede crear el archivo config.yaml. - lang: - label: Elige un idioma - db_type: - label: Motor de base de datos - db_username: - label: Nombre de usuario - placeholder: raíz - msg: El nombre de usuario no puede estar vacío. - db_password: - label: Contraseña - placeholder: raíz - msg: La contraseña no puede estar vacía. - db_host: - label: Host de base de datos - placeholder: "db:3306" - msg: El host de base de datos no puede estar vacío. - db_name: - label: Nombre de base de datos - placeholder: respuesta - msg: El nombre de la base de datos no puede estar vacío. - db_file: - label: Archivo de base de datos - placeholder: /data/respuesta.db - msg: El archivo de la base de datos no puede estar vacío. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Crear config.yaml - label: El archivo config.yaml creado. - desc: >- - Puede crear el archivo <1>config.yaml manualmente en el directorio <1>/var/www/xxx/ y pegar el siguiente texto en él. - info: Después de haber hecho eso, haga clic en el botón "Siguiente". - site_information: Información del sitio - admin_account: Cuenta de administrador - site_name: - label: Nombre del sitio - msg: El nombre del sitio no puede estar vacío. - msg_max_length: El nombre del sitio tener como máximo 30 caracteres. - site_url: - label: Sitio URL - text: La dirección de su sitio. - msg: - empty: La URL del sitio no puede estar vacía. - incorrect: Formato incorrecto de la URL del sitio. - max_length: El URL del sitio debe tener como máximo 512 caracteres. - contact_email: - label: Correo electrónico de contacto - text: Dirección de correo electrónico del contacto clave responsable de este sitio. - msg: - empty: El correo electrónico de contacto no puede estar vacío. - incorrect: Formato incorrecto de correo electrónico de contacto. - login_required: - label: Privado - switch: Inicio de sesión requerido - text: Solo usuarios conectados pueden acceder a esta comunidad. - admin_name: - label: Nombre - msg: El nombre no puede estar vacío. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Contraseña - text: >- - Necesitará esta contraseña para iniciar sesión. Guárdela en un lugar seguro. - msg: La contraseña no puede estar vacía. - msg_min_length: La contraseña debe contener 8 caracteres como mínimo. - msg_max_length: La contraseña debe contener como máximo 32 caracteres. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: Correo electrónico - text: Necesitará este correo electrónico para iniciar sesión. - msg: - empty: El correo electrónico no puede estar vacío. - incorrect: Correo electrónico con formato incorrecto. - ready_title: Tu sitio está listo - ready_desc: >- - Si alguna vez desea cambiar más configuraciones, visite la <1>sección de administración; encuéntrelo en el menú del sitio. - good_luck: "¡Diviértete y buena suerte!" - warn_title: Advertencia - warn_desc: >- - El archivo <1>config.yaml ya existe. Si necesita restablecer alguno de los elementos de configuración de este archivo, elimínelo primero. - install_now: Puede intentar <1>instalar ahora. - installed: Ya instalado - installed_desc: >- - Parece que ya lo has instalado. Para reinstalar, borre primero las tablas de la base de datos anterior. - db_failed: La conexión a la base de datos falló - db_failed_desc: >- - Esto significa que la información de la base de datos en tu archivo <1>config.yaml es incorrecta o que no pudo establecerse contacto con el servidor de la base de datos. Esto podría significar que el host está caído. - counts: - views: puntos de vista - votes: votos - answers: respuestas - accepted: Aceptado - page_error: - http_error: Error HTTP {{ code }} - desc_403: No tienes permiso para acceder a esta página. - desc_404: Desafortunadamente, esta página no existe. - desc_50X: Se produjo un error en el servidor y no pudo completarse tu solicitud. - back_home: Volver a la página de inicio - page_maintenance: - desc: "Estamos en mantenimiento, pronto estaremos de vuelta." - nav_menus: - dashboard: Panel - contents: Contenido - questions: Preguntas - answers: Respuestas - users: Usuarios - badges: Insignias - flags: Banderas - settings: Ajustes - general: General - interface: Interfaz - smtp: SMTP - branding: Marca - legal: Legal - write: Escribir - terms: Terms - tos: Términos de servicio - privacy: Privacidad - seo: ESTE - customize: Personalizar - themes: Temas - login: Iniciar sesión - privileges: Privilegios - plugins: Extensiones - installed_plugins: Extensiones Instaladas - apperance: Appearance - website_welcome: Bienvenido a {{site_name}} - user_center: - login: Iniciar sesión - qrcode_login_tip: Por favor utiliza {{ agentName }} para escanear el código QR e iniciar sesión. - login_failed_email_tip: Error al iniciar sesión, por favor permite el acceso a tu información de correo de esta aplicación antes de intentar nuevamente. - badges: - modal: - title: Enhorabuena - content: Has ganado una nueva insignia. - close: Cerrar - confirm: Ver insignia - title: Insignias - awarded: Premiado - earned_×: Obtenidos ×{{ number }} - ×_awarded: "{{ number }} adjudicado" - can_earn_multiple: Puedes ganar esto varias veces. - earned: Ganado - admin: - admin_header: - title: Administrador - dashboard: - title: Panel - welcome: '¡Bienvenido a Admin!' - site_statistics: Estadísticas del sitio - questions: "Preguntas:" - resolved: "Resuelto:" - unanswered: "Sin respuesta:" - answers: "Respuestas:" - comments: "Comentarios:" - votes: "Votos:" - users: "Usuarios:" - flags: "Banderas:" - reviews: "Revisar:" - site_health: Salud del sitio - version: "Versión:" - https: "HTTPS:" - upload_folder: "Cargar carpeta:" - run_mode: "Modo de ejecución:" - private: Privado - public: Público - smtp: "SMTP:" - timezone: "Zona horaria:" - system_info: Información del sistema - go_version: "Versión de Go:" - database: "Base de datos:" - database_size: "Tamaño de la base de datos:" - storage_used: "Almacenamiento utilizado:" - uptime: "Tiempo ejecutándose:" - links: Enlaces - plugins: Extensiones - github: GitHub - blog: Blog - contact: Contacto - forum: Foro - documents: Documentos - feedback: Comentario - support: Soporte - review: Revisar - config: Configuración - update_to: Actualizar para - latest: Lo más nuevo - check_failed: Comprobación fallida - "yes": "Si" - "no": "No" - not_allowed: No permitido - allowed: Permitido - enabled: Activado - disabled: Desactivado - writable: Redactable - not_writable: No redactable - flags: - title: Banderas - pending: Pendiente - completed: Terminado - flagged: Marcado - flagged_type: Reportado {{ type }} - created: Creado - action: Acción - review: Revisar - user_role_modal: - title: Cambiar rol de usuario a... - btn_cancel: Cancelar - btn_submit: Entregar - new_password_modal: - title: Establecer nueva contraseña - form: - fields: - password: - label: Contraseña - text: El usuario será desconectado y deberá iniciar sesión nuevamente. - msg: La contraseña debe contener entre 8 y 32 caracteres de longitud. - btn_cancel: Cancelar - btn_submit: Enviar - edit_profile_modal: - title: Editar perfil - form: - fields: - display_name: - label: Nombre para mostrar - msg_range: Display name must be 2-30 characters in length. - username: - label: Nombre de usuario - msg_range: Username must be 2-30 characters in length. - email: - label: Correo electrónico - msg_invalid: Dirección de correo inválida. - edit_success: Editado exitosamente - btn_cancel: Cancelar - btn_submit: Enviar - user_modal: - title: Añadir nuevo usuario - form: - fields: - users: - label: Añadir usuarios en cantidad - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separe “nombre, correo electrónico, contraseña” con comas. Un usuario por línea. - msg: "Por favor, introduzca el correo electrónico del usuario, uno por línea." - display_name: - label: Nombre público - msg: El nombre de la pantalla debe tener entre 2 y 30 caracteres de longitud. - email: - label: Correo - msg: El correo no es válido. - password: - label: Contraseña - msg: La contraseña debe contener entre 8 y 32 caracteres de longitud. - btn_cancel: Cancelar - btn_submit: Enviar - users: - title: Usuarios - name: Nombre - email: Correo electrónico - reputation: Reputación - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Estado - role: Rol - action: Acción - change: Cambiar - all: Todo - staff: Personal - more: Más - inactive: Inactivo - suspended: Suspendido - deleted: Eliminado - normal: Normal - Moderator: Moderador - Admin: Administrador - User: Usuario - filter: - placeholder: "Filtrar por nombre, usuario:id" - set_new_password: Establecer nueva contraseña - edit_profile: Editar perfil - change_status: Cambiar Estado - change_role: Cambiar rol - show_logs: Mostrar registros - add_user: Agregar usuario - deactivate_user: - title: Desactivar usuario - content: Un usuario inactivo debe revalidar su correo electrónico. - delete_user: - title: Eliminar este usuario - content: '¿Estás seguro de que deseas eliminar este usuario? ¡Esto es permanente!' - remove: Eliminar su contenido - label: Eliminar todas las preguntas, respuestas, comentarios, etc. - text: No marque esto si solo desea eliminar la cuenta del usuario. - suspend_user: - title: Suspender a este usuario - content: Un usuario suspendido no puede iniciar sesión. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Preguntas - unlisted: No listado - post: Correo - votes: Votos - answers: Respuestas - created: Creado - status: Estado - action: Acción - change: Cambiar - pending: Pendiente - filter: - placeholder: "Filtrar por título, pregunta:id" - answers: - page_title: Respuestas - post: Correo - votes: Votos - created: Creado - status: Estado - action: Acción - change: Cambiar - filter: - placeholder: "Filtrar por título, respuesta: id" - general: - page_title: General - name: - label: Nombre del sitio - msg: El nombre del sitio no puede estar vacío. - text: "El nombre de este sitio, tal como se usa en la etiqueta del título." - site_url: - label: Sitio URL - msg: La url del sitio no puede estar vacía. - validate: Por favor introduzca un URL válido. - text: La dirección de su sitio. - short_desc: - label: Descripción breve del sitio - msg: La descripción breve del sitio no puede estar vacía. - text: "Breve descripción, tal como se usa en la etiqueta del título en la página de inicio." - desc: - label: Descripción del sitio - msg: La descripción del sitio no puede estar vacía. - text: "Describa este sitio en una oración, como se usa en la etiqueta de meta descripción." - contact_email: - label: Correo electrónico de contacto - msg: El correo electrónico de contacto no puede estar vacío. - validate: El correo electrónico de contacto no es válido. - text: Dirección de correo electrónico del contacto clave responsable de este sitio. - check_update: - label: Actualizaciones de software - text: Comprobar actualizaciones automáticamente - interface: - page_title: Interfaz - language: - label: Idioma de Interfaz - msg: El idioma de la interfaz no puede estar vacío. - text: Idioma de la interfaz de usuario. Cambiará cuando actualice la página. - time_zone: - label: Zona horaria - msg: El huso horario no puede estar vacío. - text: Elija una ciudad en la misma zona horaria que usted. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: Desde correo - msg: Desde el correo electrónico no puede estar vacío. - text: La dirección de correo electrónico desde la que se envían los correos electrónicos. - from_name: - label: Desde nombre - msg: Desde el nombre no puede estar vacío. - text: El nombre desde el que se envían los correos electrónicos. - smtp_host: - label: Host SMTP - msg: El host SMTP no puede estar vacío. - text: Su servidor de correo. - encryption: - label: Cifrado - msg: El cifrado no puede estar vacío. - text: Para la mayoría de los servidores, SSL es la opción recomendada. - ssl: SSL - tls: TLS - none: Ninguno - smtp_port: - label: Puerto SMTP - msg: El puerto SMTP debe ser el número 1 ~ 65535. - text: El puerto a su servidor de correo. - smtp_username: - label: Nombre de usuario SMTP - msg: El nombre de usuario SMTP no puede estar vacío. - smtp_password: - label: Contraseña de SMTP - msg: La contraseña SMTP no puede estar vacía. - test_email_recipient: - label: Destinatarios de correo electrónico de prueba - text: Proporcione la dirección de correo electrónico que recibirá los envíos de prueba. - msg: Los destinatarios de correo electrónico de prueba no son válidos - smtp_authentication: - label: Habilitar autenticación - title: Autenticación SMTP - msg: La autenticación SMTP no puede estar vacía. - "yes": "Si" - "no": "No" - branding: - page_title: Marca - logo: - label: Logo - msg: El logotipo no puede estar vacío. - text: La imagen del logotipo en la parte superior izquierda de su sitio. Utilice una imagen rectangular ancha con una altura de 56 y una relación de aspecto superior a 3:1. Si se deja en blanco, se mostrará el texto del título del sitio. - mobile_logo: - label: Logo Móvil - text: El logotipo utilizado en la versión móvil de su sitio. Utilice una imagen rectangular ancha con una altura de 56. Si se deja en blanco, se utilizará la imagen de la configuración de "logotipo". - square_icon: - label: Icono cuadrado - msg: El icono cuadrado no puede estar vacío. - text: Imagen utilizada como base para los iconos de metadatos. Idealmente, debería ser más grande que 512x512. - favicon: - label: Icono de favoritos - text: Un favicon para su sitio. Para que funcione correctamente sobre un CDN, debe ser un png. Se cambiará el tamaño a 32x32. Si se deja en blanco, se utilizará el "icono cuadrado". - legal: - page_title: Legal - terms_of_service: - label: Términos de servicio - text: "Puede agregar términos de contenido de servicio aquí. Si ya tiene un documento alojado en otro lugar, proporcione la URL completa aquí." - privacy_policy: - label: Política de privacidad - text: "Puede agregar contenido de política de privacidad aquí. Si ya tiene un documento alojado en otro lugar, proporcione la URL completa aquí." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Escribir - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Escribir respuesta - label: Cada usuario solo puede escribir una respuesta por pregunta - text: "Desactivar para permitir a los usuarios escribir múltiples respuestas a la misma pregunta, lo que puede causar que las respuestas no estén enfocadas." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Etiquetas recomendadas - text: "Las etiquetas recomendadas se mostrarán en la lista desplegable por defecto." - msg: - contain_reserved: "las etiquetas recomendadas no pueden contener etiquetas reservadas" - required_tag: - title: Establecer etiquetas necesarias - label: Establecer "Etiquetas recomendadas" como etiquetas requeridas - text: "Cada nueva pregunta debe tener al menos una etiqueta de recomendación." - reserved_tags: - label: Etiquetas reservadas - text: "Las etiquetas reservadas sólo pueden ser usadas por el moderador." - image_size: - label: Tamaño máximo de la imagen (MB) - text: "Tamaño máximo de la imagen." - attachment_size: - label: Tamaño máximo del archivo adjunto (MB) - text: "El tamaño máximo de subida de archivos adjuntos." - image_megapixels: - label: Megapixels de imagen máx - text: "Número máximo de megapixels permitidos para una imagen." - image_extensions: - label: Extensiones de adjuntos autorizadas - text: "Una lista de extensiones de archivo permitidas para la visualización de imágenes, separadas con comas." - attachment_extensions: - label: Extensiones de adjuntos autorizadas - text: "Una lista de extensiones de archivo permitidas para subir, separadas con comas. ADVERTENCIA: Permitir subidas puede causar problemas de seguridad." - seo: - page_title: SEO - permalink: - label: Enlace permanente - text: Las estructuras de URL personalizadas pueden mejorar la facilidad de uso y la compatibilidad futura de sus enlaces. - robots: - label: robots.txt - text: Esto anulará permanentemente cualquier configuración del sitio relacionada. - themes: - page_title: Temas - themes: - label: Temas - text: Seleccione un tema existente. - color_scheme: - label: Esquema de color - navbar_style: - label: Navbar background style - primary_color: - label: Color primario - text: Modifica los colores usados por tus temas - css_and_html: - page_title: CSS y HTML - custom_css: - label: CSS personalizado - text: > - - head: - label: Cabeza - text: > - - header: - label: Encabezado - text: > - - footer: - label: Pie de página - text: Esto se insertará antes . - sidebar: - label: Barra lateral - text: Esto se añadirá en la barra lateral. - login: - page_title: Iniciar sesión - membership: - title: Membresía - label: Permitir registro de nuevas ceuntas - text: Desactiva esto para evitar que cualquier persona pueda crear una cuenta. - email_registration: - title: Registro de correo electrónico - label: Permitir registro de correo electrónico - text: Desactivar para evitar registros a través de correo electrónico. - allowed_email_domains: - title: Dominios de correo electrónico permitidos - text: Dominios de correo electrónico con los que los usuarios deben registrar sus cuentas. Un dominio por línea. Ignorado cuando esté vacío. - private: - title: Privado - label: Inicio de sesión requerido - text: Sólo usuarios con sesión iniciada pueden acceder a esta comunidad. - password_login: - title: Inicio de sesión con contraseña - label: Permitir inicio de sesión con correo y contraseña - text: "ADVERTENCIA: Si se desactiva, es posible que no pueda iniciar sesión si no ha configurado previamente otro método de inicio de sesión." - installed_plugins: - title: Extensiones Instaladas - plugin_link: Los plugins extienden y expanden la funcionalidad. Puede encontrar plugins en el <1>Repositorio de plugin. - filter: - all: Todos - active: Activo - inactive: Inactivo - outdated: Desactualizado - plugins: - label: Extensiones - text: Seleccione una extensión existente. - name: Nombre - version: Versión - status: Estado - action: Acción - deactivate: Desactivar - activate: Activar - settings: Ajustes - settings_users: - title: Usuarios - avatar: - label: Avatar predeterminado - text: Para usuarios sin un avatar personalizado propio. - gravatar_base_url: - label: Gravatar Base URL - text: URL de la base API del proveedor Gravatar. Ignorado cuando esté vacío. - profile_editable: - title: Perfil editable - allow_update_display_name: - label: Permitir a usuarios cambiar su nombre público - allow_update_username: - label: Permitir a los usuarios cambiar su nombre de usuario - allow_update_avatar: - label: Permitir a los usuarios cambiar su foto de perfil - allow_update_bio: - label: Permitir a los usuarios cambiar su descripción - allow_update_website: - label: Permitir a los usuarios cambiar su sitio web - allow_update_location: - label: Permitir a los usuarios cambiar su ubicación - privilege: - title: Privilegios - level: - label: Nivel de reputación requerido - text: Elegir reputación requerida para los privilegios - msg: - should_be_number: la entrada debe ser número - number_larger_1: número debe ser igual o mayor que 1 - badges: - action: Accin - active: Activo - activate: Activación - all: All - awards: Premios - deactivate: Desactivar - filter: - placeholder: Filtrar por nombre, insignia:id - group: Grupo - inactive: Inactivo - name: Nombre - show_logs: Mostrar logs - status: Status - title: Insignias - form: - optional: (opcional) - empty: no puede estar en blanco - invalid: no es válido - btn_submit: Guardar - not_found_props: "La propiedad requerida {{ key }} no se ha encontrado." - select: Seleccionar - page_review: - review: Revisar - proposed: propuesto - question_edit: Edición de preguntas - answer_edit: Edición de respuestas - tag_edit: Edición de etiquetas - edit_summary: Editar resumen - edit_question: Editar pregunta - edit_answer: Editar respuesta - edit_tag: Editar etiqueta - empty: No quedan tareas de revisión. - approve_revision_tip: '¿Aprueban ustedes esta revisión?' - approve_flag_tip: '¿Aprueban ustedes esta bandera?' - approve_post_tip: '¿Aprueban ustedes esta bandera?' - approve_user_tip: '¿Apruebas a este usuario?' - suggest_edits: Ediciones Sugeridas - flag_post: Marcar publicación - flag_user: Marcar usuario - queued_post: Publicación en cola - queued_user: Usuario en cola - filter_label: Tipo - reputation: reputación - flag_post_type: Marcada esta publicación como {{ type }}. - flag_user_type: Marcado este usuario como {{ type }}. - edit_post: Editar publicación - list_post: Listar publicación - unlist_post: Deslistar publicación - timeline: - undeleted: recuperado - deleted: eliminado - downvote: voto negativo - upvote: votar a favor - accept: aceptar - cancelled: cancelado - commented: comentado - rollback: retroceder - edited: editada - answered: contestada - asked: preguntó - closed: cerrado - reopened: reabierto - created: creado - pin: fijado - unpin: desfijado - show: listado - hide: deslistado - title: "Historial para" - tag_title: "Línea temporal para" - show_votes: "Mostrar votos" - n_or_a: N/A - title_for_question: "Línea de tiempo para" - title_for_answer: "Cronología de la respuesta a {{ title }} por {{ author }}" - title_for_tag: "Cronología de la etiqueta" - datetime: Fecha y hora - type: Tipo - by: Por - comment: Comentario - no_data: "No pudimos encontrar nada." - users: - title: Usuarios - users_with_the_most_reputation: Usuarios con el mayor puntaje de reputación esta semana - users_with_the_most_vote: Usuarios que más votaron esta semana - staffs: Nuestor equipo de la comunidad - reputation: reputación - votes: votos - prompt: - leave_page: '¿Seguro que quieres salir de la página?' - changes_not_save: Es posible que sus cambios no se guarden. - draft: - discard_confirm: '¿Está seguro de que desea descartar este borrador?' - messages: - post_deleted: Esta publicación ha sido eliminada. - post_cancel_deleted: Este publicación ha sido restaurada. - post_pin: Esta publicación ha sido fijada. - post_unpin: Esta publicación ha sido desfijada. - post_hide_list: Esta publicación ha sido ocultada de la lista. - post_show_list: Esta publicación ha sido mostrada a la lista. - post_reopen: Esta publicación ha sido reabierta. - post_list: Esta publicación ha sido listada. - post_unlist: Esta publicación ha sido retirado de la lista.. - post_pending: Su publicación está pendiente de revisión. Esto es una vista previa, será visible después de que haya sido aprobado. - post_closed: Esta publicación ha sido cerrada. - answer_deleted: Esta respuesta ha sido eliminada. - answer_cancel_deleted: Esta respuesta ha sido restaurada. - change_user_role: El rol de este usuario ha sido cambiado. - user_inactive: Este usuario ya esta inactivo. - user_normal: Este usuario ya es normal. - user_suspended: Este usuario ha sido suspendido. - user_deleted: Este usuario ha sido eliminado. - badge_activated: Esta insignia ha sido activada. - badge_inactivated: Esta insignia ha sido desactivada. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/fa_IR.yaml b/data/i18n/fa_IR.yaml deleted file mode 100644 index 5bff8a821..000000000 --- a/data/i18n/fa_IR.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: موفق. - unknown: - other: خطای ناشناخته. - request_format_error: - other: ساختار درخواست شناخته شده نیست. - unauthorized_error: - other: دسترسی غیر مجاز. - database_error: - other: خطای سرور داده. - forbidden_error: - other: عدم اجازه دسترسی. - duplicate_request_error: - other: ارسال تکراری. - action: - report: - other: نشان - edit: - other: ویرایش - delete: - other: حذف - close: - other: بستن - reopen: - other: بازگشایی - forbidden_error: - other: عدم اجازه دسترسی. - pin: - other: سنجاق کردن - hide: - other: پنهان کردن - unpin: - other: برداشتن سنجاق - show: - other: فهرست - invite_someone_to_answer: - other: ویرایش - undelete: - other: بازگردانی حذف - merge: - other: Merge - role: - name: - user: - other: کاربر - admin: - other: ادمین - moderator: - other: مدير - description: - user: - other: پیش فرض بدون دسترسی خاص. - admin: - other: تمامی دسترسی ها را داراست. - moderator: - other: دسترسی به تمامی پست هارا داراست بجز تنظیمات ادمین. - privilege: - level_1: - description: - other: سطح ۱ (شهرت کمی نیاز هست برای تیم/گروه های خصوصی) - level_2: - description: - other: سطح ۲ (شهرت کمی نیاز هست برای انجمن های استارتاپی) - level_3: - description: - other: سطح ۳ (شهرت بالایی برای نیاز هست برای انجمن های تکمیل) - level_custom: - description: - other: سطح دلخواه - rank_question_add_label: - other: سوال بپرس - rank_answer_add_label: - other: جواب بده - rank_comment_add_label: - other: نظر بده - rank_report_add_label: - other: نشان - rank_comment_vote_up_label: - other: رای موافق - rank_link_url_limit_label: - other: بیشتر از دو لینک را هم زمان پست کنید - rank_question_vote_up_label: - other: رای موافق - rank_answer_vote_up_label: - other: رای موافق - rank_question_vote_down_label: - other: رای مخالف - rank_answer_vote_down_label: - other: رای مخالف - rank_invite_someone_to_answer_label: - other: فردی رو دعوت کنین تا جواب بدن - rank_tag_add_label: - other: ساخت تگ جدید - rank_tag_edit_label: - other: ویرایش توضیحات تگ (نیازمند بازبینی) - rank_question_edit_label: - other: ویرایش سوال دیگران (نیازمند بازبینی) - rank_answer_edit_label: - other: ویرایش جواب دیگران (نیازمند بازبینی) - rank_question_edit_without_review_label: - other: ویرایش سوال دیگران بدون نیاز به بازبینی - rank_answer_edit_without_review_label: - other: ویرایش جواب دیگران بدون نیاز به بازبینی - rank_question_audit_label: - other: بازبینی ویرایش های سوال - rank_answer_audit_label: - other: بازبینی ویرایش های جواب - rank_tag_audit_label: - other: بازبینی ویرایش های تگ - rank_tag_edit_without_review_label: - other: ویرایش توضیحات تگ بدون بازبینی - rank_tag_synonym_label: - other: مدیریت تگ های مترادف - email: - other: ایمیل - e_mail: - other: ایمیل - password: - other: رمز - pass: - other: رمز - old_pass: - other: Current password - original_text: - other: پست جاری - email_or_password_wrong_error: - other: ایمیل و رمز وارد شده صحیح نیست. - error: - common: - invalid_url: - other: Invalid URL. - status_invalid: - other: Invalid status. - password: - space_invalid: - other: رمز عبور نمی تواند شامل فضای خالی باشد. - admin: - cannot_update_their_password: - other: نمیتوانید رمز عبور خود را تغییر دهید. - cannot_edit_their_profile: - other: You cannot modify your profile. - cannot_modify_self_status: - other: نمیتوانید وضعیت خود را تغییر دهید. - email_or_password_wrong: - other: ایمیل و رمز وارد شده صحیح نیست. - answer: - not_found: - other: جواب پیدا نشد. - cannot_deleted: - other: اجازه حذف ندارید. - cannot_update: - other: اجازه بروزرسانی ندارید. - question_closed_cannot_add: - other: سوالات بسته شده اند و نمیتوان سوالی اضافه کرد. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: نظرات قابل ویرایش نیستند. - not_found: - other: نظر پیدا نشد. - cannot_edit_after_deadline: - other: زمان زیادی برای ویرایش نظر گذشته است. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: ایمیل تکراری. - need_to_be_verified: - other: ایمیل باید تایید شود. - verify_url_expired: - other: لینک تایید ایمیل منقضی شده است،‌لطفا دوباره تلاش کنید. - illegal_email_domain_error: - other: دامنه ایمیل پیشتیبانی نمی شود، لطفا از ایمیل دیگری استفاده کنید. - lang: - not_found: - other: فایل زبان یافت نشد. - object: - captcha_verification_failed: - other: اشتباه در Captcha. - disallow_follow: - other: شما اجازه فالو کردن ندارید. - disallow_vote: - other: شما اجازه رای دادن ندارید. - disallow_vote_your_self: - other: شما نمی توانید به پست خودتان رای دهید. - not_found: - other: آبجکت مورد نظر پیدا نشد. - verification_failed: - other: تایید با خطا مواجه شد. - email_or_password_incorrect: - other: ایمیل و رمز وارد شده صحیح نیست. - old_password_verification_failed: - other: پسورد قدیمی تایید نشد - new_password_same_as_previous_setting: - other: پسورد جدید با پسورد قدیمی یکسان است. - already_deleted: - other: This post has been deleted. - meta: - object_not_found: - other: Meta object not found - question: - already_deleted: - other: این پست حذف شده است. - under_review: - other: Your post is awaiting review. It will be visible after it has been approved. - not_found: - other: سوال پیدا نشد. - cannot_deleted: - other: اجازه حذف ندارید. - cannot_close: - other: اجاره بستن ندارید. - cannot_update: - other: اجازه بروزرسانی ندارید. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: شهرت ناکافی. - vote_fail_to_meet_the_condition: - other: ممنون بابت بازخورد. شما حداقل به {{.Rank}} نیاز دارید برای رای دادن. - no_enough_rank_to_operate: - other: شما حداقل به {{.Rank}} نیاز دارید برای انجام این کار. - report: - handle_failed: - other: گزارش دهی با مشکل مواجه شد. - not_found: - other: گزارش مورد نظر پیدا نشد. - tag: - already_exist: - other: تگ از قبل موجود است. - not_found: - other: تگ پیدا نشد. - recommend_tag_not_found: - other: تگ پیشنهاد شده موجود نیست. - recommend_tag_enter: - other: لطفا حداقل یک تگ را وارد کنید. - not_contain_synonym_tags: - other: نباید تگ مترادف داشته باشد. - cannot_update: - other: اجازه بروزرسانی ندارید. - is_used_cannot_delete: - other: نمی توانید تگی که در حال استفاده است را حذف کنید. - cannot_set_synonym_as_itself: - other: شما نمی توانید مترادفی برای برچسب فعلی به عوان خودش تنظیم کنین. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: '"از طرفه" نمی تواند آدرس ایمیل باشد.' - theme: - not_found: - other: تم پیدا نشد. - revision: - review_underway: - other: فعلا امکان ویرایش وجود ندارد،‌این نسخه در صف بازینی قرار دارد. - no_permission: - other: اجاره بازبینی و اصلاح ندارید. - user: - external_login_missing_user_id: - other: پلتفورم های سوم شخص نمی توانند نام کاربر خاصی را ارائه دهند، بنابر این شما نمی توانید وارد شوید، لطفا با مدیریت وبسایت تماس بگیرید. - external_login_unbinding_forbidden: - other: لطفاً یک رمز ورود برای حساب خود قبل از حذف تنظیم کنید. - email_or_password_wrong: - other: - other: ایمیل و رمز وارد شده صحیح نیست. - not_found: - other: کاربر پیدا نشد. - suspended: - other: کاربر در حالت تعلیق قرار داده شده است. - username_invalid: - other: نام کاربری نامعتبر است. - username_duplicate: - other: این نام کاربری قبلا استفاده شده است. - set_avatar: - other: ست کردن آواتار با مشکل مواجه شد. - cannot_update_your_role: - other: شما نمی توانید وظیفه خود را تغییر دهید. - not_allowed_registration: - other: درحال حاضر سایت برای ثبت نام باز نیست. - not_allowed_login_via_password: - other: در حال حاضر سایت اجازه ورود از طریق رمز عبور ندارد. - access_denied: - other: دسترسی مجاز نیست - page_access_denied: - other: شما وجوز دسترسی به این صفحه را ندارید. - add_bulk_users_format_error: - other: "مشکل پیش آمده در فرمت {{.Field}} در کنار {{.Content}} در خط {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "تعداد کاربرانی که اضافه می کنید باید رنج بین ۱-{{.MaxAmount}} باشند." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: خواندن کافیگ با مشکل مواجه شد - database: - connection_failed: - other: اتصال به دیتابیس موفقیت آمیز نبود - create_table_failed: - other: ایجاد کردن جدول موفقیت آمیز نبود - install: - create_config_failed: - other: فایل config.yaml نمی تواند ایجاد شود. - upload: - unsupported_file_format: - other: فرمت فایل پشتیبانی نمی شود. - site_info: - config_not_found: - other: پیکربندی سایت پیدا نشد. - badge: - object_not_found: - other: Badge object not found - reason: - spam: - name: - other: هرزنامه - desc: - other: این پست یک تبلیغ یا خرابکاری است. این پس مفید یا مربوط به این موضوع نمی باشد. - rude_or_abusive: - name: - other: بی ادب یا توهین آمیز - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - a_duplicate: - name: - other: تکراری - desc: - other: این سوال قبلا پرسیده و جواب داده شده است. - placeholder: - other: لینک سوال مورد نظر را وارد کنید - not_a_answer: - name: - other: این یک پاسخ نیست - desc: - other: "." - no_longer_needed: - name: - other: دیگر نیازی نیست - desc: - other: این نظر منسوخ شده، مکلامه ای یا مربوط به این پس نیست. - something: - name: - other: یک مورد دیگر - desc: - other: این پست به دلیل دیگری که در بالا ذکر نشده نیاز به توجه کارکنان دارد. - placeholder: - other: به طور خاص به ما اطلاع دهید که در مورد چه چیزی نگران هستید - community_specific: - name: - other: یک دلیل خاص جامعه - desc: - other: این سوال با دستورالعمل جامعه مطابقت ندارد. - not_clarity: - name: - other: نیاز به جزئیات یا واضح کردن دارد - desc: - other: این سوال درحال حاضر شامل چندتا سوال در یکی هست. باید فقط روی یک مشکل تمرکز کند. - looks_ok: - name: - other: به نظر خوب میاد - desc: - other: این پست همانطور که هست خوب است و کیفیت پایینی ندارد. - needs_edit: - name: - other: نیاز به ویرایش بود، من انجام دادم - desc: - other: مشکلات این پست را خودتان بهبود و اصلاح کنید. - needs_close: - name: - other: نیاز است که بسته بشود - desc: - other: به یک سوال بسته شده نمیتوان جوابی ثبت کرد بلکه می توان ویرایش، رای و نظر داد. - needs_delete: - name: - other: نیاز است که حذف بشود - desc: - other: این پست حذف خواهد شد. - question: - close: - duplicate: - name: - other: هرزنامه - desc: - other: این سوال قبلا پرسیده و جواب داده شده است. - guideline: - name: - other: یک دلیل خاص جامعه - desc: - other: این سوال با دستورالعمل جامعه مطابقت ندارد. - multiple: - name: - other: نیاز به جزئیات یا واضح کردن دارد - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: یک مورد دیگر - desc: - other: این پست به دلیل دیگری نیاز دارد که در بالا ذکر نشده است. - operation_type: - asked: - other: پرسیده شده - answered: - other: جواب داده - modified: - other: تغییر یافته - deleted_title: - other: سوال حذف شده - questions_title: - other: Questions - tag: - tags_title: - other: Tags - no_description: - other: The tag has no description. - notification: - action: - update_question: - other: سوال بارگزاری شده - answer_the_question: - other: سؤال جواب داده شده - update_answer: - other: جواب بارگذاری شده - accept_answer: - other: جواب پذیرفته شده - comment_question: - other: سوال از کامنت - comment_answer: - other: جواب از کامنت - reply_to_you: - other: به شما پاسخ داد - mention_you: - other: به شما اشاره کرده - your_question_is_closed: - other: سوال شما بسته شده است - your_question_was_deleted: - other: سوال شما حذف شده است - your_answer_was_deleted: - other: جواب شما حذف شده است - your_comment_was_deleted: - other: نظر شما پاک شده است - up_voted_question: - other: رای موافق - down_voted_question: - other: سوال با رای منفی - up_voted_answer: - other: پاسخ موافق - down_voted_answer: - other: جواب مخالف - up_voted_comment: - other: نظر بدون رای - invited_you_to_answer: - other: برای جواب دادن دعوت شده اید - earned_badge: - other: You've earned the "{{.BadgeName}}" badge - email_tpl: - change_email: - title: - other: "آدرس ایمیل جدید خود را تایید کنید{{.SiteName}}" - body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} به سؤال شما پاسخ داد" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} شما را به پاسخ دعوت کرد" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} روی پست شما نظر داد" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_question: - title: - other: "[{{.SiteName}}] سؤال جدید: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] گذرواژه بازنشانی شد" - body: - other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - register: - title: - other: "[{{.SiteName}}] حساب کاربری جدید خود را تأیید کنید" - body: - other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - test: - title: - other: "[{{.SiteName}}] ایمیل آزمایشی" - body: - other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: - upvote: - other: رأی مثبت - upvoted: - other: رأی مثبت - downvote: - other: رأی منفی - downvoted: - other: رأی منفی - accept: - other: پذیرفتن - accepted: - other: پذیرفته شده - edit: - other: edit - review: - queued_post: - other: Queued post - flagged_post: - other: Flagged post - suggested_post_edit: - other: Suggested edits - reaction: - tooltip: - other: "{{ .Names }} and {{ .Count }} more..." - badge: - default_badges: - autobiographer: - name: - other: Autobiographer - desc: - other: Filled out profile information. - certified: - name: - other: Certified - desc: - other: Completed our new user tutorial. - editor: - name: - other: Editor - desc: - other: First post edit. - first_flag: - name: - other: First Flag - desc: - other: First flagged a post. - first_upvote: - name: - other: First Upvote - desc: - other: First up voted a post. - first_link: - name: - other: First Link - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: First Share - desc: - other: First shared a post. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Leave 5 comments. - new_user_of_the_month: - name: - other: New User of the Month - desc: - other: Outstanding contributions in their first month. - read_guidelines: - name: - other: Read Guidelines - desc: - other: Read the [community guidelines]. - reader: - name: - other: Reader - desc: - other: Read every answers in a topic with more than 10 answers. - welcome: - name: - other: Welcome - desc: - other: Received a up vote. - nice_share: - name: - other: Nice Share - desc: - other: Shared a post with 25 unique visitors. - good_share: - name: - other: Good Share - desc: - other: Shared a post with 300 unique visitors. - great_share: - name: - other: Great Share - desc: - other: Shared a post with 1000 unique visitors. - out_of_love: - name: - other: Out of Love - desc: - other: Used 50 up votes in a day. - higher_love: - name: - other: Higher Love - desc: - other: Used 50 up votes in a day 5 times. - crazy_in_love: - name: - other: Crazy in Love - desc: - other: Used 50 up votes in a day 20 times. - promoter: - name: - other: Promoter - desc: - other: Invited a user. - campaigner: - name: - other: Campaigner - desc: - other: Invited 3 basic users. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: Thank You - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Active member for a year, posted at least once. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: نحوه فرمت کردن - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: قبلی - next: بعدی - page_title: - question: سوال - questions: سوالات - tag: برچسب - tags: برچسب ها - tag_wiki: ویکی تگ - create_tag: ایجاد برچسب - edit_tag: ویرایش برچسب - ask_a_question: Create Question - edit_question: ویرایش سوال - edit_answer: ویرایش پاسخ - search: جستجو - posts_containing: پست های شامل - settings: تنظیمات - notifications: اعلانات - login: ورود - sign_up: ثبت نام - account_recovery: بازیابی حساب کاربری - account_activation: فعالسازی حساب - confirm_email: تایید ایمیل - account_suspended: حساب تعلیق شد - admin: ادمین - change_email: نگارش ایمیل - install: نصب Bepors - upgrade: بروزرسانی بپرس - maintenance: تعمیر و نگهداری وب سایت - users: کاربرها - oauth_callback: در حال پردازش - http_404: خطای 404 HTTP - http_50X: خطای 500 HTTP - http_403: خطای 403 HTTP - logout: خروج - posts: Posts - notifications: - title: اعلانات - inbox: پیغام‌های دریافتی - achievement: دستاوردها - new_alerts: هشدار جدید - all_read: علامتگذاری همه بعنوان خوانده شده - show_more: نمایش بیشتر - someone: کسی - inbox_type: - all: همه - posts: پست ها - invites: دعوت ها - votes: آراء - answer: Answer - question: Question - badge_award: Badge - suspended: - title: حساب شما معلق شده است - until_time: "حساب شما تا تاریخ {{ time }} به حالت تعلیق درآمده است." - forever: این کاربر برای همیشه به حالت تعلیق درآمده است. - end: شما یک دستورالعمل انجمن را رعایت نمی کنید. - contact_us: ارتباط با ما - editor: - blockquote: - text: مسابقه - bold: - text: قوی - chart: - text: نمودار - flow_chart: نمودار جریان - sequence_diagram: نمودار توالی - class_diagram: نمودار کلاس - state_diagram: نمودار حالت - entity_relationship_diagram: نمودار رابطه موجودیت - user_defined_diagram: نمودار تعریف شده توسط کاربر - gantt_chart: نمودار گانت - pie_chart: نمودار دابره‌ای - code: - text: نمونه کد - add_code: نمونه کد اضافه کنید - form: - fields: - code: - label: کد - msg: - empty: کد نمی تواند خالی باشد. - language: - label: زبان - placeholder: تشخیص خودکار - btn_cancel: لغو - btn_confirm: اضافه کردن - formula: - text: فرمول - options: - inline: فرمول در خط - block: بلاک کردن فرمول - heading: - text: سرفصل - options: - h1: سرفصل ۱ - h2: سرفصل ۲ - h3: سرفصل ۳ - h4: سرفصل ۴ - h5: سرفصل ۵ - h6: سرفصل ۶ - help: - text: راهنما - hr: - text: خط افقی - image: - text: عکس - add_image: افزودن عکس - tab_image: آپلود عکس - form_image: - fields: - file: - label: فایل عکس - btn: انتخاب عکس - msg: - empty: فایل نمی تواند خالی باشد. - only_image: فقط فایل های تصویری مجاز هستند. - max_size: File size cannot exceed {{size}} MB. - desc: - label: توضیحات - tab_url: لینک عکس - form_url: - fields: - url: - label: لینک عکس - msg: - empty: آدرس عکس نمی‌تواند خالی باشد. - name: - label: توضیحات - btn_cancel: لغو - btn_confirm: اضافه کردن - uploading: درحال ارسال - indent: - text: تورفتگی - outdent: - text: بیرون آمدگی - italic: - text: تاکید - link: - text: فراپیوند - add_link: اضافه کردن فراپیوند - form: - fields: - url: - label: آدرس - msg: - empty: آدرس نمی‌تواند خالی باشد. - name: - label: توضیح - btn_cancel: لغو - btn_confirm: افزودن - ordered_list: - text: فهرست عددی - unordered_list: - text: لیست گلوله‌ای - table: - text: جدول - heading: سرفصل - cell: تلفن همراه - file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: این پست را می بندم بدلیل... - btn_cancel: لغو - btn_submit: فرستادن - remark: - empty: نمی‌تواند خالی باشد. - msg: - empty: لطفا یک دلیل را انتخاب کنید. - report_modal: - flag_title: من پرچم گذاری می کنم تا این پست را به عنوان گزارش کنم... - close_title: این پست را می بندم بدلیل... - review_question_title: بازبینی سوال - review_answer_title: بازبینی جواب - review_comment_title: بازبینی نظر - btn_cancel: لغو - btn_submit: ثبت - remark: - empty: نمی‌تواند خالی باشد. - msg: - empty: لطفا یک دلیل را انتخاب کنید. - not_a_url: URL format is incorrect. - url_not_match: URL origin does not match the current website. - tag_modal: - title: ساخت تگ جدید - form: - fields: - display_name: - label: نام - msg: - empty: نام نمی تواند خالی باشد. - range: نام باید نهایتا ۳۵ حرف داشته باشد. - slug_name: - label: نامک آدس - desc: نامک آدرس باید نهایتا ۳۵ حرف داشته باشد. - msg: - empty: نامک آدرس نمی تواند خالی باشد. - range: نامک آدرس باید نهایتا ۳۵ حرف داشته باشد. - character: نامک آدرس شامل کلمات غیر مجاز می باشد. - desc: - label: توضیحات - revision: - label: تجدید نظر - edit_summary: - label: ویرایش خلاصه - placeholder: >- - تغییرات خود را به طور خلاصه توضیح دهید (املا صحیح، دستور زبان مناسب، قالب بندی بهبود یافته) - btn_cancel: لغو - btn_submit: ثبت - btn_post: پست کردن تگ جدید - tag_info: - created_at: ایجاد شده - edited_at: ویرایش شده - history: تاریخچه - synonyms: - title: مترادف ها - text: تگ های زیر مجدداً به آنها نگاشت می شوند - empty: مترادفی پیدا نشد. - btn_add: افزودن مترادف - btn_edit: ویرایش - btn_save: ذخیره - synonyms_text: تگ های زیر مجدداً به آنها نگاشت می شوند - delete: - title: این برچسب حذف شود - tip_with_posts: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - tip_with_synonyms: >- -

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        - tip: مطمئنید که میخواهید حذف شود? - close: بستن - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: ویرایش تگ‌ - default_reason: ویرایش تگ‌ - default_first_reason: برچسب اضافه کنید - btn_save_edits: ذخیره ویرایشها - btn_cancel: لغو - dates: - long_date: ماه ماه ماه روز - long_date_with_year: "ماه روز، سال" - long_date_with_time: "ماه روز، سال در ساعت:دقیقه" - now: حالا - x_seconds_ago: "{{count}} ثانیه پیش" - x_minutes_ago: "{{count}} دقیقه پیش" - x_hours_ago: "{{count}}ساعت پیش" - hour: ساعت - day: روز - hours: ساعات - days: روزها - month: month - months: months - year: year - reaction: - heart: heart - smile: smile - frown: frown - btn_label: add or remove reactions - undo_emoji: undo {{ emoji }} reaction - react_emoji: react with {{ emoji }} - unreact_emoji: unreact with {{ emoji }} - comment: - btn_add_comment: افزودن نظر - reply_to: پاسخ به - btn_reply: پاسخ - btn_edit: ویرایش - btn_delete: حذف - btn_flag: نشان - btn_save_edits: ذخیره ویرایشها - btn_cancel: لغو - show_more: "{{count}} نظر بیشتر" - tip_question: >- - از نظرات برای درخواست اطلاعات بیشتر یا پیشنهاد بهبود استفاده کنید. از پاسخ دادن به سوالات در نظرات خودداری کنید. - tip_answer: >- - از نظرات برای پاسخ دادن به سایر کاربران یا اطلاع دادن آنها از تغییرات استفاده کنید. اگر اطلاعات جدیدی اضافه می کنید، به جای نظر دادن، پست خود را ویرایش کنید. - tip_vote: چیز مفیدی به پست اضافه می کند - edit_answer: - title: ویرایش جواب - default_reason: ویرایش جواب - default_first_reason: پاسخ را اضافه کنید - form: - fields: - revision: - label: بازنگری - answer: - label: پاسخ - feedback: - characters: متن باید حداقل ۶ حرف داشته باشد. - edit_summary: - label: ویرایش خلاصه - placeholder: >- - بطور خلاصه تغییرات را توضیح دهید (اصلاح املایی، اصلاح دستورزبان،‌ بهبود فرمت دهی) - btn_save_edits: ذخیره ویرایش ها - btn_cancel: لغو - tags: - title: برچسب ها - sort_buttons: - popular: محبوب - name: نام - newest: جدیدترین - button_follow: دنبال کردن - button_following: دنبال می کنید - tag_label: سوالات - search_placeholder: فیلتر بر اساس اسم برچسب - no_desc: برچسب هیچ توضیحی ندارد. - more: بیشتر - wiki: Wiki - ask: - title: Create Question - edit_title: سوال را ویرایش کنید - default_reason: سوال را ویرایش کنید - default_first_reason: Create question - similar_questions: سؤال های مشابه - form: - fields: - revision: - label: تجدید نظر - title: - label: عنوان - placeholder: What's your topic? Be specific. - msg: - empty: عنوان نمی تواند خالی باشد. - range: عنوان میتواند تا ۳۰ حرف باشد - body: - label: بدنه - msg: - empty: بدنه نمی تواند خالی باشد. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: برچسب ها - msg: - empty: برچسب ها نمی تواند خالی باشد. - answer: - label: پاسخ - msg: - empty: جواب نمی تواند خالی باشد. - edit_summary: - label: ویرایش خلاصه - placeholder: >- - بطور خلاصه تغییرات را توضیح دهید (اصلاح املایی، اصلاح دستورزبان،‌ بهبود فرمت دهی) - btn_post_question: سوال خود را پست کنید - btn_save_edits: ذخیره ویرایش ها - answer_question: جواب دادن به سوال خودتان - post_question&answer: سوال خود را پست و جواب دهید - tag_selector: - add_btn: اضافه کردن برچسب - create_btn: ایجاد یک برچسب جدید - search_tag: جست‌وجوی برچسب‌ - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: هیچ تگی مطابقت ندارد - tag_required_text: تگ نیاز هست (حداقل یک مورد) - header: - nav: - question: سوالات - tag: تگ‌ها - user: کاربران - badges: Badges - profile: پروفایل - setting: تنظیمات - logout: خروج - admin: ادمین - review: بازبینی - bookmark: نشانک ها - moderation: مدیریت - search: - placeholder: جستجو - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: تغییر - loading: درحال بارگذاری... - pic_auth_code: - title: کپچا - placeholder: متن بالا را تاپ کنید - msg: - empty: کپچا نمی تواند خالی باشد. - inactive: - first: >- - شما تقریباً آماده شده اید! ما یک ایمیل فعال سازی به {{mail}} ارسال کردیم. لطفا دستورالعمل های ایمیل را برای فعال کردن حساب خود دنبال کنید. - info: "اگر ایمیل ارسالی را دریافت نکردید، قسمت spam خود را چک کنید." - another: >- - ایمیل فعال‌سازی دیگری را به آدرس {{mail}} برای شما ارسال کردیم. ممکن است چند دقیقه طول بکشد تا دستتان برسد. پوشه هرزنامه خود را حتما چک کنید. - btn_name: ارسال مجدد کد فعالسازی - change_btn_name: تغییر ایمیل - msg: - empty: نمی‌تواند خالی باشد. - resend_email: - url_label: آیا مطمئن هستید که می خواهید ایمیل فعال سازی را دوباره ارسال کنید؟ - url_text: همچنین می توانید لینک فعال سازی بالا را در اختیار کاربر قرار دهید. - login: - login_to_continue: برای ادامه وارد حساب کاربری شوید - info_sign: حساب کاربری ندارید؟ ثبت نام<1> - info_login: از قبل حساب کاربری دارید؟ <1>وارد شوید - agreements: با ثبت نام، با <1>خط مشی رازداری و <3>شرایط خدمات موافقت می کنید. - forgot_pass: رمزعبور را فراموش کردید? - name: - label: نام - msg: - empty: نام نمی‌تواند خالی باشد. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: ایمیل - msg: - empty: ایمیل نمی تواند خالی باشد. - password: - label: رمز عبور - msg: - empty: رمز عبور نمی تواند خالی باشد. - different: پسوردهای وارد شده در هر دو طرف متناقض هستند - account_forgot: - page_title: رمزعبور را فراموش کردید - btn_name: ارسال ایمیل بازیابی - send_success: >- - اگر یک حساب با {{mail}} مطابقت داشته باشد، باید به زودی ایمیلی حاوی دستورالعمل‌هایی درباره نحوه بازنشانی رمز عبور خود دریافت کنید. - email: - label: ایمیل - msg: - empty: ایمیل نمی تواند خالی باشد. - change_email: - btn_cancel: لغو - btn_update: نشانی ایمیل را به روز کنید - send_success: >- - اگر یک حساب با {{mail}} مطابقت داشته باشد، باید به زودی ایمیلی حاوی دستورالعمل‌هایی درباره نحوه بازنشانی رمز عبور خود دریافت کنید. - email: - label: ایمیل جدید - msg: - empty: ایمیل نمی تواند خالی باشد. - oauth: - connect: ارتباط با {{ auth_name }} - remove: حذف {{ auth_name }} - oauth_bind_email: - subtitle: یک ایمیل بازیابی به حساب خود اضافه کنید. - btn_update: نشانی ایمیل را به روز کنید - email: - label: ایمیل - msg: - empty: ایمیل نمی تواند خالی باشد. - modal_title: ایمیل تکراری. - modal_content: این ایمیل قبلا ثبت نام کرده است. آیا مطمئن هستید که می خواهید به حساب ثبت نام کرده متصل شوید? - modal_cancel: تغییر ایمیل - modal_confirm: به حساب کاربری ثبت نام کرده متصل شوید - password_reset: - page_title: بازیابی کلمه عبور - btn_name: رمز عبورم را بازنشانی کن - reset_success: >- - شما با موفقیت رمز عبور خود را تغییر دادید، به صفحه ورود هدایت می شوید. - link_invalid: >- - متاسفم،‌ لینک بازنشانی رمز عبور دیگر اعتبار ندارد. شاید رمز عبور شما قبلا تغییر کرده است? - to_login: ادامه بدهید تا به صفحه ورود برسید - password: - label: رمز عبور - msg: - empty: رمز عبور نمی تواند خالی باشد. - length: تعداد حروف باید بین ۸ تا ۳۲ باشد - different: پسوردهای وارد شده در هر دو طرف متناقض هستند - password_confirm: - label: تأیید رمز عبور جديد - settings: - page_title: تنظیمات - goto_modify: برای تغییر بروید - nav: - profile: پروفایل - notification: اعلانات - account: حساب کاربری - interface: رابط کاربری - profile: - heading: پروفایل - btn_name: ذخیره - display_name: - label: نام - msg: نام نمی تواند خالی باشد. - msg_range: Display name must be 2-30 characters in length. - username: - label: نام‌کاربری - caption: دیگران میتوانند به شما به بصورت "@username" اشاره کنند. - msg: نام کاربری نمی تواند خالی باشد. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: عکس پروفایل - gravatar: Gravatar - gravatar_text: می توانید تصویر را تغییر دهید - custom: سفارشی - custom_text: شما میتوانید عکس خود را بازگذاری کنید. - default: سیستم - msg: لطفا یک آواتار آپلود کنید - bio: - label: درباره من - website: - label: وب سایت - placeholder: "https://example.com" - msg: فرمت نادرست وب سایت - location: - label: موقعیت - placeholder: "شهر، کشور" - notification: - heading: اعلان های ایمیلی - turn_on: روشن کردن - inbox: - label: اعلانات ایمیل - description: پاسخ به سوالات خود،‌ نظرات،‌ دعوت ها،‌و بیشتر. - all_new_question: - label: تمامی سوالات جدید - description: درمورد تمامی سوالات جدید با خبر شوید. تا ۵۰ سوال در هفته. - all_new_question_for_following_tags: - label: تمامی سوالات جدید برای این تگ ها - description: درمورد تمامی سوالات جدید در مورد این تگ ها باخبر شوید. - account: - heading: حساب کاربری - change_email_btn: تغییر ایمیل - change_pass_btn: تغییر رمز عبور - change_email_info: >- - ما یک ایمیل به آن آدرس ارسال کردیم. لطفا مراحل تایید را طی کنید. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - pass: - label: رمز عبور فعلی - msg: رمز عبور نمی تواند خالی باشد. - password_title: رمز عبور - current_pass: - label: رمز عبور فعلی - msg: - empty: رمز عبور نمی تواند خالی باشد. - length: تعداد حروف باید بین ۸ تا ۳۲ باشد. - different: دو رمز عبور وارد شده همخوانی ندارند. - new_pass: - label: رمز عبور جدید - pass_confirm: - label: تأیید رمز عبور جديد - interface: - heading: رابط کاربری - lang: - label: زبان رابط کاربری - text: زبان رابط کاربری. زمانی تغییر می کند که صفحه را دوباره بارگذاری کنید. - my_logins: - title: ورود های من - label: با استفاده از این حساب ها وارد این سایت شوید یا ثبت نام کنید. - modal_title: حذف ورود - modal_content: آیا مطمئن هستید که می خواهید این ورود را از حساب خود حذف کنید؟ - modal_confirm_btn: حذف - remove_success: با موفقیت حذف شد - toast: - update: بروز رسانی موفق بود - update_password: رمز عبور با موفقیت تغییر کرد. - flag_success: ممنون بابت اطلاع دادن. - forbidden_operate_self: عملیات غیر مجاز - review: بازبینی شما پس از بررسی نشان داده خواهد شد. - sent_success: با موفقيت ارسال شد - related_question: - title: Related - answers: جواب ها - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: مردم پرسیدند - desc: افرادی را دعوت کنید که فکر می کنید ممکن است پاسخ را بدانند. - invite: دعوت به پاسخ - add: افزودن افراد - search: جستجوی افراد - question_detail: - action: عملیات - created: Created - Asked: پرسیده شده - asked: پرسیده شده - update: تغییر یافته - Edited: Edited - edit: ویرایش شده - commented: commented - Views: مشاهده شده - Follow: دنبال کردن - Following: دنبال می کنید - follow_tip: برای دریافت اعلان ها این سوال را دنبال کنید - answered: جواب داده - closed_in: بسته شده د - show_exist: نمایش سوال موجود. - useful: مفید - question_useful: مفید و واضح است - question_un_useful: نامشخص یا مفید نیست - question_bookmark: این سوال را نشانه گذاری کنید - answer_useful: مفید است - answer_un_useful: مفید نیست - answers: - title: پاسخ ها - score: امتیاز - newest: جدیدترین - oldest: Oldest - btn_accept: پذیرفتن - btn_accepted: پذیرفته شده - write_answer: - title: پاسخ شما - edit_answer: پاسخ فعلی من را ویرایش کنید - btn_name: پاسخ خود را ارسال کنید - add_another_answer: پاسخ دیگری اضافه کنید - confirm_title: به پاسخ دادن ادامه دهید - continue: ادامه دهید - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: جواب نمی تواند خالی باشد. - characters: متن باید حداقل ۶ حرف داشته باشد. - tips: - header_1: از جواب شما متشکریم - li1_1: لطفا مطمئن شوید که جواب دهید سوال را. جزئیات بیشتری ارائه دهید و تحقیقات خود را به اشتراک بگذارید. - li1_2: از هر اظهاراتی که می کنید با ارجاعات یا تجربه شخصی پشتیبان بگیرید. - header_2: اما دوری کنید ... - li2_1: درخواست کمک، به دنبال شفاف سازی، یا پاسخ به پاسخ های دیگر. - reopen: - confirm_btn: بازگشایی مجدد - title: بازگشایی مجدد این پست - content: آیا مطمئن هستید که می‌خواهید بازگشایی مجدد انجام دهید? - list: - confirm_btn: List - title: List this post - content: Are you sure you want to list? - unlist: - confirm_btn: Unlist - title: Unlist this post - content: Are you sure you want to unlist? - pin: - title: پست را پین کن - content: آیا مطمئن هستید میخواهید پست بصورت عمومی پین شود؟ پست در بالای تمامی پست ها نشان داده خواهد شد. - confirm_btn: پین کردن - delete: - title: حذف این پست - question: >- - ما حذف سوالات با جواب را پیشنهاد نمی کنیم، زیرا انجام این کار خوانندگان آینده را از این دانش محروم می کند.

        حذف مکرر سؤالات پاسخ داده شده می تواند منجر به مسدود شدن حساب شما از سؤال شود. آیا مطمئن هستید که می خواهید حذف کنید? - answer_accepted: >- - ما حذف جواب تایید شده را پیشنهاد نمی کنیم، زیرا انجام این کار خوانندگان آینده را از این دانش محروم می کند.

        حذف مکرر سؤالات پاسخ داده شده می تواند منجر به مسدود شدن حساب شما از سؤال شود. آیا مطمئن هستید که می خواهید حذف کنید? - other: مطمئنید که میخواهید حذف شود? - tip_answer_deleted: جواب شما حذف شده است - undelete_title: حذف این پست - undelete_desc: آیا مطمئن به بازگردانی هستید؟ - btns: - confirm: تایید - cancel: لغو - edit: ویرایش - save: ذخیره - delete: حذف - undelete: بازگردانی - list: List - unlist: Unlist - unlisted: Unlisted - login: ورود - signup: عضويت - logout: خروج - verify: تایید - create: Create - approve: تایید - reject: رد کردن - skip: بعدی - discard_draft: دور انداختن پیش‌نویس‌ - pinned: پین شد - all: همه - question: سوال - answer: پاسخ - comment: نظر - refresh: بارگذاری مجدد - resend: ارسال مجدد - deactivate: غیرفعال کردن - active: فعال - suspend: تعلیق - unsuspend: لغو تعلیق - close: بستن - reopen: بازگشایی - ok: تأیید - light: روشن - dark: تیره - system_setting: تنظیمات سامانه - default: Default - reset: Reset - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignore - submit: Submit - normal: Normal - closed: Closed - deleted: Deleted - deleted_permanently: Deleted permanently - pending: Pending - more: More - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: نتایج جستجو - keywords: کلیدواژه ها - options: گزینه‌ها - follow: دنبال کردن - following: دنبال میکنید - counts: "{{count}} نتیجه" - counts_loading: "... Results" - more: بیشتر - sort_btns: - relevance: مرتبط - newest: جدیدترین - active: فعال - score: امتیاز - more: بیشتر - tips: - title: گزینه های پیشرفته جستجو - tag: "<1>[tag] search with a tag" - user: "<1>user:username جستجو براساس نویسنده" - answer: "<1>answers:0 سوال بی جواب" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: چیزی پیدا نکردیم
        کلمات کلیدی متفاوت یا کمتر خاص را امتحان کنید. - share: - name: اشتراک‌گذاری - copy: کپی کردن لینک - via: اشتراک گذاری پست با... - copied: کپی انجام شد - facebook: اشتراک گذاری در فیس بوک - twitter: Share to X - cannot_vote_for_self: شما نمی توانید به پست خودتان رای دهید. - modal_confirm: - title: خطا... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: اکانت جدید شما تایید شده است، به صفحه خانه منتقل خواهید شد. - link: ادامه بدهید تا به صفحه خانه برسید - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: ایمیل شما به‌روز شده است. - confirm_new_email_invalid: >- - متاسفیم، لینک تایید دیگر مجاز نیست. شاید حساب شما از قبل فعال شده است? - unsubscribe: - page_title: قطع عضویت - success_title: لغو عضویت موفق (Automatic Translation) - success_desc: شما با موفقیت از این لیست مشترک حذف شده اید و دیگر ایمیلی از ما دریافت نخواهید کرد. - link: تغییر تنظیمات - question: - following_tags: تگهای مورد نظر - edit: ویرایش - save: ذخیره - follow_tag_tip: برچسب ها را دنبال کنید تا لیست سوالات خود را تنظیم کنید. - hot_questions: سوالات داغ - all_questions: تمام سوالات - x_questions: "{{ count }} سوال" - x_answers: "{{ count }} جواب" - x_posts: "{{ count }} Posts" - questions: سوالات - answers: پاسخ ها - newest: جدیدترین - active: فعال - hot: Hot - frequent: Frequent - recommend: Recommend - score: امتیاز - unanswered: بدون پاسخ - modified: تغییر یافته - answered: جواب داده - asked: پرسیده شده - closed: بسته - follow_a_tag: یک برچسب را دنبال کنید - more: بیشتر - personal: - overview: خلاصه - answers: پاسخ ها - answer: پاسخ - questions: سوالات - question: سوال - bookmarks: نشان ها - reputation: محبوبیت - comments: نظرات - votes: آراء - badges: Badges - newest: جدیدترین - score: امتیاز - edit_profile: ویرایش پروفایل - visited_x_days: "Visited {{ count }} days" - viewed: مشاهده شده - joined: عضو شد - comma: "," - last_login: مشاهده شده - about_me: درباره من - about_me_empty: "// Hello, World !" - top_answers: پاسخ های برتر - top_questions: سوالات برتر - stats: آمار - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - content_empty: No posts found. - accepted: پذیرفته شده - answered: جواب داده - asked: پرسیده شده - downvoted: رأی منفی - mod_short: MOD - mod_long: Moderators - x_reputation: محبوبیت - x_votes: آرای دریافت شد - x_answers: جواب ها - x_questions: سوالات - recent_badges: Recent Badges - install: - title: Installation - next: بعدی - done: انجام شده - config_yaml_error: نمیتوان فایل config.yaml را ایجاد کرد. - lang: - label: لطفا زبان خود را انتخاب کنید - db_type: - label: موتور پایگاه‌داده - db_username: - label: نام‌کاربری - placeholder: روت - msg: نام کاربری نمی تواند خالی باشد. - db_password: - label: رمز عبور - placeholder: روت - msg: رمز عبور نمی تواند خالی باشد. - db_host: - label: میزبان پایگاه داده - placeholder: "db:3306" - msg: پایگاه داده میزبان نمیتواند خالی باشد. - db_name: - label: نام پایگاه‌داده - placeholder: پاسخ - msg: نام پایگاه داده میزبان نمیتواند خالی باشد. - db_file: - label: فایل پایگاه داده - placeholder: /data/answer.db - msg: فایل پایگاه داده نمیتواند خالی باشد. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Config.yaml را بسازید - label: فایل config.yaml ساخته شد. - desc: >- - شما بصورت دستی میتوانید فایل <1>config.yaml را در پوشه <1>/var/wwww/xxx/ ایجاد و متن را در داخل آن جایگذاری کنید. - info: بعد از اتمام،‌ بر روی "بعدی" کلیک کنید. - site_information: اطلاعات سایت - admin_account: حساب ادمین - site_name: - label: نام سایت - msg: نام سایت نمی تواند خالی باشد. - msg_max_length: Site name must be at maximum 30 characters in length. - site_url: - label: آدرس سایت - text: آدرس سایت شما - msg: - empty: آدرس سایت نمی تواند خالی باشد. - incorrect: فرمت آدرس سایت نادرست است. - max_length: Site URL must be at maximum 512 characters in length. - contact_email: - label: ایمیل ارتباطی - text: آدرس ایمیل مخاطب کلیدی پاسخگو برای این سایت. - msg: - empty: ایمیل مخاطب نمی تواند خالی باشد. - incorrect: فرمت ایمیل مخاطب نادرست است. - login_required: - label: خصوصی - switch: ورود الزامی است - text: تنها افرادی که وارد سایت شده اند میتوانند به این انجمن دسترسی پیدا کنند. - admin_name: - label: نام - msg: نام نمی‌تواند خالی باشد. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: رمز عبور - text: >- - شما برای ورود نیازمند این پسورد خواهید بود. لطفا در محل امنی ذخیره کنید. - msg: رمز عبور نمی تواند خالی باشد. - msg_min_length: Password must be at least 8 characters in length. - msg_max_length: Password must be at maximum 32 characters in length. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: ایمیل - text: شما به این ایمیل برای ورود نیاز خواهید داشت. - msg: - empty: ایمیل نمی تواند خالی باشد. - incorrect: فرمت ایمیل نادرست است. - ready_title: Your site is ready - ready_desc: >- - اگر به تغییر بیشتر تنظیمات نیاز دارید،‌به <1> قسمت ادمین مراجعه کنید،‌میتوانید این گزینه را در منو سایت مشاهده کنید. - good_luck: "خوش بگذره و موفق باشید!" - warn_title: هشدار - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: قبلاً نصب شده است - installed_desc: >- - شما پیش از‌این وردپرس را برپا نموده‌اید. برای راه‌اندازی دوباره ابتدا جدول‌های کهنه در پایگاه‌داده را پاک نمایید. - db_failed: اتصال به دیتابیس موفقیت آمیز نبود - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: مشاهده - votes: آراء - answers: جواب ها - accepted: پذیرفته شده - page_error: - http_error: HTTP Error {{ code }} - desc_403: شما مجوز دسترسی به این صفحه را ندارید. - desc_404: متاسفانه این صفحه وجود ندارد. - desc_50X: The server encountered an error and could not complete your request. - back_home: بازگشت به صفحه اصلی - page_maintenance: - desc: "ما درحال تعمیر هستیم، به زودی برمی گردیم." - nav_menus: - dashboard: داشبرد - contents: محتوا - questions: سوالات - answers: پاسخ ها - users: کاربران - badges: Badges - flags: پرچم - settings: تنظیمات - general: عمومی - interface: رابط کاربری - smtp: SMTP - branding: نام تجاری - legal: قانونی - write: نوشتن - terms: Terms - tos: قوانین - privacy: حریم خصوصی - seo: سئو - customize: شخصی‌سازی - themes: پوسته ها - login: ورود - privileges: مجوزها - plugins: افزونه‌ها - installed_plugins: پلاگین های نصب شده - apperance: Appearance - website_welcome: به {{site_name}} خوش آمدید - user_center: - login: ورود - qrcode_login_tip: لطفاً از {{ agentName }} برای اسکن کد QR و ورود به سیستم استفاده کنید. - login_failed_email_tip: ورود ناموفق بود، لطفاً قبل از امتحان مجدد به این برنامه اجازه دهید به اطلاعات ایمیل شما دسترسی داشته باشد. - badges: - modal: - title: Congratulations - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - admin: - admin_header: - title: ادمین - dashboard: - title: داشبرد - welcome: Welcome to Admin! - site_statistics: Site statistics - questions: "سوالات:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "جواب ها:" - comments: "نظرات:" - votes: "آرا:" - users: "Users:" - flags: "علامت‌ها:" - reviews: "Reviews:" - site_health: Site health - version: "نسخه:" - https: "HTTPS:" - upload_folder: "Upload folder:" - run_mode: "Running mode:" - private: Private - public: در دسترس عموم - smtp: "SMTP:" - timezone: "منطقه زمانی:" - system_info: اطلاعات سامانه - go_version: "نسخه Go:" - database: "پایگاه داده:" - database_size: "اندازه پایگاه داده :" - storage_used: "فضای استفاده شده:" - uptime: "پایداری:" - links: Links - plugins: افزونه‌ها - github: GitHub - blog: بلاگ - contact: تماس - forum: Forum - documents: اسناد - feedback: ﺑﺎﺯﺧﻮﺭﺩ - support: پشتیبانی - review: بازبینی - config: کانفینگ - update_to: آپدیت کردن به - latest: آخرین - check_failed: بررسی ناموفق بود - "yes": "بله" - "no": "نه" - not_allowed: غیر مجاز - allowed: مجاز - enabled: فعال - disabled: غیرفعال - writable: قابل نوشتن - not_writable: غیرقابل کُپی - flags: - title: علامت‌ها - pending: در حالت انتظار - completed: تکمیل شده - flagged: علامت گذاری شده - flagged_type: پرچم گذاری شده {{ type }} - created: ایجاد شده - action: عمل - review: بازبینی - user_role_modal: - title: تغییر نقش کاربر به ... - btn_cancel: لغو - btn_submit: ثبت - new_password_modal: - title: تعیین رمزعبور جدید - form: - fields: - password: - label: رمز عبور - text: کاربر از سیستم خارج می شود و باید دوباره وارد سیستم شود. - msg: رمز عبور باید 8 تا 32 کاراکتر باشد. - btn_cancel: لغو - btn_submit: ثبت - edit_profile_modal: - title: Edit profile - form: - fields: - display_name: - label: Display name - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Invalid Email Address. - edit_success: Edited successfully - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: افزودن کاربر جدید - form: - fields: - users: - label: اضافه کردن انبوه کاربر - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: '"نام، ایمیل، رمز عبور" را با کاما جدا کنید. یک کاربر در هر خط.' - msg: "لطفا ایمیل کاربر را در هر خط یکی وارد کنید." - display_name: - label: نمایش نام - msg: Display name must be 2-30 characters in length. - email: - label: ایمیل - msg: ایمیل معتبر نمی‌باشد - password: - label: رمز عبور - msg: رمز عبور باید 8 تا 32 کاراکتر باشد. - btn_cancel: لغو - btn_submit: ثبت - users: - title: کاربرها - name: نام - email: ایمیل - reputation: محبوبیت - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: وضعیت - role: نقش - action: عمل - change: تغییر - all: همه - staff: کارکنان - more: بیشتر - inactive: غیرفعال - suspended: تعلیق شده - deleted: حذف شده - normal: عادي - Moderator: مدير - Admin: ادمین - User: کاربر - filter: - placeholder: "فیلتر براساس، user:id" - set_new_password: تعیین رمزعبور جدید - edit_profile: Edit profile - change_status: تغییر وضعیت - change_role: تغییر نقش - show_logs: نمایش ورود ها - add_user: افزودن کاربر - deactivate_user: - title: غیر فعال کردن کاربر - content: یک کاربر غیرفعال باید ایمیل خود را دوباره تایید کند. - delete_user: - title: این کاربر حذف شود - content: آیا مطمئن هستید که میخواهید این کابر را حذف نمایید؟ این اقدام دائمی است! - remove: محتوای آنها را حذف کنید - label: تمام سوالات، پاسخ ها، نظرات و غیره را حذف کن. - text: اگر می‌خواهید فقط حساب کاربر را حذف کنید، این را بررسی نکنید. - suspend_user: - title: تعلیق این کاربر - content: کاربر تعلیق شده نمی‌تواند وارد شود. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: سوالات - unlisted: Unlisted - post: پست - votes: آراء - answers: پاسخ ها - created: ایجاد شده - status: وضعیت - action: عمل - change: تغییر - pending: Pending - filter: - placeholder: "فیلتر براساس، user:id" - answers: - page_title: پاسخ ها - post: پست - votes: آراء - created: ایجاد شده - status: وضعیت - action: اقدام - change: تغییر - filter: - placeholder: "فیلتر براساس، user:id" - general: - page_title: عمومی - name: - label: نام سایت - msg: نام سایت نمی تواند خالی باشد. - text: "نام این سایت همانطور که در تگ عنوان استفاده شده است." - site_url: - label: آدرس سایت - msg: آدرس سایت نمی تواند خالی باشد. - validate: لطفا یک url معتبر وارد کنید. - text: آدرس سایت شما. - short_desc: - label: نام این سایت مورد استفاده قرار گرفته است - msg: توضیحات کوتاه سایت نمی تواند خالی باشد. - text: "شرح کوتاه، همانطور که در تگ عنوان در صفحه اصلی استفاده شده است." - desc: - label: توضیحات سایت - msg: توضیحات کوتاه سایت نمی تواند خالی باشد. - text: "همانطور که در تگ توضیحات متا استفاده شده است، این سایت را در یک جمله توصیف کنید." - contact_email: - label: ایمیل ارتباطی - msg: ایمیل مخاطب نمی تواند خالی باشد. - validate: ایمیل تماس معتبر نیست. - text: آدرس ایمیل مخاطب کلیدی مسئول این سایت. - check_update: - label: Software updates - text: Automatically check for updates - interface: - page_title: رابط کاربری - language: - label: زبان رابط کاربری - msg: زبان رابط نمی تواند خالی باشد. - text: زبان رابط کاربری. زمانی تغییر می کند که صفحه را دوباره بارگذاری کنید. - time_zone: - label: منطقه زمانی - msg: منطقه زمانی نمی تواند خالی باشد. - text: شهری را در همان منطقه زمانی خود انتخاب کنید. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: از ایمیل - msg: ایمیل نباید خالی باشد. - text: آدرس ایمیلی که ایمیل ها از آن ارسال می شوند. - from_name: - label: نام فرستنده - msg: ایمیل نباید خالی باشد. - text: آدرس ایمیلی که ایمیل ها از آن ارسال می شوند. - smtp_host: - label: ميزبان SMTP - msg: میزبان SMTP نمی تواند خالی باشد. - text: سرور ایمیل شما. - encryption: - label: رمزگذاری - msg: کلید رمزگذاری نمی تواند خالی باشد. - text: برای اکثر سرورها SSL گزینه پیشنهادی است. - ssl: SSL - tls: TLS - none: هیچ‌کدام - smtp_port: - label: پورت SMTP - msg: پورت SMTP باید شماره 1 ~ 65535 باشد. - text: پورت سرور ایمیل شما. - smtp_username: - label: نام کاربری SMTP - msg: نام کاربری SMTP نمی تواند خالی باشد. - smtp_password: - label: رمزعبور SMTP - msg: رمز عبور مدیر نمی‌تواند خالی باشد. - test_email_recipient: - label: گیرندگان ایمیل را آزمایش کنید - text: آدرس ایمیلی را ارائه دهید که ارسال های آزمایشی را دریافت می کند. - msg: گیرندگان ایمیل آزمایشی نامعتبر است - smtp_authentication: - label: فعال کردن احراز هویت - title: تأیید هویت SMTP - msg: احراز هویت SMTP نمی تواند خالی باشد. - "yes": "بله" - "no": "نه" - branding: - page_title: نام تجاری - logo: - label: لوگو - msg: کد نمی تواند خالی باشد. - text: تصویر لوگو در سمت چپ بالای سایت شما. از یک تصویر مستطیلی عریض با ارتفاع 56 و نسبت تصویر بیشتر از 3:1 استفاده کنید. اگر خالی بماند، متن عنوان سایت نشان داده می شود. - mobile_logo: - label: لوگوی موبایل - text: لوگوی مورد استفاده در نسخه موبایلی سایت شما. از یک تصویر مستطیلی عریض با ارتفاع 56 استفاده کنید. اگر خالی بماند، تصویر از تنظیمات "لوگو" استفاده خواهد شد. - square_icon: - label: نماد مربعی - msg: نماد مربعی نمی تواند خالی باشد. - text: تصویر به عنوان پایه نمادهای متادیتا استفاده می شود. در حالت ایده آل باید بزرگتر از 512x512 باشد. - favicon: - label: نمادک - text: فاویکون برای سایت شما. برای اینکه روی CDN به درستی کار کند باید یک png باشد. به 32x32 تغییر اندازه خواهد شد. اگر خالی بماند، از "نماد مربع" استفاده می شود. - legal: - page_title: قانونی - terms_of_service: - label: شرایط خدمات - text: "می توانید محتوای شرایط خدمات را در اینجا اضافه کنید. اگر قبلاً سندی دارید که در جای دیگری میزبانی شده است، URL کامل را در اینجا ارائه دهید." - privacy_policy: - label: حریم خصوصی - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: نوشتن - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Each user can only write one answer for each question - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Recommend tags - text: "Recommend tags will show in the dropdown list by default." - msg: - contain_reserved: "recommended tags cannot contain reserved tags" - required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved tags - text: "Reserved tags can only be used by moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: بهینه‌سازی عملیات موتورهای جستجو - permalink: - label: پیوند ثابت - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - color_scheme: - label: Color scheme - navbar_style: - label: Navbar background style - primary_color: - label: Primary color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: > - - head: - label: Head - text: > - - header: - label: Header - text: > - - footer: - label: Footer - text: This will insert before </body>. - sidebar: - label: Sidebar - text: This will insert in sidebar. - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - email_registration: - title: Email registration - label: Allow email registration - text: Turn off to prevent anyone creating new account through email. - allowed_email_domains: - title: دامنه های مجاز ایمیل - text: دامنه های ایمیلی که کاربران باید با آنها حساب ثبت کنند. یک دامنه در هر خط. وقتی خالی است نادیده گرفته می شود. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - password_login: - title: Password login - label: Allow email and password login - text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." - installed_plugins: - title: Installed Plugins - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. - filter: - all: All - active: Active - inactive: Inactive - outdated: Outdated - plugins: - label: Plugins - text: Select an existing plugin. - name: Name - version: Version - status: وضعیت - action: اقدام - deactivate: Deactivate - activate: فعال سازی - settings: تنظیمات - settings_users: - title: کاربران - avatar: - label: آواتار پیش فرض - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar Base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - profile_editable: - title: Profile editable - allow_update_display_name: - label: Allow users to change their display name - allow_update_username: - label: Allow users to change their username - allow_update_avatar: - label: Allow users to change their profile image - allow_update_bio: - label: Allow users to change their about me - allow_update_website: - label: Allow users to change their website - allow_update_location: - label: Allow users to change their location - privilege: - title: Privileges - level: - label: Reputation required level - text: Choose the reputation required for the privileges - msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 - badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate - filter: - placeholder: Filter by name, badge:id - group: Group - inactive: Inactive - name: Name - show_logs: Show logs - status: Status - title: Badges - form: - optional: (optional) - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - select: Select - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - approve_revision_tip: Do you approve this revision? - approve_flag_tip: Do you approve this flag? - approve_post_tip: Do you approve this post? - approve_user_tip: Do you approve this user? - suggest_edits: Suggested edits - flag_post: Flag post - flag_user: Flag user - queued_post: Queued post - queued_user: Queued user - filter_label: Type - reputation: reputation - flag_post_type: Flagged this post as {{ type }}. - flag_user_type: Flagged this user as {{ type }}. - edit_post: Edit post - list_post: List post - unlist_post: پست فهرست نشده - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - pin: pinned - unpin: unpinned - show: listed - hide: unlisted - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores this week - users_with_the_most_vote: Users who voted the most this week - staffs: Our community staff - reputation: reputation - votes: votes - prompt: - leave_page: Are you sure you want to leave the page? - changes_not_save: Your changes may not be saved. - draft: - discard_confirm: Are you sure you want to discard your draft? - messages: - post_deleted: This post has been deleted. - post_cancel_deleted: This post has been undeleted. - post_pin: This post has been pinned. - post_unpin: This post has been unpinned. - post_hide_list: This post has been hidden from list. - post_show_list: This post has been shown to list. - post_reopen: This post has been reopened. - post_list: This post has been listed. - post_unlist: This post has been unlisted. - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/fi_FI.yaml b/data/i18n/fi_FI.yaml deleted file mode 100644 index 25c086f11..000000000 --- a/data/i18n/fi_FI.yaml +++ /dev/null @@ -1,1384 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: Success. - unknown: - other: Unknown error. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - email: - other: Email - password: - other: Password - email_or_password_wrong_error: - other: Email and password do not match. - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - question: - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - rank: - fail_to_meet_the_condition: - other: Rank fail to meet the condition. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend Tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - smtp: - config_from_name_cannot_be_email: - other: The From Name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to Revision. - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - report: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude: - name: - other: rude or abusive - desc: - other: A reasonable person would find this content inappropriate for respectful discourse. - duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - not_answer: - name: - other: not an answer - desc: - other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. - not_need: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - other: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comments - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to {{site_name}} - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to {{site_name}} - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/fr_FR.yaml b/data/i18n/fr_FR.yaml deleted file mode 100644 index a4fdcb2ed..000000000 --- a/data/i18n/fr_FR.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Succès. - unknown: - other: Erreur inconnue. - request_format_error: - other: Format de fichier incorrect. - unauthorized_error: - other: Non autorisé. - database_error: - other: Erreur du serveur de données. - forbidden_error: - other: Interdit. - duplicate_request_error: - other: Soumission en double. - action: - report: - other: Signaler - edit: - other: Éditer - delete: - other: Supprimer - close: - other: Fermer - reopen: - other: Rouvrir - forbidden_error: - other: Interdit. - pin: - other: Épingler - hide: - other: Délister - unpin: - other: Désépingler - show: - other: Liste - invite_someone_to_answer: - other: Modifier - undelete: - other: Annuler la suppression - merge: - other: Fusionner - role: - name: - user: - other: Utilisateur - admin: - other: Administrateur - moderator: - other: Modérateur - description: - user: - other: Par défaut, sans accès spécial. - admin: - other: Possède tous les droits pour accéder au site. - moderator: - other: Possède les accès à tous les messages sauf aux paramètres d'administration. - privilege: - level_1: - description: - other: Niveau 1 (moins de réputation requise pour une équipe privée, un groupe) - level_2: - description: - other: Niveau 2 (faible réputation requise pour la communauté des startups) - level_3: - description: - other: Niveau 3 (haute réputation requise pour une communauté mature) - level_custom: - description: - other: Niveau personnalisé - rank_question_add_label: - other: Poser une question - rank_answer_add_label: - other: Écrire une réponse - rank_comment_add_label: - other: Ajouter un commentaire - rank_report_add_label: - other: Signaler - rank_comment_vote_up_label: - other: Voter favorablement le commentaire - rank_link_url_limit_label: - other: Poster plus de 2 liens à la fois - rank_question_vote_up_label: - other: Voter favorablement la question - rank_answer_vote_up_label: - other: Voter favorablement la réponse - rank_question_vote_down_label: - other: Voter contre la question - rank_answer_vote_down_label: - other: Voter contre la réponse - rank_invite_someone_to_answer_label: - other: Inviter quelqu'un à répondre - rank_tag_add_label: - other: Créer une nouvelle étiquette - rank_tag_edit_label: - other: Modifier la description de la balise (à réviser) - rank_question_edit_label: - other: Modifier la question des autres (à revoir) - rank_answer_edit_label: - other: Modifier la réponse d'un autre (à revoir) - rank_question_edit_without_review_label: - other: Modifier la question d'un autre utilisateur sans révision - rank_answer_edit_without_review_label: - other: Modifier la réponse d'un autre utilisateur sans révision - rank_question_audit_label: - other: Vérifier la question - rank_answer_audit_label: - other: Revoir les modifications de la réponse - rank_tag_audit_label: - other: Évaluer les modifications des tags - rank_tag_edit_without_review_label: - other: Modifier la description du tag sans révision - rank_tag_synonym_label: - other: Gérer les tags synonyme - email: - other: Email - e_mail: - other: Email - password: - other: Mot de passe - pass: - other: Mot de passe - old_pass: - other: Mot de passe actuel - original_text: - other: Ce post - email_or_password_wrong_error: - other: L'email et le mot de passe ne correspondent pas. - error: - common: - invalid_url: - other: URL invalide. - status_invalid: - other: Statut invalide. - password: - space_invalid: - other: Le mot de passe ne doit pas comporter d'espaces. - admin: - cannot_update_their_password: - other: Vous ne pouvez pas modifier votre mot de passe. - cannot_edit_their_profile: - other: Vous ne pouvez pas modifier votre profil. - cannot_modify_self_status: - other: Vous ne pouvez pas modifier votre statut. - email_or_password_wrong: - other: L'email et le mot de passe ne correspondent pas. - answer: - not_found: - other: Réponse introuvable. - cannot_deleted: - other: Pas de permission pour supprimer. - cannot_update: - other: Pas de permission pour mettre à jour. - question_closed_cannot_add: - other: Les questions sont fermées et ne peuvent pas être ajoutées. - content_cannot_empty: - other: La réponse ne peut être vide. - comment: - edit_without_permission: - other: Les commentaires ne sont pas autorisés à être modifiés. - not_found: - other: Commentaire non trouvé. - cannot_edit_after_deadline: - other: Le commentaire a été posté il y a trop longtemps pour être modifié. - content_cannot_empty: - other: Le commentaire ne peut être vide. - email: - duplicate: - other: L'adresse e-mail existe déjà. - need_to_be_verified: - other: L'adresse e-mail doit être vérifiée. - verify_url_expired: - other: L'URL de vérification de l'email a expiré, veuillez renvoyer l'email. - illegal_email_domain_error: - other: L'e-mail n'est pas autorisé à partir de ce domaine de messagerie. Veuillez en utiliser un autre. - lang: - not_found: - other: Fichier de langue non trouvé. - object: - captcha_verification_failed: - other: Le Captcha est incorrect. - disallow_follow: - other: Vous n’êtes pas autorisé à suivre. - disallow_vote: - other: Vous n’êtes pas autorisé à voter. - disallow_vote_your_self: - other: Vous ne pouvez pas voter pour votre propre message. - not_found: - other: Objet non trouvé. - verification_failed: - other: La vérification a échoué. - email_or_password_incorrect: - other: L'e-mail et le mot de passe ne correspondent pas. - old_password_verification_failed: - other: La vérification de l'ancien mot de passe a échoué - new_password_same_as_previous_setting: - other: Le nouveau mot de passe est le même que le précédent. - already_deleted: - other: Ce post a été supprimé. - meta: - object_not_found: - other: Méta objet introuvable - question: - already_deleted: - other: Ce message a été supprimé. - under_review: - other: Votre message est en attente de révision. Il sera visible une fois approuvé. - not_found: - other: Question non trouvée. - cannot_deleted: - other: Pas de permission pour supprimer. - cannot_close: - other: Pas de permission pour fermer. - cannot_update: - other: Pas de permission pour mettre à jour. - content_cannot_empty: - other: Le contenu ne peut pas être vide. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Le rang de réputation ne remplit pas la condition. - vote_fail_to_meet_the_condition: - other: Merci pour vos commentaires. Vous avez besoin d'au moins {{.Rank}} de réputation pour voter. - no_enough_rank_to_operate: - other: Vous avez besoin d'au moins {{.Rank}} de réputation pour faire cela. - report: - handle_failed: - other: La gestion du rapport a échoué. - not_found: - other: Rapport non trouvé. - tag: - already_exist: - other: Le tag existe déjà. - not_found: - other: Tag non trouvé. - recommend_tag_not_found: - other: Le tag Recommandé n'existe pas. - recommend_tag_enter: - other: Veuillez saisir au moins un tag. - not_contain_synonym_tags: - other: Ne dois pas contenir de tags synonymes. - cannot_update: - other: Pas de permission pour mettre à jour. - is_used_cannot_delete: - other: Vous ne pouvez pas supprimer un tag utilisé. - cannot_set_synonym_as_itself: - other: Vous ne pouvez pas définir le synonyme de la balise actuelle comme elle-même. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: Le nom d'expéditeur ne peut pas être une adresse e-mail. - theme: - not_found: - other: Thème non trouvé. - revision: - review_underway: - other: Impossible d'éditer actuellement, il y a une version dans la file d'attente des revues. - no_permission: - other: Aucune autorisation de réviser. - user: - external_login_missing_user_id: - other: La plateforme tierce ne fournit pas un identifiant d'utilisateur unique, vous ne pouvez donc pas vous connecter, veuillez contacter l'administrateur du site. - external_login_unbinding_forbidden: - other: Veuillez définir un mot de passe de connexion pour votre compte avant de supprimer ce login. - email_or_password_wrong: - other: - other: L'email et le mot de passe ne correspondent pas. - not_found: - other: Utilisateur non trouvé. - suspended: - other: L'utilisateur a été suspendu. - username_invalid: - other: Le nom d'utilisateur est invalide. - username_duplicate: - other: Nom d'utilisateur déjà utilisé. - set_avatar: - other: La configuration de l'avatar a échoué. - cannot_update_your_role: - other: Vous ne pouvez pas modifier votre rôle. - not_allowed_registration: - other: Actuellement, le site n'est pas ouvert aux inscriptions. - not_allowed_login_via_password: - other: Actuellement le site n'est pas autorisé à se connecter par mot de passe. - access_denied: - other: Accès refusé - page_access_denied: - other: Vous n'avez pas accès à cette page. - add_bulk_users_format_error: - other: "Erreur format {{.Field}} près de '{{.Content}}' à la ligne {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "Le nombre d'utilisateurs que vous ajoutez simultanément doit être compris entre 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: La lecture de la configuration a échoué - database: - connection_failed: - other: La connexion à la base de données a échoué - create_table_failed: - other: La création de la table a échoué - install: - create_config_failed: - other: Impossible de créer le fichier config.yaml. - upload: - unsupported_file_format: - other: Format de fichier non supporté. - site_info: - config_not_found: - other: Configuration du site introuvable. - badge: - object_not_found: - other: Objet badge introuvable - reason: - spam: - name: - other: Courrier indésirable - desc: - other: Ce message est une publicité ou un vandalisme. Il n'est pas utile ou pertinent pour le sujet actuel. - rude_or_abusive: - name: - other: grossier ou abusif - desc: - other: "Une personne raisonnable trouverait ce contenu inapproprié pour un discours respectueux." - a_duplicate: - name: - other: un doublon - desc: - other: Cette question a déjà été posée et a déjà une réponse. - placeholder: - other: Entrez le lien de la question existante - not_a_answer: - name: - other: n'est pas une réponse - desc: - other: "Cela a été posté comme une réponse, mais il n'essaie pas de répondre à la question. Il devrait s'agir d'un commentaire, d'une autre question, ou devrait être supprimé totalement." - no_longer_needed: - name: - other: ce n’est plus nécessaire - desc: - other: Ce commentaire est obsolète, conversationnel ou non pertinent pour ce post. - something: - name: - other: quelque chose d'autre - desc: - other: Ce message nécessite l'attention de l'équipe de modération pour une autre raison non listée ci-dessus. - placeholder: - other: Faites-nous savoir précisément ce qui vous préoccupe - community_specific: - name: - other: une raison spécifique à la communauté - desc: - other: Cette question ne répond pas à une directive de la communauté. - not_clarity: - name: - other: nécessite plus de détails ou de clarté - desc: - other: Cette question comprend actuellement plusieurs questions en une seule. Elle ne devrait se concentrer que sur un seul problème. - looks_ok: - name: - other: semble bien - desc: - other: Ce poste est bon en tant que tel et n'est pas de mauvaise qualité. - needs_edit: - name: - other: a besoin d'être modifié, et je l'ai fait - desc: - other: Améliorez et corrigez vous-même les problèmes liés à ce message. - needs_close: - name: - other: a besoin de fermer - desc: - other: Une question fermée ne peut pas être répondue, mais peut-être quand même modifiée, votée et commentée. - needs_delete: - name: - other: a besoin d'être supprimé - desc: - other: Ce message sera supprimé. - question: - close: - duplicate: - name: - other: courrier indésirable - desc: - other: Cette question a déjà été posée auparavant et a déjà une réponse. - guideline: - name: - other: une raison spécifique à la communauté - desc: - other: Cette question ne répond pas à une directive de la communauté. - multiple: - name: - other: a besoin de détails ou de clarté - desc: - other: Cette question comprend actuellement plusieurs questions en une seule. Elle ne devrait se concentrer que sur un seul problème. - other: - name: - other: quelque chose d'autre - desc: - other: Ce message nécessite l'attention du personnel pour une autre raison non listée ci-dessus. - operation_type: - asked: - other: demandé - answered: - other: répondu - modified: - other: modifié - deleted_title: - other: Question supprimée - questions_title: - other: Questions - tag: - tags_title: - other: Étiquettes - no_description: - other: L'étiquette n'a pas de description. - notification: - action: - update_question: - other: question mise à jour - answer_the_question: - other: question répondue - update_answer: - other: réponse mise à jour - accept_answer: - other: réponse acceptée - comment_question: - other: a commenté la question - comment_answer: - other: a commenté la réponse - reply_to_you: - other: vous a répondu - mention_you: - other: vous a mentionné - your_question_is_closed: - other: Une réponse a été publiée pour votre question - your_question_was_deleted: - other: Une réponse a été publiée pour votre question - your_answer_was_deleted: - other: Votre réponse a bien été supprimée - your_comment_was_deleted: - other: Votre commentaire a été supprimé - up_voted_question: - other: question approuvée - down_voted_question: - other: question défavorisée - up_voted_answer: - other: voter favorablement la réponse - down_voted_answer: - other: réponse défavorisée - up_voted_comment: - other: commentaire approuvé - invited_you_to_answer: - other: vous invite à répondre - earned_badge: - other: Vous avez gagné le badge "{{.BadgeName}}" - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Confirmez votre nouvelle adresse e-mail" - body: - other: "Confirmez votre nouvelle adresse électronique pour {{.SiteName}} en cliquant sur le lien suivant :
        \\n{{.ChangeEmailUrl}}

        \\n\\nSi vous n'avez pas demandé ce changement, veuillez ignorer cet e-mail.

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} a répondu à votre question" - body: - other: "{{.QuestionTitle}}

        \\n\\n{{.DisplayName}}:
        \\n
        {{.AnswerSummary}}

        \\nVoir sur {{.SiteName}}

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue.

        \\n\\nDésabonner" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} vous a invité à répondre" - body: - other: "{{.QuestionTitle}}

        \\n\\n{{.DisplayName}}:
        \\n
        Je pense que vous pourriez connaître la réponse.

        \\nVoir sur {{.SiteName}}

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue.

        \\n\\nDésabonner" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} a commenté votre message" - body: - other: "{{.QuestionTitle}}

        \\n\\n{{.DisplayName}}:
        \\n
        {{.CommentSummary}}

        \\nVoir sur {{.SiteName}}

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue.

        \\n\\nDésabonner" - new_question: - title: - other: "[{{.SiteName}}] Nouvelle question : {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote : Il s'agit d'un e-mail automatique, merci de ne pas répondre à ce message, votre réponse ne pourra être considérée.

        \n\nSe désabonner" - pass_reset: - title: - other: "[{{.SiteName }}] Réinitialisation du mot de passe" - body: - other: "Quelqu'un a demandé à réinitialiser votre mot de passe sur {{.SiteName}}.

        \\n\\nSi ce n'était pas vous, vous pouvez ignorer cet e-mail en toute sécurité.

        \\n\\nCliquez sur le lien suivant pour choisir un nouveau mot de passe :
        \\n{{.PassResetUrl}}\\n

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue." - register: - title: - other: "[{{.SiteName}}] Confirmez la création de votre compte" - body: - other: "Bienvenue sur {{.SiteName}}!

        \\n\\nCliquez sur le lien suivant pour confirmer et activer votre nouveau compte :
        \\n{{.RegisterUrl}}

        \\n\\nSi le lien ci-dessus n'est pas cliquable, essayez de le copier et de le coller dans la barre d'adresse de votre navigateur web.

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue." - test: - title: - other: "[{{.SiteName}}] Email de test" - body: - other: "Ceci est un e-mail de test.

        \\n\\n--
        \\nNote : Ceci est un e-mail automatisé du système, merci de ne pas répondre à ce message car votre réponse ne sera pas vue." - action_activity_type: - upvote: - other: vote positif - upvoted: - other: voté pour - downvote: - other: voter contre - downvoted: - other: voté contre - accept: - other: accepter - accepted: - other: accepté - edit: - other: éditer - review: - queued_post: - other: Post en file d'attente - flagged_post: - other: Signaler post - suggested_post_edit: - other: Modifications suggérées - reaction: - tooltip: - other: "{{ .Names }} et {{ .Count }} de plus..." - badge: - default_badges: - autobiographer: - name: - other: Autobiographe - desc: - other: Informations sur le profil. - certified: - name: - other: Certifié - desc: - other: Nous avons terminé notre nouveau tutoriel d'utilisation. - editor: - name: - other: Éditeur - desc: - other: Première modification du post. - first_flag: - name: - other: Premier drapeau - desc: - other: Premier a signalé un post. - first_upvote: - name: - other: Premier vote positif - desc: - other: Premier a signalé un post. - first_link: - name: - other: Premier lien - desc: - other: A ajouté un lien vers un autre message. - first_reaction: - name: - other: Première réaction - desc: - other: Première réaction au post. - first_share: - name: - other: Premier partage - desc: - other: Premier post partagé. - scholar: - name: - other: Érudit - desc: - other: A posé une question et accepté une réponse. - commentator: - name: - other: Commentateur - desc: - other: Laissez 5 commentaires. - new_user_of_the_month: - name: - other: Nouvel utilisateur du mois - desc: - other: Contributions en suspens au cours de leur premier mois. - read_guidelines: - name: - other: Lire les lignes de conduite - desc: - other: Lisez les [lignes directrices de la communauté]. - reader: - name: - other: Lecteur - desc: - other: Lisez toutes les réponses dans un sujet avec plus de 10 réponses. - welcome: - name: - other: Bienvenue - desc: - other: A reçu un vote positif. - nice_share: - name: - other: Bien partagé - desc: - other: A partagé un poste avec 25 visiteurs uniques. - good_share: - name: - other: Bon partage - desc: - other: A partagé un poste avec 300 visiteurs uniques. - great_share: - name: - other: Super Partage - desc: - other: A partagé un poste avec 1000 visiteurs uniques. - out_of_love: - name: - other: Amoureux - desc: - other: A donné 50 likes dans une journée. - higher_love: - name: - other: Amour plus grand - desc: - other: A donné 50 likes dans une journée 5 fois. - crazy_in_love: - name: - other: Fou d'amour - desc: - other: A recueilli 50 votes positifs par jour 20 fois. - promoter: - name: - other: Promoteur - desc: - other: Inviter un utilisateur. - campaigner: - name: - other: Propagandiste - desc: - other: A invité 3 utilisateurs de base. - champion: - name: - other: Champion - desc: - other: A invité 5 membres. - thank_you: - name: - other: Merci - desc: - other: A 20 postes votés et a donné 10 votes. - gives_back: - name: - other: Redonne - desc: - other: A 100 postes votés et a donné 100 votes. - empathetic: - name: - other: Empathique - desc: - other: A 500 postes votés et a donné 1000 votes. - enthusiast: - name: - other: Enthousiaste - desc: - other: Visite de 10 jours consécutifs. - aficionado: - name: - other: Aficionado - desc: - other: Visite de 100 jours consécutifs. - devotee: - name: - other: Devotee - desc: - other: Visite de 365 jours consécutifs. - anniversary: - name: - other: Anniversaire - desc: - other: Membre actif pour une année, affiché au moins une fois. - appreciated: - name: - other: Apprécié - desc: - other: A reçu 1 vote positif sur 20 posts. - respected: - name: - other: Respecté - desc: - other: A reçu 2 vote positif sur 100 posts. - admired: - name: - other: Admirée - desc: - other: A reçu 5 vote positif sur 300 messages. - solved: - name: - other: Résolu - desc: - other: Une réponse a été acceptée. - guidance_counsellor: - name: - other: Conseiller d'orientation - desc: - other: 10 réponses sont acceptées. - know_it_all: - name: - other: Tout-savoir - desc: - other: 50 réponses sont acceptées. - solution_institution: - name: - other: Institution de solution - desc: - other: 150 réponses sont acceptées. - nice_answer: - name: - other: Belle réponse - desc: - other: Réponse a obtenu un score de 10 ou plus. - good_answer: - name: - other: Bonne répone - desc: - other: Réponse a obtenu un score de 25 ou plus. - great_answer: - name: - other: Super Réponse - desc: - other: Réponse a obtenu un score de 50 ou plus. - nice_question: - name: - other: Belle Question - desc: - other: Question a obtenu un score de 10 ou plus. - good_question: - name: - other: Bonne Question - desc: - other: Question a obtenu un score de 25 ou plus. - great_question: - name: - other: Super Question - desc: - other: Question a obtenu un score de 50 ou plus. - popular_question: - name: - other: Question Populaire - desc: - other: Question avec 500 points de vue. - notable_question: - name: - other: Question notable - desc: - other: Question avec 1,000 points de vue. - famous_question: - name: - other: Question célèbre - desc: - other: Question avec 5000 points de vue. - popular_link: - name: - other: Lien populaire - desc: - other: A posté un lien externe avec 50 clics. - hot_link: - name: - other: Lien chaud - desc: - other: A posté un lien externe avec 300 clics. - famous_link: - name: - other: Célèbre lien - desc: - other: A posté un lien externe avec 100 clics. - default_badge_groups: - getting_started: - name: - other: Initialisation complète - community: - name: - other: Communauté - posting: - name: - other: Publication -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Comment mettre en forme - desc: >- -
        • mentionner un post: #post_id

        • Pour faire des liens

          <https://url.com>

          [Title](https://url.com)
        • mettre des retour entre les paragraphes

        • _italic_ or **gras**

        • indenter le code par 4 espaces

        • citation en plaçant > au début de la ligne

        • guillemets inversés `comme_ca_`

        • créer une banière de code avec les guillemets inversés `

          ```
          code ici
          ```
        - pagination: - prev: Préc - next: Suivant - page_title: - question: Question - questions: Questions - tag: Étiquette - tags: Étiquettes - tag_wiki: tag wiki - create_tag: Créer un tag - edit_tag: Modifier l'étiquette - ask_a_question: Create Question - edit_question: Modifier la question - edit_answer: Modifier la réponse - search: Rechercher - posts_containing: Messages contenant - settings: Paramètres - notifications: Notifications - login: Se connecter - sign_up: S'inscrire - account_recovery: Récupération de compte - account_activation: Activation du compte - confirm_email: Confirmer l'email - account_suspended: Compte suspendu - admin: Admin - change_email: Modifier l'e-mail - install: Installation d'Answer - upgrade: Mise à jour d'Answer - maintenance: Maintenance du site - users: Utilisateurs - oauth_callback: Traitement - http_404: Erreur HTTP 404 - http_50X: Erreur HTTP 500 - http_403: Erreur HTTP 403 - logout: Se déconnecter - posts: Posts - notifications: - title: Notifications - inbox: Boîte de réception - achievement: Accomplissements - new_alerts: Nouvelles notifications - all_read: Tout marquer comme lu - show_more: Afficher plus - someone: Quelqu'un - inbox_type: - all: Tous - posts: Publications - invites: Invitations - votes: Votes - answer: Réponse - question: Question - badge_award: Badge - suspended: - title: Votre compte a été suspendu - until_time: "Votre compte a été suspendu jusqu'au {{ time }}." - forever: Cet utilisateur a été suspendu pour toujours. - end: Vous ne respectez pas les directives de la communauté. - contact_us: Contactez-nous - editor: - blockquote: - text: Bloc de citation - bold: - text: Gras - chart: - text: Diagramme - flow_chart: Organigramme - sequence_diagram: Diagramme de séquence - class_diagram: Diagramme de classe - state_diagram: Diagramme d'état - entity_relationship_diagram: Diagramme entité-association - user_defined_diagram: Diagramme défini par l'utilisateur - gantt_chart: Diagramme de Gantt - pie_chart: Camembert - code: - text: Exemple de Code - add_code: Ajouter un exemple de code - form: - fields: - code: - label: Code - msg: - empty: Le code ne peut pas être vide. - language: - label: Langage - placeholder: Détection automatique - btn_cancel: Annuler - btn_confirm: Ajouter - formula: - text: Formule - options: - inline: Formule en ligne - block: Bloc de formule - heading: - text: Titre - options: - h1: Titre de niveau 1 - h2: Titre de niveau 2 - h3: Titre de niveau 3 - h4: Titre de niveau 4 - h5: Titre de niveau 5 - h6: Titre de niveau 6 - help: - text: Aide - hr: - text: Ligne horizontale - image: - text: Image - add_image: Ajouter une image - tab_image: Téléverser une image - form_image: - fields: - file: - label: Fichier image - btn: Sélectionner une image - msg: - empty: Le fichier ne doit pas être vide. - only_image: Seules les images sont autorisées. - max_size: La taille du fichier ne doit pas dépasser {{size}} Mo. - desc: - label: Description - tab_url: URL de l'image - form_url: - fields: - url: - label: URL de l'image - msg: - empty: L'URL de l'image ne peut pas être vide. - name: - label: Description - btn_cancel: Annuler - btn_confirm: Ajouter - uploading: Téléversement en cours - indent: - text: Indentation - outdent: - text: Désindenter - italic: - text: Mise en valeur - link: - text: Hyperlien - add_link: Ajouter un lien hypertexte - form: - fields: - url: - label: URL - msg: - empty: L'URL ne peut pas être vide. - name: - label: Description - btn_cancel: Annuler - btn_confirm: Ajouter - ordered_list: - text: Liste numérotée - unordered_list: - text: Liste à puces - table: - text: Tableau - heading: Titre - cell: Cellule - file: - text: Joindre des fichiers - not_supported: "Ne prenez pas en charge ce type de fichier. Réessayez avec {{file_type}}." - max_size: "La taille du fichier ne doit pas dépasser {{size}} Mo." - close_modal: - title: Je ferme ce post comme... - btn_cancel: Annuler - btn_submit: Valider - remark: - empty: Ne peut pas être vide. - msg: - empty: Veuillez sélectionner une raison. - report_modal: - flag_title: Je suis en train de signaler ce post comme... - close_title: Je ferme ce post comme... - review_question_title: Vérifier la question - review_answer_title: Vérifier la réponse - review_comment_title: Revoir le commentaire - btn_cancel: Annuler - btn_submit: Envoyer - remark: - empty: Ne peut pas être vide. - msg: - empty: Veuillez sélectionner une raison s'il vous plaît. - not_a_url: Le format de l'URL est incorrect. - url_not_match: L'origine de l'URL ne correspond pas au site web actuel. - tag_modal: - title: Créer un nouveau tag - form: - fields: - display_name: - label: Nom Affiché - msg: - empty: Le nom d'affichage ne peut être vide. - range: Le nom doit contenir moins de 35 caractères. - slug_name: - label: Limace d'URL - desc: Titre de 35 caractères maximum. - msg: - empty: L'URL ne peut pas être vide. - range: Titre de 35 caractères maximum. - character: Le slug d'URL contient un jeu de caractères non autorisé. - desc: - label: Description - revision: - label: Révision - edit_summary: - label: Modifier le résumé - placeholder: >- - Expliquez brièvement vos modifications (orthographe corrigée, grammaire corrigée, mise en forme améliorée) - btn_cancel: Annuler - btn_submit: Valider - btn_post: Publier un nouveau tag - tag_info: - created_at: Créé - edited_at: Modifié - history: Historique - synonyms: - title: Synonymes - text: Les tags suivants seront redistribués vers - empty: Aucun synonyme trouvé. - btn_add: Ajouter un synonyme - btn_edit: Modifier - btn_save: Enregistrer - synonyms_text: Les balises suivantes seront remappées en - delete: - title: Supprimer cette étiquette - tip_with_posts: >- -

        Nous ne permettons pas la suppression d'un tag avec des posts

        Veuillez d'abord supprimer ce tag des posts.

        - tip_with_synonyms: >- -

        Nous ne permettons pas de supprimer un tag avec des synonymes.

        Veuillez d'abord supprimer les synonymes de ce tag.

        - tip: Êtes-vous sûr de vouloir supprimer ? - close: Fermer - merge: - title: Étiquette de fusion - source_tag_title: Étiquette de source - source_tag_description: Cette étiquette de source et ses données associées seront réorganisées vers l'étiquette cible. - target_tag_title: Étiquette cible - target_tag_description: Un synonyme entre ces deux étiquettes sera créé après la fusion. - no_results: Aucune étiquette correspondante - btn_submit: Valider - btn_close: Fermer - edit_tag: - title: Editer le tag - default_reason: Éditer le tag - default_first_reason: Ajouter un tag - btn_save_edits: Enregistrer les modifications - btn_cancel: Annuler - dates: - long_date: D MMM - long_date_with_year: "D MMMM YYYY" - long_date_with_time: "D MMM YYYY [at] HH:mm" - now: maintenant - x_seconds_ago: "il y a {{count}}s" - x_minutes_ago: "il y a {{count}}m" - x_hours_ago: "il y a {{count}}h" - hour: heure - day: jour - hours: heures - days: jours - month: month - months: months - year: year - reaction: - heart: cœur - smile: sourire - frown: froncer les sourcils - btn_label: ajout et suppression de réactions - undo_emoji: annuler la réaction {{ emoji }} - react_emoji: réagir à {{ emoji }} - unreact_emoji: annuler la réaction avec {{ emoji }} - comment: - btn_add_comment: Ajoutez un commentaire - reply_to: Répondre à - btn_reply: Répondre - btn_edit: Éditer - btn_delete: Supprimer - btn_flag: Balise - btn_save_edits: Enregistrer les modifications - btn_cancel: Annuler - show_more: "{{count}} commentaires restants" - tip_question: >- - Utilisez les commentaires pour demander plus d'informations ou suggérer des améliorations. Évitez de répondre aux questions dans les commentaires. - tip_answer: >- - Utilisez des commentaires pour répondre à d'autres utilisateurs ou leur signaler des modifications. Si vous ajoutez de nouvelles informations, modifiez votre message au lieu de commenter. - tip_vote: Il ajoute quelque chose d'utile au post - edit_answer: - title: Modifier la réponse - default_reason: Modifier la réponse - default_first_reason: Ajouter une réponse - form: - fields: - revision: - label: Modification - answer: - label: Réponse - feedback: - characters: le contenu doit comporter au moins 6 caractères. - edit_summary: - label: Modifier le résumé - placeholder: >- - Expliquez brièvement vos changements (correction orthographique, correction grammaticale, mise en forme améliorée) - btn_save_edits: Enregistrer les modifications - btn_cancel: Annuler - tags: - title: Étiquettes - sort_buttons: - popular: Populaire - name: Nom - newest: Le plus récent - button_follow: Suivre - button_following: Abonnements - tag_label: questions - search_placeholder: Filtrer par étiquette - no_desc: L'étiquette n'a pas de description. - more: Plus - wiki: Wiki - ask: - title: Create Question - edit_title: Modifier la question - default_reason: Modifier la question - default_first_reason: Create question - similar_questions: Questions similaires - form: - fields: - revision: - label: Modification - title: - label: Titre - placeholder: What's your topic? Be specific. - msg: - empty: Le titre ne peut pas être vide. - range: Titre de 150 caractères maximum - body: - label: Corps - msg: - empty: Le corps ne peut pas être vide. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Étiquettes - msg: - empty: Les étiquettes ne peuvent pas être vides. - answer: - label: Réponse - msg: - empty: La réponse ne peut être vide. - edit_summary: - label: Modifier le résumé - placeholder: >- - Expliquez brièvement vos changements (correction orthographique, correction grammaticale, mise en forme améliorée) - btn_post_question: Publier votre question - btn_save_edits: Enregistrer les modifications - answer_question: Répondre à votre propre question - post_question&answer: Publiez votre question et votre réponse - tag_selector: - add_btn: Ajouter une étiquette - create_btn: Créer une nouvelle étiquette - search_tag: Rechercher une étiquette - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: Aucune étiquette correspondante - tag_required_text: Étiquette requise (au moins une) - header: - nav: - question: Questions - tag: Étiquettes - user: Utilisateurs - badges: Badges - profile: Profil - setting: Paramètres - logout: Se déconnecter - admin: Administration - review: Vérifier - bookmark: Favoris - moderation: Modération - search: - placeholder: Rechercher - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Remplacer - loading: chargement en cours... - pic_auth_code: - title: Captcha - placeholder: Saisissez le texte ci-dessus - msg: - empty: Le captcha ne peut pas être vide. - inactive: - first: >- - Vous avez presque fini ! Un mail de confirmation a été envoyé à {{mail}}. Veuillez suivre les instructions dans le mail pour activer votre compte. - info: "S'il n'arrive pas, vérifiez dans votre dossier spam." - another: >- - Nous vous avons envoyé un autre e-mail d'activation à {{mail}}. Cela peut prendre quelques minutes pour arriver ; assurez-vous de vérifier votre dossier spam. - btn_name: Renvoyer le mail d'activation - change_btn_name: Modifier l'e-mail - msg: - empty: Ne peut pas être vide. - resend_email: - url_label: Êtes-vous sûr de vouloir renvoyer l'email d'activation ? - url_text: Vous pouvez également donner le lien d'activation ci-dessus à l'utilisateur. - login: - login_to_continue: Connectez-vous pour continuer - info_sign: Vous n'avez pas de compte ? <1>Inscrivez-vous - info_login: Vous avez déjà un compte ? <1>Connectez-vous - agreements: En vous inscrivant, vous acceptez la <1>politique de confidentialité et les <3>conditions de service. - forgot_pass: Mot de passe oublié ? - name: - label: Nom - msg: - empty: Le nom ne peut pas être vide. - range: Le nom doit contenir entre 2 et 30 caractères. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: Email - msg: - empty: L'email ne peut pas être vide. - password: - label: Mot de passe - msg: - empty: Le mot de passe ne peut pas être vide. - different: Les mots de passe saisis ne sont pas identiques - account_forgot: - page_title: Mot de passe oublié - btn_name: Envoyer un e-mail de récupération - send_success: >- - Si un compte est associé à {{mail}}, vous recevrez un email contenant les instructions pour réinitialiser votre mot de passe. - email: - label: E-mail - msg: - empty: L'e-mail ne peut pas être vide. - change_email: - btn_cancel: Annuler - btn_update: Mettre à jour l'adresse e-mail - send_success: >- - Si un compte est associé à {{mail}}, vous recevrez un email contenant les instructions pour réinitialiser votre mot de passe. - email: - label: Nouvel e-mail - msg: - empty: L'email ne peut pas être vide. - oauth: - connect: Se connecter avec {{ auth_name }} - remove: Retirer {{ auth_name }} - oauth_bind_email: - subtitle: Ajoutez un e-mail de récupération à votre compte. - btn_update: Mettre à jour l'adresse e-mail - email: - label: Email - msg: - empty: L'email ne peut pas être vide. - modal_title: L'email existe déjà. - modal_content: Cette adresse e-mail est déjà enregistrée. Êtes-vous sûr de vouloir vous connecter au compte existant ? - modal_cancel: Modifier l'adresse e-mail - modal_confirm: Se connecter au compte existant - password_reset: - page_title: Réinitialiser le mot de passe - btn_name: Réinitialiser mon mot de passe - reset_success: >- - Vous avez modifié votre mot de passe avec succès ; vous allez être redirigé vers la page de connexion. - link_invalid: >- - Désolé, ce lien de réinitialisation de mot de passe n'est plus valide. Peut-être que votre mot de passe est déjà réinitialisé ? - to_login: Continuer vers la page de connexion - password: - label: Mot de passe - msg: - empty: Le mot de passe ne peut pas être vide. - length: La longueur doit être comprise entre 8 et 32 - different: Les mots de passe saisis ne sont pas identiques - password_confirm: - label: Confirmer le nouveau mot de passe - settings: - page_title: Paramètres - goto_modify: Aller modifier - nav: - profile: Profil - notification: Notifications - account: Compte - interface: Interface - profile: - heading: Profil - btn_name: Enregistrer - display_name: - label: Nom affiché - msg: Le nom ne peut être vide. - msg_range: Le nom d'affichage doit contenir entre 2 et 30 caractères. - username: - label: Nom d'utilisateur - caption: Les gens peuvent vous mentionner avec "@username". - msg: Le nom d'utilisateur ne peut pas être vide. - msg_range: Le nom d'utilisateur doit contenir entre 2 et 30 caractères. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Photo de profil - gravatar: Gravatar - gravatar_text: Vous pouvez modifier l'image sur - custom: Personnaliser - custom_text: Vous pouvez charger votre image. - default: Système - msg: Veuillez charger un avatar - bio: - label: Biographie - website: - label: Site Web - placeholder: "https://example.com" - msg: Format du site web incorrect - location: - label: Position - placeholder: "Ville, Pays" - notification: - heading: Notifications - turn_on: Activer - inbox: - label: Notifications par e-mail - description: Réponses à vos questions, commentaires, invitaitons et plus. - all_new_question: - label: Toutes les nouvelles questions - description: Recevez une notification pour toutes les nouvelles questions. Jusqu'à 50 questions par semaine. - all_new_question_for_following_tags: - label: Toutes les nouvelles questions pour les tags suivants - description: Recevez une notification pour toutes les nouvelles questions avec les tags suivants. - account: - heading: Compte - change_email_btn: Modifier l'adresse e-mail - change_pass_btn: Changer le mot de passe - change_email_info: >- - Nous vous avons envoyé un mail à cette adresse. Merci de suivre les instructions. - email: - label: Email - new_email: - label: Nouvel e-mail - msg: La nouvelle adresse e-mail ne peut pas être vide. - pass: - label: Mot de passe actuel - msg: Le mot de passe ne peut pas être vide. - password_title: Mot de passe - current_pass: - label: Mot de passe actuel - msg: - empty: Le mot de passe actuel ne peut pas être vide. - length: La longueur doit être comprise entre 8 et 32. - different: Le mot de passe saisi ne correspond pas. - new_pass: - label: Nouveau mot de passe - pass_confirm: - label: Confirmer le nouveau mot de passe - interface: - heading: Interface - lang: - label: Langue de l'interface - text: Langue de l'interface utilisateur. Cela changera lorsque vous rafraîchissez la page. - my_logins: - title: Mes identifiants - label: Connectez-vous ou inscrivez-vous sur ce site en utilisant ces comptes. - modal_title: Supprimer la connexion - modal_content: Confirmez-vous vouloir supprimer cette connexion de votre compte ? - modal_confirm_btn: Supprimer - remove_success: Supprimé avec succès - toast: - update: mise à jour effectuée - update_password: Mot de passe changé avec succès. - flag_success: Merci pour votre signalement. - forbidden_operate_self: Interdit d'opérer sur vous-même - review: Votre révision s'affichera après vérification. - sent_success: Envoyé avec succès - related_question: - title: Related - answers: réponses - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Personnes interrogées - desc: Invite people who you think might know the answer. - invite: Inviter à répondre - add: Ajouter des personnes - search: Rechercher des personnes - question_detail: - action: Action - created: Created - Asked: Demandé - asked: demandé - update: Modifié - Edited: Edited - edit: modifié - commented: commenté - Views: Consultée - Follow: S’abonner - Following: Abonné(s) - follow_tip: Suivre cette question pour recevoir des notifications - answered: répondu - closed_in: Fermé dans - show_exist: Afficher la question existante. - useful: Utile - question_useful: C'est utile et clair - question_un_useful: Ce n'est pas clair ou n'est pas utile - question_bookmark: Ajouter cette question à vos favoris - answer_useful: C'est utile - answer_un_useful: Ce n'est pas utile - answers: - title: Réponses - score: Score - newest: Les plus récents - oldest: Le plus ancien - btn_accept: Accepter - btn_accepted: Accepté - write_answer: - title: Votre réponse - edit_answer: Modifier ma réponse existante - btn_name: Poster votre réponse - add_another_answer: Ajouter une autre réponse - confirm_title: Continuer à répondre - continue: Continuer - confirm_info: >- -

        Êtes-vous sûr de vouloir ajouter une autre réponse ?

        Vous pouvez utiliser le lien d'édition pour affiner et améliorer votre réponse existante.

        - empty: La réponse ne peut être vide. - characters: le contenu doit comporter au moins 6 caractères. - tips: - header_1: Merci pour votre réponse - li1_1: N’oubliez pas de répondre à la question. Fournissez des détails et partagez vos recherches. - li1_2: Sauvegardez toutes les déclarations que vous faites avec des références ou une expérience personnelle. - header_2: Mais évitez... - li2_1: Demander de l'aide, chercher des éclaircissements ou répondre à d'autres réponses. - reopen: - confirm_btn: Rouvrir - title: Rouvrir ce message - content: Êtes-vous sûr de vouloir rouvrir ? - list: - confirm_btn: Liste - title: Lister ce message - content: Êtes-vous sûr de vouloir lister ? - unlist: - confirm_btn: Délister - title: Masquer ce message de la liste - content: Êtes-vous sûr de vouloir masquer ce message de la liste ? - pin: - title: Épingler cet article - content: Êtes-vous sûr de vouloir l'épingler globalement ? Ce message apparaîtra en haut de toutes les listes de messages. - confirm_btn: Épingler - delete: - title: Supprimer la publication - question: >- - Nous ne recommandons pas de supprimer des questions avec des réponses car cela prive les futurs lecteurs de cette connaissance.

        Suppression répétée des questions répondues peut empêcher votre compte de poser. Êtes-vous sûr de vouloir supprimer ? - answer_accepted: >- -

        Nous ne recommandons pas de supprimer la réponse acceptée car cela prive les futurs lecteurs de cette connaissance.

        La suppression répétée des réponses acceptées peut empêcher votre compte de répondre. Êtes-vous sûr de vouloir supprimer ? - other: Êtes-vous sûr de vouloir supprimer ? - tip_answer_deleted: Cette réponse a été supprimée - undelete_title: Annuler la suppression de ce message - undelete_desc: Êtes-vous sûr de vouloir annuler la suppression ? - btns: - confirm: Confimer - cancel: Annuler - edit: Modifier - save: Enregistrer - delete: Supprimer - undelete: Annuler la suppression - list: Liste - unlist: Délister - unlisted: Non listé - login: Se connecter - signup: S'inscrire - logout: Se déconnecter - verify: Vérifier - create: Créer - approve: Approuver - reject: Rejeter - skip: Ignorer - discard_draft: Abandonner le brouillon - pinned: Épinglé - all: Tous - question: Question - answer: Réponse - comment: Commentaire - refresh: Actualiser - resend: Renvoyer - deactivate: Désactiver - active: Actif - suspend: Suspendre - unsuspend: Lever la suspension - close: Fermer - reopen: Rouvrir - ok: OK - light: Clair - dark: Sombre - system_setting: Paramètres système - default: Défaut - reset: Réinitialiser - tag: Étiquette - post_lowercase: publier - filter: Filtre - ignore: Ignore - submit: Soumettre - normal: Normal - closed: Fermé - deleted: Supprimé - deleted_permanently: Supprimé définitivement - pending: En attente de traitement - more: Plus - view: Vue - card: Carte - compact: Compact - display_below: Afficher dessous - always_display: Toujours afficher - or: ou - back_sites: Retour aux sites - search: - title: Résultats de la recherche - keywords: Mots-clés - options: Options - follow: Suivre - following: Abonnements - counts: "{{count}} Résultats" - counts_loading: "... Results" - more: Plus - sort_btns: - relevance: Pertinence - newest: Les plus récents - active: Actif - score: Score - more: Plus - tips: - title: Astuces de recherche avancée - tag: "<1>[tag] recherche à l'aide d'un tag" - user: "<1>utilisateur:username recherche par auteur" - answer: "<1>réponses:0 questions sans réponses" - score: "<1>score:3 messages avec plus de 3 points" - question: "<1>est:question rechercher des questions" - is_answer: "<1>est :réponse réponses de recherche" - empty: Nous n'avons rien trouvé.
        Essayez des mots-clés différents ou moins spécifiques. - share: - name: Partager - copy: Copier le lien - via: Partager via... - copied: Copié - facebook: Partager sur Facebook - twitter: Partager sur X - cannot_vote_for_self: Vous ne pouvez pas voter pour votre propre message. - modal_confirm: - title: Erreur... - delete_permanently: - title: Supprimer définitivement - content: Êtes-vous sûr de vouloir supprimer définitivement ? - account_result: - success: Votre nouveau compte est confirmé; vous serez redirigé vers la page d'accueil. - link: Continuer vers la page d'accueil - oops: Oups ! - invalid: Le lien que vous utilisez ne fonctionne plus. - confirm_new_email: Votre adresse email a été mise à jour. - confirm_new_email_invalid: >- - Désolé, ce lien de confirmation n'est plus valide. Votre email est peut-être déjà modifié ? - unsubscribe: - page_title: Se désabonner - success_title: Désabonnement réussi - success_desc: Vous avez été supprimé de cette liste d'abonnés avec succès et ne recevrez plus d'e-mails. - link: Modifier les paramètres - question: - following_tags: Hashtags suivis - edit: Éditer - save: Enregistrer - follow_tag_tip: Suivez les tags pour organiser votre liste de questions. - hot_questions: Questions populaires - all_questions: Toutes les questions - x_questions: "{{ count }} questions" - x_answers: "{{ count }} réponses" - x_posts: "{{ count }} Posts" - questions: Questions - answers: Réponses - newest: Les plus récents - active: Actif - hot: Populaires - frequent: Fréquent - recommend: Recommandé - score: Score - unanswered: Sans réponse - modified: modifié - answered: répondu - asked: demandé - closed: fermé - follow_a_tag: Suivre ce tag - more: Plus - personal: - overview: Aperçu - answers: Réponses - answer: réponse - questions: Questions - question: question - bookmarks: Favoris - reputation: Réputation - comments: Commentaires - votes: Votes - badges: Badges - newest: Les plus récents - score: Score - edit_profile: Éditer le profil - visited_x_days: "Visité {{ count }} jours" - viewed: Vu - joined: Inscrit - comma: "," - last_login: Vu - about_me: À propos de moi - about_me_empty: "// Hello, World !" - top_answers: Les meilleures réponses - top_questions: Questions les plus populaires - stats: Statistiques - list_empty: Aucune publication trouvée.
        Peut-être souhaiteriez-vous sélectionner un autre onglet ? - content_empty: Aucun post trouvé. - accepted: Accepté - answered: a répondu - asked: a demandé - downvoted: voté contre - mod_short: MOD - mod_long: Modérateurs - x_reputation: réputation - x_votes: votes reçus - x_answers: réponses - x_questions: questions - recent_badges: Badges récents - install: - title: Installation - next: Suivant - done: Terminé - config_yaml_error: Impossible de créer le fichier config.yaml. - lang: - label: Veuillez choisir une langue - db_type: - label: Moteur de base de données - db_username: - label: Nom d'utilisateur - placeholder: root - msg: Le nom d'utilisateur ne peut pas être vide. - db_password: - label: Mot de passe - placeholder: root - msg: Le mot de passe ne peut pas être vide. - db_host: - label: Hôte de la base de données - placeholder: "db:3306" - msg: L'hôte de la base de données ne peut pas être vide. - db_name: - label: Nom de la base de données - placeholder: réponse - msg: Le nom de la base de données ne peut pas être vide. - db_file: - label: Fichier de base de données - placeholder: /data/answer.db - msg: Le fichier de base de données ne doit pas être vide. - ssl_enabled: - label: Activer SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: Mode SSL - ssl_root_cert: - placeholder: Chemin du fichier sslrootcert - msg: Le chemin vers le fichier sslrootcert ne peut pas être vide - ssl_cert: - placeholder: Chemin du fichier sslcert - msg: Le chemin vers le fichier sslcert ne peut pas être vide - ssl_key: - placeholder: Chemin du fichier sslkey - msg: Le chemin vers le fichier sslkey ne peut pas être vide - config_yaml: - title: Créer config.yaml - label: Le fichier config.yaml a été créé. - desc: >- - Vous pouvez créer manuellement le fichier <1>config.yaml dans le répertoire <1>/var/wwww/xxx/ et y coller le texte suivant. - info: Après avoir fini, cliquez sur le bouton "Suivant". - site_information: Informations du site - admin_account: Compte Admin - site_name: - label: Nom du site - msg: Le nom ne peut pas être vide. - msg_max_length: Le nom affiché doit avoir une longueur de 4 à 30 caractères. - site_url: - label: URL du site - text: L'adresse de ce site. - msg: - empty: L'URL ne peut pas être vide. - incorrect: Le format de l'URL est incorrect. - max_length: L'URL du site doit avoir une longueur maximale de 512 caractères. - contact_email: - label: Email de contact - text: L'adresse email du responsable du site. - msg: - empty: L'email de contact ne peut pas être vide. - incorrect: Le format de l'email du contact est incorrect. - login_required: - label: Privé - switch: Connexion requise - text: Seuls les utilisateurs connectés peuvent accéder à cette communauté. - admin_name: - label: Nom - msg: Le nom ne peut pas être vide. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: La longueur du nom doit être comprise entre 2 et 30 caractères. - admin_password: - label: Mot de passe - text: >- - Vous aurez besoin de ce mot de passe pour vous connecter . Sauvegarder le de façon sécurisée. - msg: Le mot de passe ne peut pas être vide. - msg_min_length: Le mot de passe doit comporter au moins 8 caractères. - msg_max_length: Le mot de passe doit comporter au maximum 32 caractères. - admin_confirm_password: - label: "Répétez le mot de passe" - text: "Veuillez saisir à nouveau votre mot de passe pour confirmer." - msg: "Les mots de passe ne correspondent pas." - admin_email: - label: Email - text: Vous aurez besoin de cet email pour vous connecter. - msg: - empty: L'email ne peut pas être vide. - incorrect: Le format de l'email est incorrect. - ready_title: Votre site est prêt - ready_desc: >- - Si vous avez envie de changer plus de paramètres, visitez la <1>section admin; retrouvez la dans le menu du site. - good_luck: "Amusez-vous et bonne chance !" - warn_title: Attention - warn_desc: >- - Le fichier <1>config.yaml existe déjà. Si vous avez besoin de réinitialiser l'un des éléments de configuration de ce fichier, veuillez le supprimer d'abord. - install_now: Vous pouvez essayer de <1>l'installer maintenant. - installed: Déjà installé - installed_desc: >- - Il semble que se soit déjà installer. Pour tout réinstaller, veuillez d'abord nettoyer votre ancienne base de données. - db_failed: La connexion à la base de données a échoué - db_failed_desc: >- - Cela signifie que les informations de la base de données dans votre fichier <1>config.yaml est incorrect ou le contact avec le serveur de base de données n'a pas pu être établi. Cela pourrait signifier que le serveur de base de données de votre hôte est hors service. - counts: - views: vues - votes: votes - answers: réponses - accepted: Accepté - page_error: - http_error: Erreur HTTP {{ code }} - desc_403: Vous n'avez pas l'autorisation d'accéder à cette page. - desc_404: Malheureusement, cette page n'existe pas. - desc_50X: Le serveur a rencontré une erreur et n'a pas pu répondre à votre requête. - back_home: Retour à la page d'accueil - page_maintenance: - desc: "Nous sommes en maintenance, nous serons bientôt de retour." - nav_menus: - dashboard: Tableau de bord - contents: Contenus - questions: Questions - answers: Réponses - users: Utilisateurs - badges: Badges - flags: Signalements - settings: Paramètres - general: Général - interface: Interface - smtp: SMTP - branding: Marque - legal: Légal - write: Écrire - terms: Terms - tos: Conditions d'utilisation - privacy: Confidentialité - seo: SEO - customize: Personnaliser - themes: Thèmes - login: Se connecter - privileges: Privilèges - plugins: Extensions - installed_plugins: Extensions installées - apperance: Apparence - website_welcome: Bienvenue sur {{site_name}} - user_center: - login: Connexion - qrcode_login_tip: Veuillez utiliser {{ agentName }} pour scanner le code QR et vous connecter. - login_failed_email_tip: La connexion a échoué, veuillez autoriser cette application à accéder à vos informations de messagerie avant de réessayer. - badges: - modal: - title: Félicitations - content: Vous avez gagné un nouveau badge. - close: Fermer - confirm: Voir les badges - title: Badges - awarded: Octroyé - earned_×: Gagné ×{{ number }} - ×_awarded: "{{ number }} octroyés" - can_earn_multiple: Vous pouvez gagner cela plusieurs fois. - earned: Gagné - admin: - admin_header: - title: Admin - dashboard: - title: Tableau de bord - welcome: Bienvenue dans l'admin ! - site_statistics: Statistiques du site - questions: "Questions :" - resolved: "Résolu :" - unanswered: "Sans réponse :" - answers: "Réponses :" - comments: "Commentaires:" - votes: "Votes :" - users: "Utilisateurs :" - flags: "Signalements:" - reviews: "Revoir :" - site_health: Etat du site - version: "Version :" - https: "HTTPS :" - upload_folder: "Dossier de téléversement :" - run_mode: "Mode de fonctionnement :" - private: Privé - public: Public - smtp: "SMTP :" - timezone: "Fuseau horaire :" - system_info: Informations système - go_version: "Version de Go :" - database: "Base de donnée :" - database_size: "Taille de la base de données :" - storage_used: "Stockage utilisé :" - uptime: "Uptime :" - links: Liens - plugins: Extensions - github: GitHub - blog: Blog - contact: Contact - forum: Forum - documents: Documents - feedback: Commentaires - support: Support - review: Vérifier - config: Configuration - update_to: Mise à jour vers - latest: Récents - check_failed: Vérification échouée - "yes": "Oui" - "no": "Non" - not_allowed: Non autorisé - allowed: Autorisé - enabled: Activé - disabled: Désactivé - writable: Écriture autorisée - not_writable: Écriture refusée - flags: - title: Signalements - pending: En attente - completed: Complété - flagged: Signalé - flagged_type: Signalé {{ type }} - created: Créé - action: Action - review: Vérification - user_role_modal: - title: Changer le rôle d'un utilisateur en... - btn_cancel: Annuler - btn_submit: Valider - new_password_modal: - title: Définir un nouveau mot de passe - form: - fields: - password: - label: Mot de passe - text: L'utilisateur sera déconnecté et devra se connecter à nouveau. - msg: Le mot de passe doit contenir entre 8 et 32 caractères. - btn_cancel: Annuler - btn_submit: Envoyer - edit_profile_modal: - title: Éditer le profil - form: - fields: - display_name: - label: Nom affiché - msg_range: Le nom d'affichage doit contenir entre 2 et 30 caractères. - username: - label: Nom d'utilisateur - msg_range: Le nom d'utilisateur doit contenir entre 2 et 30 caractères. - email: - label: Email - msg_invalid: Adresse e-mail non valide. - edit_success: Modifié avec succès - btn_cancel: Annuler - btn_submit: Soumettre - user_modal: - title: Ajouter un nouvel utilisateur - form: - fields: - users: - label: Ajouter des utilisateurs en masse - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Séparez « nom, email, mot de passe » par des virgules. Un utilisateur par ligne. - msg: "Veuillez entrer l'email de l'utilisateur, un par ligne." - display_name: - label: Nom affiché - msg: Le nom affiché doit avoir une longueur de 2 à 30 caractères. - email: - label: Email - msg: L'email n'est pas valide. - password: - label: Mot de passe - msg: Le mot de passe doit comporter entre 8 et 32 caractères. - btn_cancel: Annuler - btn_submit: Valider - users: - title: Utilisateurs - name: Nom - email: E-mail - reputation: Réputation - created_at: Date de création - delete_at: Date de suppression - suspend_at: Date de suspension - suspend_until: Suspend until - status: Statut - role: Rôle - action: Action - change: Modifier - all: Tous - staff: Staff - more: Plus - inactive: Inactif - suspended: Suspendu - deleted: Supprimé - normal: Normal - Moderator: Modérateur - Admin: Administrateur - User: Utilisateur - filter: - placeholder: "Filtrer par nom, utilisateur:id" - set_new_password: Définir un nouveau mot de passe - edit_profile: Éditer le profil - change_status: Modifier le statut - change_role: Modifier le rôle - show_logs: Voir les logs - add_user: Ajouter un utilisateur - deactivate_user: - title: Désactiver l'utilisateur - content: Un utilisateur inactif doit revalider son email. - delete_user: - title: Supprimer cet utilisateur - content: Êtes-vous sûr de vouloir supprimer cet utilisateur ? Cette action est définitive ! - remove: Supprimer leur contenu - label: Supprimer toutes les questions, réponses, commentaires, etc. - text: Ne cochez pas cette case si vous souhaitez seulement supprimer le compte de l'utilisateur. - suspend_user: - title: Suspendre cet utilisateur - content: Un utilisateur suspendu ne peut pas se connecter. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Questions - unlisted: Non listé - post: Publication - votes: Votes - answers: Réponses - created: Créé - status: Statut - action: Action - change: Modifier - pending: En attente de traitement - filter: - placeholder: "Filtrer par titre, question:id" - answers: - page_title: Réponses - post: Publication - votes: Votes - created: Créé - status: Statut - action: Action - change: Modifier - filter: - placeholder: "Filtrer par titre, question:id" - general: - page_title: Général - name: - label: Nom du site - msg: Le nom ne peut pas être vide. - text: "Le nom de ce site, tel qu'il est utilisé dans la balise titre." - site_url: - label: URL du site - msg: L'URL ne peut pas être vide. - validate: Indiquez une URL valide. - text: L'adresse de ce site. - short_desc: - label: Courte description du site - msg: La description courte ne peut pas être vide. - text: "La description courte, telle qu'elle est utilisée dans le tag titre de la page d'accueil." - desc: - label: Description du site - msg: La description du site ne peut pas être vide. - text: "Décrivez ce site en une phrase, telle qu'elle est utilisée dans la balise meta description." - contact_email: - label: Email du contact - msg: L'email de contact ne peut pas être vide. - validate: L'email de contact n'est pas valide. - text: L'adresse email du responsable du site. - check_update: - label: Mises à jour logicielles - text: Rechercher automatiquement les mises à jour - interface: - page_title: Interface - language: - label: Langue de l'interface - msg: La langue de l'interface ne peut pas être vide. - text: Langue de l'interface de l'utilisateur. Cela changera lorsque vous rafraîchissez la page. - time_zone: - label: Fuseau Horaire - msg: Le fuseau horaire ne peut pas être vide. - text: Choisissez une ville dans le même fuseau horaire que vous. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: E-mail de l'expéditeur - msg: L'email expéditeur ne peut pas être vide. - text: L'adresse email à partir de laquelle les emails sont envoyés. - from_name: - label: Nom de l'expéditeur - msg: Le nom expéditeur ne peut pas être vide. - text: Le nom d'expéditeur à partir duquel les emails sont envoyés. - smtp_host: - label: Serveur SMTP - msg: Le'hôte SMTP ne peut pas être vide. - text: Votre serveur de mail. - encryption: - label: Chiffrement - msg: Le chiffrement ne peut pas être vide. - text: Pour la plupart des serveurs, l'option SSL est recommandée. - ssl: SSL - tls: TLS - none: Aucun - smtp_port: - label: Port SMTP - msg: Le port SMTP doit être compris entre 1 et 65535. - text: Le port vers votre serveur d'email. - smtp_username: - label: Utilisateur SMTP - msg: Le nom d'utilisateur SMTP ne peut pas être vide. - smtp_password: - label: Mot de passe SMTP - msg: Le mot de passe SMTP ne peut être vide. - test_email_recipient: - label: Destinataires des e-mails de test - text: Indiquez l'adresse email qui recevra l'email de test. - msg: Le destinataire de l'email de test est invalide - smtp_authentication: - label: Activer l'authentification - title: Authentification SMTP - msg: L'authentification SMTP ne peut pas être vide. - "yes": "Oui" - "no": "Non" - branding: - page_title: Marque - logo: - label: Logo - msg: Le logo ne peut pas être vide. - text: L'image du logo en haut à gauche de votre site. Utilisez une grande image rectangulaire avec une hauteur de 56 et un ratio d'aspect supérieur à 3:1. Si laissé vide, le titre du site sera affiché. - mobile_logo: - label: Logo pour la version mobile - text: Le logo utilisé sur la version mobile de votre site. Utilisez une image rectangulaire large avec une hauteur de 56. Si laissé vide, l'image du paramètre « logo » sera utilisée. - square_icon: - label: Icône carrée - msg: L'icône carrée ne peut pas être vide. - text: Image utilisée comme base pour les icônes de métadonnées. Idéalement supérieure à 512x512. - favicon: - label: Favicon - text: Une favicon pour votre site. Pour fonctionner correctement sur un CDN, il doit s'agir d'un png. Sera redimensionné en 32x32. Si laissé vide, « icône carrée » sera utilisé. - legal: - page_title: Légal - terms_of_service: - label: Conditions d’utilisation - text: "Vous pouvez ajouter le contenu des conditions de service ici. Si vous avez déjà un document hébergé ailleurs, veuillez fournir l'URL complète ici." - privacy_policy: - label: Protection des données - text: "Vous pouvez ajouter le contenu des conditions de service ici. Si vous avez déjà un document hébergé ailleurs, veuillez fournir l'URL complète ici." - external_content_display: - label: Contenu externe - text: "Le contenu comprend des images, des vidéos et des médias intégrés à partir de sites web externes." - always_display: Toujours afficher le contenu externe - ask_before_display: Demander avant d'afficher le contenu externe - write: - page_title: Écrire - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Écriture de la réponse - label: Chaque utilisateur ne peut écrire qu'une seule réponse pour chaque question - text: "Désactivez pour permettre aux utilisateurs d'écrire plusieurs réponses à la même question, ce qui peut causer une perte de concentration des réponses." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Tags recommandés - text: "Les balises recommandées apparaîtront par défaut dans la liste déroulante." - msg: - contain_reserved: "les tags recommandés ne peuvent pas contenir de tags réservés" - required_tag: - title: Définir les tags nécessaires - label: Définir les balises « Recommander» comme balises requises - text: "Chaque nouvelle question doit avoir au moins un tag recommandé." - reserved_tags: - label: Tags réservés - text: "Les tags réservés ne peuvent être ajoutés à un message que par un modérateur." - image_size: - label: Taille maximale de l'image (MB) - text: "La taille maximale de téléchargement d'image." - attachment_size: - label: Taille maximale des pièces jointes (MB) - text: "La taille maximale de téléchargement des fichiers joints." - image_megapixels: - label: Max mégapixels image - text: "Nombre maximum de mégapixels autorisés pour une image." - image_extensions: - label: Extensions de pièces jointes autorisées - text: "Une liste d'extensions de fichier autorisées pour l'affichage d'image, séparées par des virgules." - attachment_extensions: - label: Extensions de pièces jointes autorisées - text: "Une liste d'extensions de fichier autorisées pour le téléchargement, séparées par des virgules. ATTENTION : Autoriser les envois peut causer des problèmes de sécurité." - seo: - page_title: Référencement - permalink: - label: Lien permanent - text: Des structures d'URL personnalisées peuvent améliorer la facilité d'utilisation et la compatibilité de vos liens. - robots: - label: robots.txt - text: Ceci remplacera définitivement tous les paramètres liés au site. - themes: - page_title: Thèmes - themes: - label: Thèmes - text: Sélectionne un thème existant. - color_scheme: - label: Jeu de couleurs - navbar_style: - label: Style d'arrière-plan de la barre de navigation - primary_color: - label: Couleur primaire - text: Modifier les couleurs utilisées par vos thèmes - css_and_html: - page_title: CSS et HTML - custom_css: - label: CSS personnalisé - text: > - - head: - label: Head - text: > - - header: - label: En-tête - text: > - - footer: - label: Pied de page - text: Ceci va être inséré avant </html>. - sidebar: - label: Panneau latéral - text: Cela va être inséré dans la barre latérale. - login: - page_title: Se connecter - membership: - title: Adhésion - label: Autoriser les inscriptions - text: Désactivez pour empêcher quiconque de créer un nouveau compte. - email_registration: - title: Inscription par e-mail - label: Autoriser l'inscription par e-mail - text: Désactiver pour empêcher toute personne de créer un nouveau compte par e-mail. - allowed_email_domains: - title: Domaines d'email autorisés - text: Domaines de messagerie avec lesquels les utilisateurs peuvent créer des comptes. Un domaine par ligne. Ignoré si vide. - private: - title: Privé - label: Connexion requise - text: Seuls les utilisateurs connectés peuvent accéder à cette communauté. - password_login: - title: Connexion par mot de passe - label: Autoriser la connexion par e-mail et mot de passe - text: "AVERTISSEMENT : Si cette option est désactivée, vous ne pourrez peut-être pas vous connecter si vous n'avez pas configuré une autre méthode de connexion." - installed_plugins: - title: Extensions installées - plugin_link: Les plugins étendent les fonctionnalités d'Answer. Vous pouvez trouver des plugins dans le dépôt <1>Answer Plugin Repositor. - filter: - all: Tous - active: Actif - inactive: Inactif - outdated: Est obsolète - plugins: - label: Extensions - text: Sélectionnez une extension existante. - name: Nom - version: Versión - status: Statut - action: Action - deactivate: Désactiver - activate: Activer - settings: Paramètres - settings_users: - title: Utilisateurs - avatar: - label: Photo de profil par défaut - text: Pour les utilisateurs sans avatar personnalisé. - gravatar_base_url: - label: Gravatar Base URL - text: URL de la base de l'API du fournisseur Gravatar. Ignorée lorsqu'elle est vide. - profile_editable: - title: Profil modifiable - allow_update_display_name: - label: Permettre aux utilisateurs de changer leur nom d'affichage - allow_update_username: - label: Permettre aux clients de changer leurs noms d'utilisateur - allow_update_avatar: - label: Permettre aux utilisateurs de changer leur image de profil - allow_update_bio: - label: Permettre aux utilisateurs de changer leur biographie - allow_update_website: - label: Permettre aux utilisateurs de modifier leur site web - allow_update_location: - label: Permettre aux utilisateurs de modifier leur position - privilege: - title: Privilèges - level: - label: Niveau de réputation requis - text: Choisissez la réputation requise pour les privilèges - msg: - should_be_number: l'entrée doit être un nombre - number_larger_1: le nombre doit être égal ou supérieur à 1 - badges: - action: Action - active: Actif - activate: Activer - all: Tous - awards: Récompenses - deactivate: Désactiver - filter: - placeholder: Filtrer par nom, badge:id - group: Groupe - inactive: Inactif - name: Nom - show_logs: Voir les logs - status: Statut - title: Badges - form: - optional: (optionnel) - empty: ne peut pas être vide - invalid: est invalide - btn_submit: Sauvegarder - not_found_props: "La propriété requise {{ key }} est introuvable." - select: Sélectionner - page_review: - review: Vérifier - proposed: proposé - question_edit: Modifier la question - answer_edit: Modifier la réponse - tag_edit: Modifier le tag - edit_summary: Modifier le résumé - edit_question: Modifier la question - edit_answer: Modifier la réponse - edit_tag: Modifier l’étiquette - empty: Aucune révision restante. - approve_revision_tip: Acceptez-vous cette révision? - approve_flag_tip: Acceptez-vous ce rapport ? - approve_post_tip: Acceptez-vous ce post? - approve_user_tip: Acceptez-vous cet utilisateur ? - suggest_edits: Modifications suggérées - flag_post: Signaler ce message - flag_user: Signaler un utilisateur - queued_post: Message en file d'attente - queued_user: Utilisateur en file d'attente - filter_label: Type - reputation: réputation - flag_post_type: A signalé ce message comme {{ type }}. - flag_user_type: A signalé cet utilisateur comme {{ type }}. - edit_post: Éditer le post - list_post: Lister le post - unlist_post: Masquer la post de la liste - timeline: - undeleted: restauré - deleted: supprimé - downvote: vote négatif - upvote: voter pour - accept: accepté - cancelled: annulé - commented: commenté - rollback: Retour arrière (Rollback) - edited: modifié - answered: répondu - asked: demandé - closed: fermé - reopened: réouvert - created: créé - pin: épinglé - unpin: non épinglé - show: listé - hide: non listé - title: "Historique de" - tag_title: "Chronologie de" - show_votes: "Afficher les votes" - n_or_a: N/A - title_for_question: "Chronologie de" - title_for_answer: "Chronologie de la réponse à {{ title }} par {{ author }}" - title_for_tag: "Chronologie pour le tag" - datetime: Date et heure - type: Type - by: Par - comment: Commentaire - no_data: "Nous n'avons rien pu trouver." - users: - title: Utilisateurs - users_with_the_most_reputation: Utilisateurs ayant le score de réputation le plus élevé cette semaine - users_with_the_most_vote: Utilisateurs qui ont le plus voté cette semaine - staffs: Staff de la communauté - reputation: réputation - votes: votes - prompt: - leave_page: Voulez-vous vraiment quitter la page ? - changes_not_save: Impossible d'enregistrer vos modifications. - draft: - discard_confirm: Êtes-vous sûr de vouloir abandonner ce brouillon ? - messages: - post_deleted: Ce message a été supprimé. - post_cancel_deleted: Ce post a été restauré. - post_pin: Ce message a été épinglé. - post_unpin: Ce message a été déépinglé. - post_hide_list: Ce message a été masqué de la liste. - post_show_list: Ce message a été affiché dans la liste. - post_reopen: Ce message a été rouvert. - post_list: Ce post a été ajouté à la liste. - post_unlist: Ce post a été retiré de la liste. - post_pending: Votre message est en attente de révision. C'est un aperçu, il sera visible une fois qu'il aura été approuvé. - post_closed: Ce post a été fermé. - answer_deleted: Cette réponse a été supprimée. - answer_cancel_deleted: Cette réponse a été restaurée. - change_user_role: Le rôle de cet utilisateur a été modifié. - user_inactive: Cet utilisateur est déjà inactif. - user_normal: Cet utilisateur est déjà normal. - user_suspended: Cet utilisateur a été suspendu. - user_deleted: Cet utilisateur a été supprimé. - badge_activated: Ce badge a été activé. - badge_inactivated: Ce badge a été désactivé. - users_deleted: Ces utilisateurs ont été supprimés. - posts_deleted: Ces questions ont été supprimées. - answers_deleted: Ces réponses ont été supprimées. - copy: Copier dans le presse-papier - copied: Copié - external_content_warning: Les images/médias externes ne sont pas affichés. - - diff --git a/data/i18n/he_IL.yaml b/data/i18n/he_IL.yaml deleted file mode 100644 index 25c086f11..000000000 --- a/data/i18n/he_IL.yaml +++ /dev/null @@ -1,1384 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: Success. - unknown: - other: Unknown error. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - email: - other: Email - password: - other: Password - email_or_password_wrong_error: - other: Email and password do not match. - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - question: - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - rank: - fail_to_meet_the_condition: - other: Rank fail to meet the condition. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend Tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - smtp: - config_from_name_cannot_be_email: - other: The From Name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to Revision. - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - report: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude: - name: - other: rude or abusive - desc: - other: A reasonable person would find this content inappropriate for respectful discourse. - duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - not_answer: - name: - other: not an answer - desc: - other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. - not_need: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - other: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comments - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to {{site_name}} - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to {{site_name}} - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/hi_IN.yaml b/data/i18n/hi_IN.yaml deleted file mode 100644 index 17b0a6109..000000000 --- a/data/i18n/hi_IN.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Success. - unknown: - other: Unknown error. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - forbidden_error: - other: Forbidden. - duplicate_request_error: - other: Duplicate submission. - action: - report: - other: Flag - edit: - other: Edit - delete: - other: Delete - close: - other: Close - reopen: - other: Reopen - forbidden_error: - other: Forbidden. - pin: - other: Pin - hide: - other: Unlist - unpin: - other: Unpin - show: - other: List - invite_someone_to_answer: - other: Edit - undelete: - other: Undelete - merge: - other: Merge - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - privilege: - level_1: - description: - other: Level 1 (less reputation required for private team, group) - level_2: - description: - other: Level 2 (low reputation required for startup community) - level_3: - description: - other: Level 3 (high reputation required for mature community) - level_custom: - description: - other: Custom Level - rank_question_add_label: - other: Ask question - rank_answer_add_label: - other: Write answer - rank_comment_add_label: - other: Write comment - rank_report_add_label: - other: Flag - rank_comment_vote_up_label: - other: Upvote comment - rank_link_url_limit_label: - other: Post more than 2 links at a time - rank_question_vote_up_label: - other: Upvote question - rank_answer_vote_up_label: - other: Upvote answer - rank_question_vote_down_label: - other: Downvote question - rank_answer_vote_down_label: - other: Downvote answer - rank_invite_someone_to_answer_label: - other: Invite someone to answer - rank_tag_add_label: - other: Create new tag - rank_tag_edit_label: - other: Edit tag description (need to review) - rank_question_edit_label: - other: Edit other's question (need to review) - rank_answer_edit_label: - other: Edit other's answer (need to review) - rank_question_edit_without_review_label: - other: Edit other's question without review - rank_answer_edit_without_review_label: - other: Edit other's answer without review - rank_question_audit_label: - other: Review question edits - rank_answer_audit_label: - other: Review answer edits - rank_tag_audit_label: - other: Review tag edits - rank_tag_edit_without_review_label: - other: Edit tag description without review - rank_tag_synonym_label: - other: Manage tag synonyms - email: - other: Email - e_mail: - other: Email - password: - other: Password - pass: - other: Password - old_pass: - other: Current password - original_text: - other: This post - email_or_password_wrong_error: - other: Email and password do not match. - error: - common: - invalid_url: - other: Invalid URL. - status_invalid: - other: Invalid status. - password: - space_invalid: - other: Password cannot contain spaces. - admin: - cannot_update_their_password: - other: You cannot modify your password. - cannot_edit_their_profile: - other: You cannot modify your profile. - cannot_modify_self_status: - other: You cannot modify your status. - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - question_closed_cannot_add: - other: Questions are closed and cannot be added. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - illegal_email_domain_error: - other: Email is not allowed from that email domain. Please use another one. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - already_deleted: - other: This post has been deleted. - meta: - object_not_found: - other: Meta object not found - question: - already_deleted: - other: This post has been deleted. - under_review: - other: Your post is awaiting review. It will be visible after it has been approved. - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Reputation rank fail to meet the condition. - vote_fail_to_meet_the_condition: - other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. - no_enough_rank_to_operate: - other: You need at least {{.Rank}} reputation to do this. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - already_exist: - other: Tag already exists. - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - is_used_cannot_delete: - other: You cannot delete a tag that is in use. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: The from name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to revise. - user: - external_login_missing_user_id: - other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. - external_login_unbinding_forbidden: - other: Please set a login password for your account before you remove this login. - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration. - not_allowed_login_via_password: - other: Currently the site is not allowed to login via password. - access_denied: - other: Access denied - page_access_denied: - other: You do not have access to this page. - add_bulk_users_format_error: - other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - site_info: - config_not_found: - other: Site config not found. - badge: - object_not_found: - other: Badge object not found - reason: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude_or_abusive: - name: - other: rude or abusive - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - a_duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - placeholder: - other: Enter the existing question link - not_a_answer: - name: - other: not an answer - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." - no_longer_needed: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - something: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - placeholder: - other: Let us know specifically what you are concerned about - community_specific: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - not_clarity: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - looks_ok: - name: - other: looks OK - desc: - other: This post is good as-is and not low quality. - needs_edit: - name: - other: needs edit, and I did it - desc: - other: Improve and correct problems with this post yourself. - needs_close: - name: - other: needs close - desc: - other: A closed question can't answer, but still can edit, vote and comment. - needs_delete: - name: - other: needs delete - desc: - other: This post will be deleted. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - deleted_title: - other: Deleted question - questions_title: - other: Questions - tag: - tags_title: - other: Tags - no_description: - other: The tag has no description. - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted - up_voted_question: - other: upvoted question - down_voted_question: - other: downvoted question - up_voted_answer: - other: upvoted answer - down_voted_answer: - other: downvoted answer - up_voted_comment: - other: upvoted comment - invited_you_to_answer: - other: invited you to answer - earned_badge: - other: You've earned the "{{.BadgeName}}" badge - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Confirm your new email address" - body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} answered your question" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_question: - title: - other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Password reset" - body: - other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - register: - title: - other: "[{{.SiteName}}] Confirm your new account" - body: - other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - test: - title: - other: "[{{.SiteName}}] Test Email" - body: - other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: - upvote: - other: upvote - upvoted: - other: upvoted - downvote: - other: downvote - downvoted: - other: downvoted - accept: - other: accept - accepted: - other: accepted - edit: - other: edit - review: - queued_post: - other: Queued post - flagged_post: - other: Flagged post - suggested_post_edit: - other: Suggested edits - reaction: - tooltip: - other: "{{ .Names }} and {{ .Count }} more..." - badge: - default_badges: - autobiographer: - name: - other: Autobiographer - desc: - other: Filled out profile information. - certified: - name: - other: Certified - desc: - other: Completed our new user tutorial. - editor: - name: - other: Editor - desc: - other: First post edit. - first_flag: - name: - other: First Flag - desc: - other: First flagged a post. - first_upvote: - name: - other: First Upvote - desc: - other: First up voted a post. - first_link: - name: - other: First Link - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: First Share - desc: - other: First shared a post. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Leave 5 comments. - new_user_of_the_month: - name: - other: New User of the Month - desc: - other: Outstanding contributions in their first month. - read_guidelines: - name: - other: Read Guidelines - desc: - other: Read the [community guidelines]. - reader: - name: - other: Reader - desc: - other: Read every answers in a topic with more than 10 answers. - welcome: - name: - other: Welcome - desc: - other: Received a up vote. - nice_share: - name: - other: Nice Share - desc: - other: Shared a post with 25 unique visitors. - good_share: - name: - other: Good Share - desc: - other: Shared a post with 300 unique visitors. - great_share: - name: - other: Great Share - desc: - other: Shared a post with 1000 unique visitors. - out_of_love: - name: - other: Out of Love - desc: - other: Used 50 up votes in a day. - higher_love: - name: - other: Higher Love - desc: - other: Used 50 up votes in a day 5 times. - crazy_in_love: - name: - other: Crazy in Love - desc: - other: Used 50 up votes in a day 20 times. - promoter: - name: - other: Promoter - desc: - other: Invited a user. - campaigner: - name: - other: Campaigner - desc: - other: Invited 3 basic users. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: Thank You - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Active member for a year, posted at least once. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - create_tag: Create Tag - edit_tag: Edit Tag - ask_a_question: Create Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - oauth_callback: Processing - http_404: HTTP Error 404 - http_50X: HTTP Error 500 - http_403: HTTP Error 403 - logout: Log Out - posts: Posts - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - new_alerts: New alerts - all_read: Mark all as read - show_more: Show more - someone: Someone - inbox_type: - all: All - posts: Posts - invites: Invites - votes: Votes - answer: Answer - question: Question - badge_award: Badge - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - contact_us: Contact us - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image file - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed {{size}} MB. - desc: - label: Description - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered list - unordered_list: - text: Bulleted list - table: - text: Table - heading: Heading - cell: Cell - file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - not_a_url: URL format is incorrect. - url_not_match: URL origin does not match the current website. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description - revision: - label: Revision - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_cancel: Cancel - btn_submit: Submit - btn_post: Post new tag - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - tip_with_posts: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - tip_with_synonyms: >- -

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        - tip: Are you sure you wish to delete? - close: Close - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - default_first_reason: Add tag - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - hours: hours - days: days - month: month - months: months - year: year - reaction: - heart: heart - smile: smile - frown: frown - btn_label: add or remove reactions - undo_emoji: undo {{ emoji }} reaction - react_emoji: react with {{ emoji }} - unreact_emoji: unreact with {{ emoji }} - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: "{{count}} more comments" - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - tip_vote: It adds something useful to the post - edit_answer: - title: Edit Answer - default_reason: Edit answer - default_first_reason: Add answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: Newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - wiki: Wiki - ask: - title: Create Question - edit_title: Edit Question - default_reason: Edit question - default_first_reason: Create question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: What's your topic? Be specific. - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - badges: Badges - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - bookmark: Bookmarks - moderation: Moderation - search: - placeholder: Search - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - resend_email: - url_label: Are you sure you want to resend the activation email? - url_text: You can also give the activation link above to the user. - login: - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New email - msg: - empty: Email cannot be empty. - oauth: - connect: Connect with {{ auth_name }} - remove: Remove {{ auth_name }} - oauth_bind_email: - subtitle: Add a recovery email to your account. - btn_update: Update email address - email: - label: Email - msg: - empty: Email cannot be empty. - modal_title: Email already existes. - modal_content: This email address already registered. Are you sure you want to connect to the existing account? - modal_cancel: Change email - modal_confirm: Connect to the existing account - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm new password - settings: - page_title: Settings - goto_modify: Go to modify - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile image - gravatar: Gravatar - gravatar_text: You can change image on - custom: Custom - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About me - website: - label: Website - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location - placeholder: "City, Country" - notification: - heading: Email Notifications - turn_on: Turn on - inbox: - label: Inbox notifications - description: Answers to your questions, comments, invites, and more. - all_new_question: - label: All new questions - description: Get notified of all new questions. Up to 50 questions per week. - all_new_question_for_following_tags: - label: All new questions for following tags - description: Get notified of new questions for following tags. - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - pass: - label: Current password - msg: Password cannot be empty. - password_title: Password - current_pass: - label: Current password - msg: - empty: Current password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New password - pass_confirm: - label: Confirm new password - interface: - heading: Interface - lang: - label: Interface language - text: User interface language. It will change when you refresh the page. - my_logins: - title: My logins - label: Log in or sign up on this site using these accounts. - modal_title: Remove login - modal_content: Are you sure you want to remove this login from your account? - modal_confirm_btn: Remove - remove_success: Removed successfully - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - sent_success: Sent successfully - related_question: - title: Related - answers: answers - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: People Asked - desc: Select people who you think might know the answer. - invite: Invite to answer - add: Add people - search: Search people - question_detail: - action: Action - created: Created - Asked: Asked - asked: asked - update: Modified - Edited: Edited - edit: edited - commented: commented - Views: Viewed - Follow: Follow - Following: Following - follow_tip: Follow this question to receive notifications - answered: answered - closed_in: Closed in - show_exist: Show existing question. - useful: Useful - question_useful: It is useful and clear - question_un_useful: It is unclear or not useful - question_bookmark: Bookmark this question - answer_useful: It is useful - answer_un_useful: It is not useful - answers: - title: Answers - score: Score - newest: Newest - oldest: Oldest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - edit_answer: Edit my existing answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - tips: - header_1: Thanks for your answer - li1_1: Please be sure to answer the question. Provide details and share your research. - li1_2: Back up any statements you make with references or personal experience. - header_2: But avoid ... - li2_1: Asking for help, seeking clarification, or responding to other answers. - reopen: - confirm_btn: Reopen - title: Reopen this post - content: Are you sure you want to reopen? - list: - confirm_btn: List - title: List this post - content: Are you sure you want to list? - unlist: - confirm_btn: Unlist - title: Unlist this post - content: Are you sure you want to unlist? - pin: - title: Pin this post - content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. - confirm_btn: Pin - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_answer_deleted: This answer has been deleted - undelete_title: Undelete this post - undelete_desc: Are you sure you wish to undelete? - btns: - confirm: Confirm - cancel: Cancel - edit: Edit - save: Save - delete: Delete - undelete: Undelete - list: List - unlist: Unlist - unlisted: Unlisted - login: Log in - signup: Sign up - logout: Log out - verify: Verify - create: Create - approve: Approve - reject: Reject - skip: Skip - discard_draft: Discard draft - pinned: Pinned - all: All - question: Question - answer: Answer - comment: Comment - refresh: Refresh - resend: Resend - deactivate: Deactivate - active: Active - suspend: Suspend - unsuspend: Unsuspend - close: Close - reopen: Reopen - ok: OK - light: Light - dark: Dark - system_setting: System setting - default: Default - reset: Reset - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignore - submit: Submit - normal: Normal - closed: Closed - deleted: Deleted - deleted_permanently: Deleted permanently - pending: Pending - more: More - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - counts_loading: "... Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post. - modal_confirm: - title: Error... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - x_posts: "{{ count }} Posts" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - frequent: Frequent - recommend: Recommend - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - badges: Badges - newest: Newest - score: Score - edit_profile: Edit profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - comma: "," - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - content_empty: No posts found. - accepted: Accepted - answered: answered - asked: asked - downvoted: downvoted - mod_short: MOD - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - recent_badges: Recent Badges - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please choose a language - db_type: - label: Database engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database host - placeholder: "db:3306" - msg: Database host cannot be empty. - db_name: - label: Database name - placeholder: answer - msg: Database name cannot be empty. - db_file: - label: Database file - placeholder: /data/answer.db - msg: Database file cannot be empty. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site name - msg: Site name cannot be empty. - msg_max_length: Site name must be at maximum 30 characters in length. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - max_length: Site URL must be at maximum 512 characters in length. - contact_email: - label: Contact email - text: Email address of key contact responsible for this site. - msg: - empty: Contact email cannot be empty. - incorrect: Contact email incorrect format. - login_required: - label: Private - switch: Login required - text: Only logged in users can access this community. - admin_name: - label: Name - msg: Name cannot be empty. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - msg_min_length: Password must be at least 8 characters in length. - msg_max_length: Password must be at maximum 32 characters in length. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_error: - http_error: HTTP Error {{ code }} - desc_403: You don't have permission to access this page. - desc_404: Unfortunately, this page doesn't exist. - desc_50X: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - badges: Badges - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - terms: Terms - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - login: Login - privileges: Privileges - plugins: Plugins - installed_plugins: Installed Plugins - apperance: Appearance - website_welcome: Welcome to {{site_name}} - user_center: - login: Login - qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. - login_failed_email_tip: Login failed, please allow this app to access your email information before try again. - badges: - modal: - title: Congratulations - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site statistics - questions: "Questions:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - users: "Users:" - flags: "Flags:" - reviews: "Reviews:" - site_health: Site health - version: "Version:" - https: "HTTPS:" - upload_folder: "Upload folder:" - run_mode: "Running mode:" - private: Private - public: Public - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System info - go_version: "Go version:" - database: "Database:" - database_size: "Database size:" - storage_used: "Storage used:" - uptime: "Uptime:" - links: Links - plugins: Plugins - github: GitHub - blog: Blog - contact: Contact - forum: Forum - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - writable: Writable - not_writable: Not writable - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - flagged_type: Flagged {{ type }} - created: Created - action: Action - review: Review - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - edit_profile_modal: - title: Edit profile - form: - fields: - display_name: - label: Display name - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Invalid Email Address. - edit_success: Edited successfully - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - users: - label: Bulk add user - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separate “name, email, password” with commas. One user per line. - msg: "Please enter the user's email, one per line." - display_name: - label: Display name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - more: More - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - edit_profile: Edit profile - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - deactivate_user: - title: Deactivate user - content: An inactive user must re-validate their email. - delete_user: - title: Delete this user - content: Are you sure you want to delete this user? This is permanent! - remove: Remove their content - label: Remove all questions, answers, comments, etc. - text: Don’t check this if you wish to only delete the user’s account. - suspend_user: - title: Suspend this user - content: A suspended user can't log in. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Questions - unlisted: Unlisted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - pending: Pending - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short site description - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site description - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - check_update: - label: Software updates - text: Automatically check for updates - interface: - page_title: Interface - language: - label: Interface language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: From email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - tls: TLS - none: None - smtp_port: - label: SMTP port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test email recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile logo - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square icon - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Write - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Each user can only write one answer for each question - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Recommend tags - text: "Recommend tags will show in the dropdown list by default." - msg: - contain_reserved: "recommended tags cannot contain reserved tags" - required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved tags - text: "Reserved tags can only be used by moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - color_scheme: - label: Color scheme - navbar_style: - label: Navbar background style - primary_color: - label: Primary color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: > - - head: - label: Head - text: > - - header: - label: Header - text: > - - footer: - label: Footer - text: This will insert before </body>. - sidebar: - label: Sidebar - text: This will insert in sidebar. - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - email_registration: - title: Email registration - label: Allow email registration - text: Turn off to prevent anyone creating new account through email. - allowed_email_domains: - title: Allowed email domains - text: Email domains that users must register accounts with. One domain per line. Ignored when empty. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - password_login: - title: Password login - label: Allow email and password login - text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." - installed_plugins: - title: Installed Plugins - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. - filter: - all: All - active: Active - inactive: Inactive - outdated: Outdated - plugins: - label: Plugins - text: Select an existing plugin. - name: Name - version: Version - status: Status - action: Action - deactivate: Deactivate - activate: Activate - settings: Settings - settings_users: - title: Users - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - profile_editable: - title: Profile editable - allow_update_display_name: - label: Allow users to change their display name - allow_update_username: - label: Allow users to change their username - allow_update_avatar: - label: Allow users to change their profile image - allow_update_bio: - label: Allow users to change their about me - allow_update_website: - label: Allow users to change their website - allow_update_location: - label: Allow users to change their location - privilege: - title: Privileges - level: - label: Reputation required level - text: Choose the reputation required for the privileges - msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 - badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate - filter: - placeholder: Filter by name, badge:id - group: Group - inactive: Inactive - name: Name - show_logs: Show logs - status: Status - title: Badges - form: - optional: (optional) - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - select: Select - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - approve_revision_tip: Do you approve this revision? - approve_flag_tip: Do you approve this flag? - approve_post_tip: Do you approve this post? - approve_user_tip: Do you approve this user? - suggest_edits: Suggested edits - flag_post: Flag post - flag_user: Flag user - queued_post: Queued post - queued_user: Queued user - filter_label: Type - reputation: reputation - flag_post_type: Flagged this post as {{ type }}. - flag_user_type: Flagged this user as {{ type }}. - edit_post: Edit post - list_post: List post - unlist_post: Unlist post - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - pin: pinned - unpin: unpinned - show: listed - hide: unlisted - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores this week - users_with_the_most_vote: Users who voted the most this week - staffs: Our community staff - reputation: reputation - votes: votes - prompt: - leave_page: Are you sure you want to leave the page? - changes_not_save: Your changes may not be saved. - draft: - discard_confirm: Are you sure you want to discard your draft? - messages: - post_deleted: This post has been deleted. - post_cancel_deleted: This post has been undeleted. - post_pin: This post has been pinned. - post_unpin: This post has been unpinned. - post_hide_list: This post has been hidden from list. - post_show_list: This post has been shown to list. - post_reopen: This post has been reopened. - post_list: This post has been listed. - post_unlist: This post has been unlisted. - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/hu_HU.yaml b/data/i18n/hu_HU.yaml deleted file mode 100644 index 25c086f11..000000000 --- a/data/i18n/hu_HU.yaml +++ /dev/null @@ -1,1384 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: Success. - unknown: - other: Unknown error. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - email: - other: Email - password: - other: Password - email_or_password_wrong_error: - other: Email and password do not match. - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - question: - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - rank: - fail_to_meet_the_condition: - other: Rank fail to meet the condition. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend Tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - smtp: - config_from_name_cannot_be_email: - other: The From Name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to Revision. - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - report: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude: - name: - other: rude or abusive - desc: - other: A reasonable person would find this content inappropriate for respectful discourse. - duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - not_answer: - name: - other: not an answer - desc: - other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. - not_need: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - other: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comments - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to {{site_name}} - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to {{site_name}} - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/hy_AM.yaml b/data/i18n/hy_AM.yaml deleted file mode 100644 index 4249c5f03..000000000 --- a/data/i18n/hy_AM.yaml +++ /dev/null @@ -1,1371 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: "Success." - unknown: - other: "Unknown error." - request_format_error: - other: "Request format is not valid." - unauthorized_error: - other: "Unauthorized." - database_error: - other: "Data server error." - role: - name: - user: - other: "User" - admin: - other: "Admin" - moderator: - other: "Moderator" - description: - user: - other: "Default with no special access." - admin: - other: "Have the full power to access the site." - moderator: - other: "Has access to all posts except admin settings." - email: - other: "Email" - password: - other: "Password" - email_or_password_wrong_error: - other: "Email and password do not match." - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: "Answer do not found." - cannot_deleted: - other: "No permission to delete." - cannot_update: - other: "No permission to update." - comment: - edit_without_permission: - other: "Comment are not allowed to edit." - not_found: - other: "Comment not found." - email: - duplicate: - other: "Email already exists." - need_to_be_verified: - other: "Email should be verified." - verify_url_expired: - other: "Email verified URL has expired, please resend the email." - lang: - not_found: - other: "Language file not found." - object: - captcha_verification_failed: - other: "Captcha wrong." - disallow_follow: - other: "You are not allowed to follow." - disallow_vote: - other: "You are not allowed to vote." - disallow_vote_your_self: - other: "You can't vote for your own post." - not_found: - other: "Object not found." - verification_failed: - other: "Verification failed." - email_or_password_incorrect: - other: "Email and password do not match." - old_password_verification_failed: - other: "The old password verification failed" - new_password_same_as_previous_setting: - other: "The new password is the same as the previous one." - question: - not_found: - other: "Question not found." - cannot_deleted: - other: "No permission to delete." - cannot_close: - other: "No permission to close." - cannot_update: - other: "No permission to update." - rank: - fail_to_meet_the_condition: - other: "Rank fail to meet the condition." - report: - handle_failed: - other: "Report handle failed." - not_found: - other: "Report not found." - tag: - not_found: - other: "Tag not found." - recommend_tag_not_found: - other: "Recommend Tag is not exist." - recommend_tag_enter: - other: "Please enter at least one required tag." - not_contain_synonym_tags: - other: "Should not contain synonym tags." - cannot_update: - other: "No permission to update." - cannot_set_synonym_as_itself: - other: "You cannot set the synonym of the current tag as itself." - smtp: - config_from_name_cannot_be_email: - other: "The From Name cannot be a email address." - theme: - not_found: - other: "Theme not found." - revision: - review_underway: - other: "Can't edit currently, there is a version in the review queue." - no_permission: - other: "No permission to Revision." - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: "User not found." - suspended: - other: "User has been suspended." - username_invalid: - other: "Username is invalid." - username_duplicate: - other: "Username is already in use." - set_avatar: - other: "Avatar set failed." - cannot_update_your_role: - other: "You cannot modify your role." - not_allowed_registration: - other: "Currently the site is not open for registration" - config: - read_config_failed: - other: "Read config failed" - database: - connection_failed: - other: "Database connection failed" - create_table_failed: - other: "Create table failed" - install: - create_config_failed: - other: "Can't create the config.yaml file." - report: - spam: - name: - other: "spam" - desc: - other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." - rude: - name: - other: "rude or abusive" - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - duplicate: - name: - other: "a duplicate" - desc: - other: "This question has been asked before and already has an answer." - not_answer: - name: - other: "not an answer" - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." - not_need: - name: - other: "no longer needed" - desc: - other: "This comment is outdated, conversational or not relevant to this post." - other: - name: - other: "something else" - desc: - other: "This post requires staff attention for another reason not listed above." - question: - close: - duplicate: - name: - other: "spam" - desc: - other: "This question has been asked before and already has an answer." - guideline: - name: - other: "a community-specific reason" - desc: - other: "This question doesn't meet a community guideline." - multiple: - name: - other: "needs details or clarity" - desc: - other: "This question currently includes multiple questions in one. It should focus on one problem only." - other: - name: - other: "something else" - desc: - other: "This post requires another reason not listed above." - operation_type: - asked: - other: "asked" - answered: - other: "answered" - modified: - other: "modified" - notification: - action: - update_question: - other: "updated question" - answer_the_question: - other: "answered question" - update_answer: - other: "updated answer" - accept_answer: - other: "accepted answer" - comment_question: - other: "commented question" - comment_answer: - other: "commented answer" - reply_to_you: - other: "replied to you" - mention_you: - other: "mentioned you" - your_question_is_closed: - other: "Your question has been closed" - your_question_was_deleted: - other: "Your question has been deleted" - your_answer_was_deleted: - other: "Your answer has been deleted" - your_comment_was_deleted: - other: "Your comment has been deleted" -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comment - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to Answer - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name up to 30 characters - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username up to 30 characters - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to Answer - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: "After you've done that, click “Next” button." - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: display_name must be at 2 - 30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/i18n.yaml b/data/i18n/i18n.yaml deleted file mode 100644 index 7abb748db..000000000 --- a/data/i18n/i18n.yaml +++ /dev/null @@ -1,64 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# all support language -language_options: - - label: "English" - value: "en_US" - progress: 100 - - label: "Español" - value: "es_ES" - progress: 96 - - label: "Português(BR)" - value: "pt_BR" - progress: 96 - - label: "Português" - value: "pt_PT" - progress: 96 - - label: "Deutsch" - value: "de_DE" - progress: 96 - - label: "Français" - value: "fr_FR" - progress: 96 - - label: "日本語" - value: "ja_JP" - progress: 96 - - label: "Italiano" - value: "it_IT" - progress: 96 - - label: "Русский" - value: "ru_RU" - progress: 80 - - label: "简体中文" - value: "zh_CN" - progress: 100 - - label: "繁體中文" - value: "zh_TW" - progress: 47 - - label: "한국어" - value: "ko_KR" - progress: 73 - - label: "Tiếng Việt" - value: "vi_VN" - progress: 96 - - label: "Slovak" - value: "sk_SK" - progress: 45 - - label: "فارسی" - value: "fa_IR" - progress: 69 diff --git a/data/i18n/id_ID.yaml b/data/i18n/id_ID.yaml deleted file mode 100644 index 3928c6f39..000000000 --- a/data/i18n/id_ID.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Sukses. - unknown: - other: Kesalahan tidak diketahui. - request_format_error: - other: Permintaan tidak sah. - unauthorized_error: - other: Tidak diizinkan. - database_error: - other: Kesalahan data server. - forbidden_error: - other: Forbidden. - duplicate_request_error: - other: Duplicate submission. - action: - report: - other: Flag - edit: - other: Ubah - delete: - other: Hapus - close: - other: Tutup - reopen: - other: Buka kembali - forbidden_error: - other: Forbidden. - pin: - other: Pin - hide: - other: Unlist - unpin: - other: Unpin - show: - other: Daftar - invite_someone_to_answer: - other: Undang seseorang untuk menjawab - undelete: - other: Undelete - merge: - other: Merge - role: - name: - user: - other: Pengguna - admin: - other: Administrator - moderator: - other: Moderator - description: - user: - other: Default tanpa akses khusus. - admin: - other: Memiliki kontrol penuh atas situs. - moderator: - other: Memiliki kendali atas semua kiriman kecuali pengaturan administrator. - privilege: - level_1: - description: - other: Level 1 (less reputation required for private team, group) - level_2: - description: - other: Level 2 (low reputation required for startup community) - level_3: - description: - other: Level 3 (high reputation required for mature community) - level_custom: - description: - other: Custom Level - rank_question_add_label: - other: Tanyakan sesuatu - rank_answer_add_label: - other: Tulis jawaban - rank_comment_add_label: - other: Tulis komentar - rank_report_add_label: - other: Flag - rank_comment_vote_up_label: - other: Upvote comment - rank_link_url_limit_label: - other: Kirim lebih dari 2 tautan secara bersamaan - rank_question_vote_up_label: - other: Upvote question - rank_answer_vote_up_label: - other: Upvote answer - rank_question_vote_down_label: - other: Downvote question - rank_answer_vote_down_label: - other: Downvote answer - rank_invite_someone_to_answer_label: - other: Undang seseorang untuk menjawab - rank_tag_add_label: - other: Buat tag baru - rank_tag_edit_label: - other: Edit tag description (need to review) - rank_question_edit_label: - other: Edit other's question (need to review) - rank_answer_edit_label: - other: Edit other's answer (need to review) - rank_question_edit_without_review_label: - other: Edit other's question without review - rank_answer_edit_without_review_label: - other: Edit other's answer without review - rank_question_audit_label: - other: Review question edits - rank_answer_audit_label: - other: Review answer edits - rank_tag_audit_label: - other: Review tag edits - rank_tag_edit_without_review_label: - other: Edit tag description without review - rank_tag_synonym_label: - other: Manage tag synonyms - email: - other: Email - e_mail: - other: Email - password: - other: Kata sandi - pass: - other: Password - old_pass: - other: Current password - original_text: - other: This post - email_or_password_wrong_error: - other: '"Email" dan kata sandi tidak cocok.' - error: - common: - invalid_url: - other: URL salah. - status_invalid: - other: Invalid status. - password: - space_invalid: - other: Password tidak boleh mengandung spasi. - admin: - cannot_update_their_password: - other: You cannot modify your password. - cannot_edit_their_profile: - other: You cannot modify your profile. - cannot_modify_self_status: - other: You cannot modify your status. - email_or_password_wrong: - other: Email dan kata sandi tidak cocok. - answer: - not_found: - other: Jawaban tidak ditemukan. - cannot_deleted: - other: Tidak memiliki izin untuk menghapus. - cannot_update: - other: Tidak memiliki izin untuk memperbarui. - question_closed_cannot_add: - other: Questions are closed and cannot be added. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Tidak diizinkan untuk mengubah komentar. - not_found: - other: Komentar tidak ditemukan. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: Email telah terdaftar. - need_to_be_verified: - other: Email harus terverifikasi. - verify_url_expired: - other: URL verifikasi email telah kadaluwarsa, silahkan kirim ulang. - illegal_email_domain_error: - other: Email is not allowed from that email domain. Please use another one. - lang: - not_found: - other: Bahasa tidak ditemukan. - object: - captcha_verification_failed: - other: Captcha salah. - disallow_follow: - other: Anda tidak diizinkan untuk mengikuti. - disallow_vote: - other: Anda tisak diizinkan untuk melakukan vote. - disallow_vote_your_self: - other: Anda tidak dapat melakukan voting untuk ulasan Anda sendiri. - not_found: - other: Objek tidak ditemukan. - verification_failed: - other: Verifikasi gagal. - email_or_password_incorrect: - other: Email dan kata sandi tidak cocok. - old_password_verification_failed: - other: Verifikasi password lama, gagal - new_password_same_as_previous_setting: - other: Kata sandi baru sama dengan kata sandi yang sebelumnya. - already_deleted: - other: This post has been deleted. - meta: - object_not_found: - other: Meta object not found - question: - already_deleted: - other: This post has been deleted. - under_review: - other: Your post is awaiting review. It will be visible after it has been approved. - not_found: - other: Pertanyaan tidak ditemukan. - cannot_deleted: - other: Tidak memiliki izin untuk menghapus. - cannot_close: - other: Tidak diizinkan untuk menutup. - cannot_update: - other: Tidak diizinkan untuk memperbarui. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Reputation rank fail to meet the condition. - vote_fail_to_meet_the_condition: - other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. - no_enough_rank_to_operate: - other: You need at least {{.Rank}} reputation to do this. - report: - handle_failed: - other: Laporan penanganan gagal. - not_found: - other: Laporan tidak ditemukan. - tag: - already_exist: - other: Tag already exists. - not_found: - other: Tag tidak ditemukan. - recommend_tag_not_found: - other: Recommend tag is not exist. - recommend_tag_enter: - other: Silahkan isi setidaknya satu tag yang diperlukan. - not_contain_synonym_tags: - other: Tidak boleh mengandung Tag sinonim. - cannot_update: - other: Tidak memiliki izin untuk memperbaharui. - is_used_cannot_delete: - other: You cannot delete a tag that is in use. - cannot_set_synonym_as_itself: - other: Anda tidak bisa menetapkan sinonim dari tag saat ini dengan tag yang sama. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: The from name cannot be a email address. - theme: - not_found: - other: Tema tidak ditemukan. - revision: - review_underway: - other: Tidak dapat mengedit saat ini, sedang ada review versi pada antrian. - no_permission: - other: No permission to revise. - user: - external_login_missing_user_id: - other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. - external_login_unbinding_forbidden: - other: Please set a login password for your account before you remove this login. - email_or_password_wrong: - other: - other: Email dan kata sandi tidak cocok. - not_found: - other: Pengguna tidak ditemukan. - suspended: - other: Pengguna ini telah ditangguhkan. - username_invalid: - other: Nama pengguna tidak sesuai. - username_duplicate: - other: Nama pengguna sudah digunakan. - set_avatar: - other: Set avatar gagal. - cannot_update_your_role: - other: Anda tidak dapat mengubah peran anda sendiri. - not_allowed_registration: - other: Currently the site is not open for registration. - not_allowed_login_via_password: - other: Currently the site is not allowed to login via password. - access_denied: - other: Access denied - page_access_denied: - other: You do not have access to this page. - add_bulk_users_format_error: - other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Gagal membaca konfigurasi - database: - connection_failed: - other: Koneksi ke database gagal - create_table_failed: - other: Gagal membuat tabel - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - site_info: - config_not_found: - other: Site config not found. - badge: - object_not_found: - other: Badge object not found - reason: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude_or_abusive: - name: - other: rude or abusive - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - a_duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - placeholder: - other: Enter the existing question link - not_a_answer: - name: - other: not an answer - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." - no_longer_needed: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - something: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - placeholder: - other: Let us know specifically what you are concerned about - community_specific: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - not_clarity: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - looks_ok: - name: - other: looks OK - desc: - other: This post is good as-is and not low quality. - needs_edit: - name: - other: needs edit, and I did it - desc: - other: Improve and correct problems with this post yourself. - needs_close: - name: - other: needs close - desc: - other: A closed question can't answer, but still can edit, vote and comment. - needs_delete: - name: - other: needs delete - desc: - other: This post will be deleted. - question: - close: - duplicate: - name: - other: spam - desc: - other: Pertanyaan ini telah ditanyakan sebelumnya dan sudah ada jawabannya. - guideline: - name: - other: a community-specific reason - desc: - other: Pertanyaan ini tidak sesuai dengan pedoman komunitas. - multiple: - name: - other: membutuhkan detail atau kejelasan - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: lainnya - desc: - other: Posting ini membutuhkan alasan lain yang tidak tercantum di atas. - operation_type: - asked: - other: ditanyakan - answered: - other: dijawab - modified: - other: dimodifikasi - deleted_title: - other: Deleted question - questions_title: - other: Questions - tag: - tags_title: - other: Tags - no_description: - other: The tag has no description. - notification: - action: - update_question: - other: pertanyaan yang diperbaharui - answer_the_question: - other: pertanyaan yang dijawab - update_answer: - other: jawaban yang diperbaharui - accept_answer: - other: pertanyaan yanag diterima - comment_question: - other: pertanyaan yang dikomentari - comment_answer: - other: jawaban yang dikomentari - reply_to_you: - other: membalas Anda - mention_you: - other: menyebutmu - your_question_is_closed: - other: Pertanyaanmu telah ditutup - your_question_was_deleted: - other: Pertanyaanmu telah dihapus - your_answer_was_deleted: - other: Jawabanmu telah dihapus - your_comment_was_deleted: - other: Komentarmu telah dihapus - up_voted_question: - other: upvoted question - down_voted_question: - other: downvoted question - up_voted_answer: - other: upvoted answer - down_voted_answer: - other: downvoted answer - up_voted_comment: - other: upvoted comment - invited_you_to_answer: - other: invited you to answer - earned_badge: - other: You've earned the "{{.BadgeName}}" badge - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Confirm your new email address" - body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} answered your question" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_question: - title: - other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Password reset" - body: - other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - register: - title: - other: "[{{.SiteName}}] Confirm your new account" - body: - other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - test: - title: - other: "[{{.SiteName}}] Test Email" - body: - other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: - upvote: - other: upvote - upvoted: - other: upvoted - downvote: - other: downvote - downvoted: - other: downvoted - accept: - other: accept - accepted: - other: accepted - edit: - other: edit - review: - queued_post: - other: Queued post - flagged_post: - other: Flagged post - suggested_post_edit: - other: Suggested edits - reaction: - tooltip: - other: "{{ .Names }} and {{ .Count }} more..." - badge: - default_badges: - autobiographer: - name: - other: Autobiographer - desc: - other: Filled out profile information. - certified: - name: - other: Certified - desc: - other: Completed our new user tutorial. - editor: - name: - other: Editor - desc: - other: First post edit. - first_flag: - name: - other: First Flag - desc: - other: First flagged a post. - first_upvote: - name: - other: First Upvote - desc: - other: First up voted a post. - first_link: - name: - other: First Link - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: First Share - desc: - other: First shared a post. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Leave 5 comments. - new_user_of_the_month: - name: - other: New User of the Month - desc: - other: Outstanding contributions in their first month. - read_guidelines: - name: - other: Read Guidelines - desc: - other: Read the [community guidelines]. - reader: - name: - other: Reader - desc: - other: Read every answers in a topic with more than 10 answers. - welcome: - name: - other: Welcome - desc: - other: Received a up vote. - nice_share: - name: - other: Nice Share - desc: - other: Shared a post with 25 unique visitors. - good_share: - name: - other: Good Share - desc: - other: Shared a post with 300 unique visitors. - great_share: - name: - other: Great Share - desc: - other: Shared a post with 1000 unique visitors. - out_of_love: - name: - other: Out of Love - desc: - other: Used 50 up votes in a day. - higher_love: - name: - other: Higher Love - desc: - other: Used 50 up votes in a day 5 times. - crazy_in_love: - name: - other: Crazy in Love - desc: - other: Used 50 up votes in a day 20 times. - promoter: - name: - other: Promoter - desc: - other: Invited a user. - campaigner: - name: - other: Campaigner - desc: - other: Invited 3 basic users. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: Thank You - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Active member for a year, posted at least once. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Cara memformat - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Sebelumnya - next: Selanjutnya - page_title: - question: Pertanyaan - questions: Pertanyaan - tag: Tag - tags: Tags - tag_wiki: tag wiki - create_tag: Create Tag - edit_tag: Ubah Tag - ask_a_question: Create Question - edit_question: Sunting Pertanyaan - edit_answer: Sunting jawaban - search: Cari - posts_containing: Postingan mengandung - settings: Pengaturan - notifications: Pemberitahuan - login: Log In - sign_up: Daftar - account_recovery: Pemulihan Akun - account_activation: Aktivasi Akun - confirm_email: Konfirmasi email - account_suspended: Akun Ditangguhkan - admin: Admin - change_email: Modifikasi email - install: Instalasi Answer - upgrade: Meng-upgrade Answer - maintenance: Pemeliharaan Website - users: Pengguna - oauth_callback: Processing - http_404: HTTP Error 404 - http_50X: HTTP Error 500 - http_403: HTTP Error 403 - logout: Log Out - posts: Posts - notifications: - title: Pemberitahuan - inbox: Kotak Masuk - achievement: Pencapaian - new_alerts: New alerts - all_read: Tandai Semua Jika Sudah Dibaca - show_more: Tampilkan lebih banyak - someone: Someone - inbox_type: - all: All - posts: Posts - invites: Invites - votes: Votes - answer: Answer - question: Question - badge_award: Badge - suspended: - title: Akun Anda telah ditangguhkan - until_time: "Akun anda ditangguhkan sampai {{ time }}." - forever: Pengguna ini ditangguhkan selamanya. - end: Anda tidak sesuai dengan syarat pedoman komunitas. - contact_us: Contact us - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Diagram alir - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Tambahkan sample code - form: - fields: - code: - label: Code - msg: - empty: Code tidak boleh kosong. - language: - label: Language - placeholder: Deteksi otomatis - btn_cancel: Batal - btn_confirm: Tambah - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal rule - image: - text: Gambar - add_image: Tambahkan gambar - tab_image: Unggah gambar - form_image: - fields: - file: - label: Image file - btn: Pilih gambar - msg: - empty: File tidak boleh kosong. - only_image: Hanya file Gambar yang diperbolehkan. - max_size: File size cannot exceed {{size}} MB. - desc: - label: Description - tab_url: URL gambar - form_url: - fields: - url: - label: URL gambar - msg: - empty: URL gambar tidak boleh kosong. - name: - label: Description - btn_cancel: Batal - btn_confirm: Tambah - uploading: Sedang mengunggah - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description - btn_cancel: Batal - btn_confirm: Tambah - ordered_list: - text: Numbered list - unordered_list: - text: Bulleted list - table: - text: Table - heading: Heading - cell: Cell - file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: Postingan ini saya tutup sebagai... - btn_cancel: Batal - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - not_a_url: URL format is incorrect. - url_not_match: URL origin does not match the current website. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description - revision: - label: Revision - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_cancel: Cancel - btn_submit: Submit - btn_post: Post new tag - tag_info: - created_at: Dibuat - edited_at: Disunting - history: Riwayat - synonyms: - title: Sinonim - text: Tag berikut akan dipetakan ulang ke - empty: Sinonim tidak ditemukan. - btn_add: Tambahkan sinonim - btn_edit: Sunting - btn_save: Simpan - synonyms_text: Tag berikut akan dipetakan ulang ke - delete: - title: Hapus tagar ini - tip_with_posts: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - tip_with_synonyms: >- -

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        - tip: Are you sure you wish to delete? - close: Tutup - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Ubah Tag - default_reason: Sunting tag - default_first_reason: Add tag - btn_save_edits: Simpan suntingan - btn_cancel: Batal - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: sekarang - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: jam - day: hari - hours: hours - days: days - month: month - months: months - year: year - reaction: - heart: heart - smile: smile - frown: frown - btn_label: add or remove reactions - undo_emoji: undo {{ emoji }} reaction - react_emoji: react with {{ emoji }} - unreact_emoji: unreact with {{ emoji }} - comment: - btn_add_comment: Tambahkan Komentar - reply_to: Balas ke - btn_reply: Balas - btn_edit: Sunting - btn_delete: Hapus - btn_flag: Flag - btn_save_edits: Simpan suntingan - btn_cancel: Batal - show_more: "{{count}} more comments" - tip_question: >- - Gunakan komentar untuk meminta informasi lebih lanjut atau menyarankan perbaikan. Hindari menjawab pertanyaan di komentar. - tip_answer: >- - Gunakan komentar untuk membalas pengguna lain atau memberi tahu mereka tentang perubahan. Jika Anda menambahkan informasi baru, cukup edit posting Anda. - tip_vote: It adds something useful to the post - edit_answer: - title: Sunting jawaban - default_reason: Edit jawaban - default_first_reason: Add answer - form: - fields: - revision: - label: Revisi - answer: - label: Jawaban - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: Newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - wiki: Wiki - ask: - title: Create Question - edit_title: Edit Question - default_reason: Edit question - default_first_reason: Create question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: What's your topic? Be specific. - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Pengguna - badges: Badges - profile: Profil - setting: Pengaturan - logout: Keluar - admin: Admin - review: Ulasan - bookmark: Bookmarks - moderation: Moderation - search: - placeholder: Cari - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Ubah - loading: sedang memuat... - pic_auth_code: - title: Capthcha - placeholder: Masukkan teks di atas - msg: - empty: Captcha tidak boleh kosong. - inactive: - first: >- - Kamu hampir selesai! Kami telah mengirimkan email aktivasi ke {{mail}}. Silakan ikuti petunjuk dalam email untuk mengaktifkan akun Anda. - info: "Jika tidak ada email masuk, mohon periksa folder spam Anda." - another: >- - Kami telah mengirimkan email aktivasi lain kepada Anda di {{mail}}. Mungkin butuh beberapa menit untuk tiba; pastikan untuk memeriksa folder spam Anda. - btn_name: Kirim ulang email aktivasi - change_btn_name: Ganti email - msg: - empty: Tidak bisa kosong. - resend_email: - url_label: Are you sure you want to resend the activation email? - url_text: You can also give the activation link above to the user. - login: - login_to_continue: Masuk untuk melanjutkan - info_sign: Belum punya akun? <1>Daftar - info_login: Sudah punya akun? <1>Masuk - agreements: Dengan mendaftar, Anda menyetujui <1>kebijakan privasi dan <3>persyaratan layanan. - forgot_pass: Lupa password? - name: - label: Nama - msg: - empty: Nama tidak boleh kosong. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email tidak boleh kosong. - password: - label: Kata sandi - msg: - empty: Kata sandi tidak boleh kosong. - different: Kata sandi yang dimasukkan tidak sama - account_forgot: - page_title: Lupa kata sandi Anda - btn_name: Tulis email pemulihan - send_success: >- - Jika akun cocok dengan {{mail}}, Anda akan segera menerima email berisi petunjuk tentang cara menyetel ulang sandi. - email: - label: Email - msg: - empty: Email tidak boleh kosong. - change_email: - btn_cancel: Batal - btn_update: Perbarui alamat email - send_success: >- - Jika akun cocok dengan {{mail}}, Anda akan segera menerima email berisi petunjuk tentang cara menyetel ulang sandi. - email: - label: New email - msg: - empty: Email tidak boleh kosong. - oauth: - connect: Connect with {{ auth_name }} - remove: Remove {{ auth_name }} - oauth_bind_email: - subtitle: Add a recovery email to your account. - btn_update: Update email address - email: - label: Email - msg: - empty: Email cannot be empty. - modal_title: Email already existes. - modal_content: This email address already registered. Are you sure you want to connect to the existing account? - modal_cancel: Change email - modal_confirm: Connect to the existing account - password_reset: - page_title: Atur ulang kata sandi - btn_name: Atur ulang kata sandi saya - reset_success: >- - Anda berhasil mengubah kata sandi Anda; Anda akan dialihkan ke halaman login. - link_invalid: >- - Maaf, link setel ulang sandi ini sudah tidak valid. Mungkin kata sandi Anda sudah diatur ulang? - to_login: Lanjutkan ke halaman Login - password: - label: Kata sandi - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm new password - settings: - page_title: Settings - goto_modify: Go to modify - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile image - gravatar: Gravatar - gravatar_text: You can change image on - custom: Custom - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About me - website: - label: Website - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location - placeholder: "City, Country" - notification: - heading: Email Notifications - turn_on: Turn on - inbox: - label: Inbox notifications - description: Answers to your questions, comments, invites, and more. - all_new_question: - label: All new questions - description: Get notified of all new questions. Up to 50 questions per week. - all_new_question_for_following_tags: - label: All new questions for following tags - description: Get notified of new questions for following tags. - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - pass: - label: Current password - msg: Password cannot be empty. - password_title: Password - current_pass: - label: Current password - msg: - empty: Current password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New password - pass_confirm: - label: Confirm new password - interface: - heading: Interface - lang: - label: Interface language - text: Bahasa antarmuka pengguna. Itu akan berubah ketika Anda me-refresh halaman. - my_logins: - title: My logins - label: Log in or sign up on this site using these accounts. - modal_title: Remove login - modal_content: Are you sure you want to remove this login from your account? - modal_confirm_btn: Remove - remove_success: Removed successfully - toast: - update: pembaruan sukses - update_password: Kata sandi berhasil diganti. - flag_success: Terima kasih telah menandai. - forbidden_operate_self: Dilarang melakukan operasi ini pada diri sendiri - review: Revisi Anda akan ditampilkan setelah ditinjau. - sent_success: Sent successfully - related_question: - title: Related - answers: jawaban - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: People Asked - desc: Select people who you think might know the answer. - invite: Invite to answer - add: Add people - search: Search people - question_detail: - action: Action - created: Created - Asked: Ditanyakan - asked: ditanyakan - update: Diubah - Edited: Edited - edit: disunting - commented: commented - Views: Dilihat - Follow: Ikuti - Following: Mengikuti - follow_tip: Follow this question to receive notifications - answered: dijawab - closed_in: Ditutup pada - show_exist: Gunakan pertanyaan yang sudah ada. - useful: Useful - question_useful: It is useful and clear - question_un_useful: It is unclear or not useful - question_bookmark: Bookmark this question - answer_useful: It is useful - answer_un_useful: It is not useful - answers: - title: Jawaban - score: Nilai - newest: Terbaru - oldest: Oldest - btn_accept: Terima - btn_accepted: Diterima - write_answer: - title: Jawaban Anda - edit_answer: Edit my existing answer - btn_name: Kirimkan jawaban Anda - add_another_answer: Tambahkan jawaban lain - confirm_title: Lanjutkan menjawab - continue: Lanjutkan - confirm_info: >- -

        Yakin ingin menambahkan jawaban lain?

        Sebagai gantinya, Anda dapat menggunakan tautan edit untuk menyaring dan menyempurnakan jawaban anda.

        - empty: Jawaban tidak boleh kosong. - characters: content must be at least 6 characters in length. - tips: - header_1: Thanks for your answer - li1_1: Please be sure to answer the question. Provide details and share your research. - li1_2: Back up any statements you make with references or personal experience. - header_2: But avoid ... - li2_1: Asking for help, seeking clarification, or responding to other answers. - reopen: - confirm_btn: Reopen - title: Buka kembali postingan ini - content: Kamu yakin ingin membuka kembali? - list: - confirm_btn: List - title: List this post - content: Are you sure you want to list? - unlist: - confirm_btn: Unlist - title: Unlist this post - content: Are you sure you want to unlist? - pin: - title: Pin this post - content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. - confirm_btn: Pin - delete: - title: Hapus pos ini - question: >- - Kami tidak menyarankan menghapus pertanyaan dengan jawaban karena hal itu menghilangkan pengetahuan ini dari pembaca di masa mendatang.

        Penghapusan berulang atas pertanyaan yang dijawab dapat mengakibatkan akun Anda diblokir untuk bertanya. Apakah Anda yakin ingin menghapus? - answer_accepted: >- -

        Kami tidak menyarankan menghapus jawaban yang diterima karena hal itu menghilangkan pengetahuan ini dari pembaca di masa mendatang.

        Penghapusan berulang dari jawaban yang diterima dapat menyebabkan akun Anda diblokir dari menjawab. Apakah Anda yakin ingin menghapus? - other: Anda yakin ingin menghapusnya? - tip_answer_deleted: Jawaban ini telah dihapus - undelete_title: Undelete this post - undelete_desc: Are you sure you wish to undelete? - btns: - confirm: Konfirmasi - cancel: Batal - edit: Edit - save: Simpan - delete: Hapus - undelete: Undelete - list: List - unlist: Unlist - unlisted: Unlisted - login: Masuk - signup: Daftar - logout: Keluar - verify: Verifikasi - create: Create - approve: Approve - reject: Reject - skip: Skip - discard_draft: Discard draft - pinned: Pinned - all: All - question: Question - answer: Answer - comment: Comment - refresh: Refresh - resend: Resend - deactivate: Deactivate - active: Active - suspend: Suspend - unsuspend: Unsuspend - close: Close - reopen: Reopen - ok: OK - light: Light - dark: Dark - system_setting: System setting - default: Default - reset: Reset - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignore - submit: Submit - normal: Normal - closed: Closed - deleted: Deleted - deleted_permanently: Deleted permanently - pending: Pending - more: More - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - counts_loading: "... Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post. - modal_confirm: - title: Error... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - x_posts: "{{ count }} Posts" - questions: Questions - answers: Jawaban - newest: Terbaru - active: Aktif - hot: Hot - frequent: Frequent - recommend: Recommend - score: Nilai - unanswered: Belum dijawab - modified: diubah - answered: dijawab - asked: ditanyakan - closed: ditutup - follow_a_tag: Ikuti tagar - more: Lebih - personal: - overview: Ringkasan - answers: Jawaban - answer: jawaban - questions: Pertanyaan - question: pertanyaan - bookmarks: Bookmarks - reputation: Reputasi - comments: Komentar - votes: Vote - badges: Badges - newest: Terbaru - score: Nilai - edit_profile: Edit profile - visited_x_days: "Dikunjungi {{ count }} hari" - viewed: Dilihat - joined: Bergabung - comma: "," - last_login: Dilihat - about_me: Tentang Saya - about_me_empty: "// Hello, World !" - top_answers: Jawaban terpopuler - top_questions: Pertanyaan terpopuler - stats: Statistik - list_empty: Postingan tidak ditemukan.
        Mungkin Anda ingin memilih tab lain? - content_empty: No posts found. - accepted: Diterima - answered: dijawab - asked: ditanyakan - downvoted: downvoted - mod_short: MOD - mod_long: Moderator - x_reputation: reputasi - x_votes: vote diterima - x_answers: jawaban - x_questions: pertanyaan - recent_badges: Recent Badges - install: - title: Installation - next: Selanjutnya - done: Selesai - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please choose a language - db_type: - label: Database engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database host - placeholder: "db:3306" - msg: Database host cannot be empty. - db_name: - label: Database name - placeholder: answer - msg: Database name cannot be empty. - db_file: - label: Database file - placeholder: /data/answer.db - msg: Database file cannot be empty. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site name - msg: Site name cannot be empty. - msg_max_length: Site name must be at maximum 30 characters in length. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - max_length: Site URL must be at maximum 512 characters in length. - contact_email: - label: Contact email - text: Email address of key contact responsible for this site. - msg: - empty: Contact email cannot be empty. - incorrect: Contact email incorrect format. - login_required: - label: Private - switch: Login required - text: Only logged in users can access this community. - admin_name: - label: Name - msg: Name cannot be empty. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - msg_min_length: Password must be at least 8 characters in length. - msg_max_length: Password must be at maximum 32 characters in length. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Koneksi ke database gagal - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_error: - http_error: HTTP Error {{ code }} - desc_403: You don't have permission to access this page. - desc_404: Unfortunately, this page doesn't exist. - desc_50X: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dasbor - contents: Konten - questions: Pertanyaan - answers: Jawaban - users: Pengguna - badges: Badges - flags: Flags - settings: Pengaturan - general: Umum - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - terms: Terms - tos: Terms of Service - privacy: Privasi - seo: SEO - customize: Kostumisasi - themes: Tema - login: Masuk - privileges: Privileges - plugins: Plugins - installed_plugins: Installed Plugins - apperance: Appearance - website_welcome: Welcome to {{site_name}} - user_center: - login: Login - qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. - login_failed_email_tip: Login failed, please allow this app to access your email information before try again. - badges: - modal: - title: Congratulations - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - admin: - admin_header: - title: Admin - dashboard: - title: Dasbor - welcome: Welcome to Admin! - site_statistics: Site statistics - questions: "Pertanyaan:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "Jawaban:" - comments: "Komentar:" - votes: "Vote:" - users: "Users:" - flags: "Flags:" - reviews: "Reviews:" - site_health: Site health - version: "Versi:" - https: "HTTPS:" - upload_folder: "Upload folder:" - run_mode: "Running mode:" - private: Private - public: Public - smtp: "SMTP:" - timezone: "Zona Waktu:" - system_info: System info - go_version: "Go version:" - database: "Database:" - database_size: "Database size:" - storage_used: "Penyimpanan yang terpakai:" - uptime: "Uptime:" - links: Links - plugins: Plugins - github: GitHub - blog: Blog - contact: Contact - forum: Forum - documents: Dokumen - feedback: Masukan - support: Dukungan - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - writable: Writable - not_writable: Not writable - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - flagged_type: Flagged {{ type }} - created: Created - action: Action - review: Review - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - edit_profile_modal: - title: Edit profile - form: - fields: - display_name: - label: Display name - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Invalid Email Address. - edit_success: Edited successfully - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - users: - label: Bulk add user - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separate “name, email, password” with commas. One user per line. - msg: "Please enter the user's email, one per line." - display_name: - label: Display name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Status - role: Role - action: Action - change: Ubah - all: Semua - staff: Staf - more: More - inactive: Tidak Aktif - suspended: Ditangguhkan - deleted: Dihapus - normal: Normal - Moderator: Moderator - Admin: Admin - User: Pengguna - filter: - placeholder: "Filter berdasarkan nama, user:id" - set_new_password: Atur password baru - edit_profile: Edit profile - change_status: Ubah status - change_role: Ubah role - show_logs: Tampilkan log - add_user: Tambahkan pengguna - deactivate_user: - title: Deactivate user - content: An inactive user must re-validate their email. - delete_user: - title: Delete this user - content: Are you sure you want to delete this user? This is permanent! - remove: Remove their content - label: Remove all questions, answers, comments, etc. - text: Don’t check this if you wish to only delete the user’s account. - suspend_user: - title: Suspend this user - content: A suspended user can't log in. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Pertanyaan - unlisted: Unlisted - post: Post - votes: Vote - answers: Jawaban - created: Dibuat - status: Status - action: Action - change: Ubah - pending: Pending - filter: - placeholder: "Filter berdasarkan judul, question:id" - answers: - page_title: Jawaban - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short site description - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site description - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - check_update: - label: Software updates - text: Automatically check for updates - interface: - page_title: Interface - language: - label: Interface language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: From email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Enkripsi - msg: Enkripsi tidak boleh kosong. - text: For most servers SSL is the recommended option. - ssl: SSL - tls: TLS - none: Tidak ada - smtp_port: - label: SMTP port - msg: SMTP port must be number 1 ~ 65535. - text: Port untuk server email Anda. - smtp_username: - label: SMTP username - msg: Nama Pengguna SMTP tidak boleh kosong. - smtp_password: - label: SMTP password - msg: Password SMTP tidak boleh kosong. - test_email_recipient: - label: Test email recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile logo - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square icon - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Write - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Each user can only write one answer for each question - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Recommend tags - text: "Recommend tags will show in the dropdown list by default." - msg: - contain_reserved: "recommended tags cannot contain reserved tags" - required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved tags - text: "Reserved tags can only be used by moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - color_scheme: - label: Color scheme - navbar_style: - label: Navbar background style - primary_color: - label: Primary color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: > - - head: - label: Head - text: > - - header: - label: Header - text: > - - footer: - label: Footer - text: This will insert before </body>. - sidebar: - label: Sidebar - text: This will insert in sidebar. - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - email_registration: - title: Email registration - label: Allow email registration - text: Turn off to prevent anyone creating new account through email. - allowed_email_domains: - title: Allowed email domains - text: Email domains that users must register accounts with. One domain per line. Ignored when empty. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - password_login: - title: Password login - label: Allow email and password login - text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." - installed_plugins: - title: Installed Plugins - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. - filter: - all: All - active: Active - inactive: Inactive - outdated: Outdated - plugins: - label: Plugins - text: Select an existing plugin. - name: Name - version: Version - status: Status - action: Action - deactivate: Deactivate - activate: Activate - settings: Settings - settings_users: - title: Users - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar Base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - profile_editable: - title: Profile editable - allow_update_display_name: - label: Allow users to change their display name - allow_update_username: - label: Allow users to change their username - allow_update_avatar: - label: Allow users to change their profile image - allow_update_bio: - label: Allow users to change their about me - allow_update_website: - label: Allow users to change their website - allow_update_location: - label: Allow users to change their location - privilege: - title: Privileges - level: - label: Reputation required level - text: Choose the reputation required for the privileges - msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 - badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate - filter: - placeholder: Filter by name, badge:id - group: Group - inactive: Inactive - name: Name - show_logs: Show logs - status: Status - title: Badges - form: - optional: (optional) - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - select: Select - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - approve_revision_tip: Do you approve this revision? - approve_flag_tip: Do you approve this flag? - approve_post_tip: Do you approve this post? - approve_user_tip: Do you approve this user? - suggest_edits: Suggested edits - flag_post: Flag post - flag_user: Flag user - queued_post: Queued post - queued_user: Queued user - filter_label: Type - reputation: reputation - flag_post_type: Flagged this post as {{ type }}. - flag_user_type: Flagged this user as {{ type }}. - edit_post: Edit post - list_post: List post - unlist_post: Unlist post - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - pin: pinned - unpin: unpinned - show: listed - hide: unlisted - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores this week - users_with_the_most_vote: Users who voted the most this week - staffs: Our community staff - reputation: reputation - votes: votes - prompt: - leave_page: Are you sure you want to leave the page? - changes_not_save: Your changes may not be saved. - draft: - discard_confirm: Are you sure you want to discard your draft? - messages: - post_deleted: This post has been deleted. - post_cancel_deleted: This post has been undeleted. - post_pin: This post has been pinned. - post_unpin: This post has been unpinned. - post_hide_list: This post has been hidden from list. - post_show_list: This post has been shown to list. - post_reopen: This post has been reopened. - post_list: This post has been listed. - post_unlist: This post has been unlisted. - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/it_IT.yaml b/data/i18n/it_IT.yaml deleted file mode 100644 index ddc9723c6..000000000 --- a/data/i18n/it_IT.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Successo. - unknown: - other: Errore sconosciuto. - request_format_error: - other: Il formato della richiesta non è valido. - unauthorized_error: - other: Non autorizzato. - database_error: - other: Errore nel server dati. - forbidden_error: - other: Vietato. - duplicate_request_error: - other: Duplica invio. - action: - report: - other: Segnala - edit: - other: Modifica - delete: - other: Cancella - close: - other: Chiudi - reopen: - other: Riapri - forbidden_error: - other: Vietato. - pin: - other: Fissa sul profilo - hide: - other: Rimuovi dall'elenco - unpin: - other: Stacca dal profilo - show: - other: Aggiungi all'elenco - invite_someone_to_answer: - other: Modifica - undelete: - other: Ripristina - merge: - other: Unisci - role: - name: - user: - other: Utente - admin: - other: Amministratore - moderator: - other: Moderatore - description: - user: - other: Predefinito senza alcun accesso speciale. - admin: - other: Avere il pieno potere di accedere al sito. - moderator: - other: Ha accesso a tutti i post tranne le impostazioni di amministratore. - privilege: - level_1: - description: - other: 'Livello 1 (per team o gruppi privati: richiesta reputazione limitata)' - level_2: - description: - other: 'Livello 2 (per startup community: richiesta reputazione scarsa)' - level_3: - description: - other: 'Livello 3 (per community riconosciute: richiesta reputazione alta)' - level_custom: - description: - other: Livello personalizzato - rank_question_add_label: - other: Fai una domanda - rank_answer_add_label: - other: Scrivi una risposta - rank_comment_add_label: - other: Scrivi un commento - rank_report_add_label: - other: Segnala - rank_comment_vote_up_label: - other: Approva commento - rank_link_url_limit_label: - other: Pubblica più di 2 link alla volta - rank_question_vote_up_label: - other: Approva domanda - rank_answer_vote_up_label: - other: Approva risposta - rank_question_vote_down_label: - other: Disapprova domanda - rank_answer_vote_down_label: - other: Disapprova risposta - rank_invite_someone_to_answer_label: - other: Invita qualcuno a rispondere - rank_tag_add_label: - other: Crea un nuovo tag - rank_tag_edit_label: - other: Modifica descrizione tag (necessità di revisione) - rank_question_edit_label: - other: Modifica la domanda di altri (necessità di revisione) - rank_answer_edit_label: - other: Modifica la risposta di altri (necessità di revisione) - rank_question_edit_without_review_label: - other: Modifica la domanda di altri senza bisogno di revisione - rank_answer_edit_without_review_label: - other: Modifica la risposta di altri senza bisogno di revisione - rank_question_audit_label: - other: Rivedi modifiche alla domanda - rank_answer_audit_label: - other: Rivedi modifiche alla risposta - rank_tag_audit_label: - other: Esamina le modifiche ai tag - rank_tag_edit_without_review_label: - other: Modifica la descrizione del tag senza necessità di revisione - rank_tag_synonym_label: - other: Gestisci sinonimi dei tag - email: - other: E-mail - e_mail: - other: E-mail - password: - other: Chiave di accesso - pass: - other: Password - old_pass: - other: Password attuale - original_text: - other: Questo post - email_or_password_wrong_error: - other: Email o password errati. - error: - common: - invalid_url: - other: URL non valido. - status_invalid: - other: Status non valido. - password: - space_invalid: - other: La password non può contenere spazi. - admin: - cannot_update_their_password: - other: Non è possibile modificare la password. - cannot_edit_their_profile: - other: Non è possibile modificare il profilo. - cannot_modify_self_status: - other: Non è possibile modificare il tuo status. - email_or_password_wrong: - other: Email o password errati. - answer: - not_found: - other: Risposta non trovata. - cannot_deleted: - other: Permesso per cancellare mancante. - cannot_update: - other: Nessun permesso per l'aggiornamento. - question_closed_cannot_add: - other: Le domande sono chiuse e non possono essere aggiunte. - content_cannot_empty: - other: Il contenuto della risposta non può essere vuoto. - comment: - edit_without_permission: - other: Non si hanno di privilegi sufficienti per modificare il commento. - not_found: - other: Commento non trovato. - cannot_edit_after_deadline: - other: Il tempo per editare è scaduto. - content_cannot_empty: - other: Il commento non può essere vuoto. - email: - duplicate: - other: Email già esistente. - need_to_be_verified: - other: L'email deve essere verificata. - verify_url_expired: - other: L'url di verifica email è scaduto, si prega di reinviare l'email. - illegal_email_domain_error: - other: L'email non è consentita da quel dominio di posta elettronica. Si prega di usarne un altro. - lang: - not_found: - other: File lingua non trovato. - object: - captcha_verification_failed: - other: Captcha errato. - disallow_follow: - other: Non sei autorizzato a seguire - disallow_vote: - other: non sei autorizzato a votare - disallow_vote_your_self: - other: Non puoi votare un tuo post! - not_found: - other: oggetto non trovato - verification_failed: - other: verifica fallita - email_or_password_incorrect: - other: email o password incorretti - old_password_verification_failed: - other: la verifica della vecchia password è fallita - new_password_same_as_previous_setting: - other: La nuova password è identica alla precedente - already_deleted: - other: Questo post è stato eliminato. - meta: - object_not_found: - other: Meta oggetto non trovato - question: - already_deleted: - other: Questo post è stato eliminato. - under_review: - other: Il tuo post è in attesa di revisione. Sarà visibile dopo essere stato approvato. - not_found: - other: domanda non trovata - cannot_deleted: - other: Permesso per cancellare mancante. - cannot_close: - other: Nessun permesso per chiudere. - cannot_update: - other: Nessun permesso per l'aggiornamento. - content_cannot_empty: - other: Il contenuto non può essere vuoto. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Il rango di reputazione non soddisfa le condizioni. - vote_fail_to_meet_the_condition: - other: Grazie per il feedback. Hai bisogno di almeno una reputazione {{.Rank}} per votare. - no_enough_rank_to_operate: - other: Hai bisogno di almeno una reputazione {{.Rank}} per fare questo. - report: - handle_failed: - other: Gestione del report fallita - not_found: - other: Report non trovato - tag: - already_exist: - other: Tag già esistente. - not_found: - other: Etichetta non trovata - recommend_tag_not_found: - other: Il tag consigliato non esiste. - recommend_tag_enter: - other: Inserisci almeno un tag. - not_contain_synonym_tags: - other: Non deve contenere tag sinonimi. - cannot_update: - other: Nessun permesso per l'aggiornamento. - is_used_cannot_delete: - other: Non è possibile eliminare un tag in uso. - cannot_set_synonym_as_itself: - other: Non puoi impostare il sinonimo del tag corrente come se stesso. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: Il mittente non può essere un indirizzo email. - theme: - not_found: - other: tema non trovato - revision: - review_underway: - other: Non è possibile modificare al momento, c'è una versione nella coda di revisione. - no_permission: - other: Non è permessa la revisione. - user: - external_login_missing_user_id: - other: La piattaforma di terze parti non fornisce un utente ID unico, quindi non è possibile effettuare il login. Si prega di contattare l'amministratore del sito web. - external_login_unbinding_forbidden: - other: Per favore imposta una password di login per il tuo account prima di rimuovere questo accesso. - email_or_password_wrong: - other: - other: Email o password errati - not_found: - other: utente non trovato - suspended: - other: utente sospeso - username_invalid: - other: utente non valido - username_duplicate: - other: Nome utente già in uso - set_avatar: - other: Inserimento dell'Avatar non riuscito. - cannot_update_your_role: - other: Non puoi modificare il tuo ruolo. - not_allowed_registration: - other: Attualmente il sito non è aperto per la registrazione. - not_allowed_login_via_password: - other: Attualmente non è consentito accedere al sito tramite password. - access_denied: - other: Accesso negato - page_access_denied: - other: Non hai accesso a questa pagina. - add_bulk_users_format_error: - other: "Errore {{.Field}} formato vicino a '{{.Content}}' alla riga {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "Il numero di utenti che aggiungi contemporaneamente dovrebbe essere compreso tra 1 e {{.MaxAmount}}." - status_suspended_forever: - other: "Questo utente è stato sospeso per sempre. Questo utente non soddisfa le linee guida della comunità." - status_suspended_until: - other: "Questo utente è stato sospeso fino a {{.SuspendedUntil}}. Questo utente non soddisfa le linee guida della comunità." - status_deleted: - other: "Utente eliminato." - status_inactive: - other: "L'utente è inattivo." - config: - read_config_failed: - other: Configurazione lettura fallita - database: - connection_failed: - other: Connessione al database fallita - create_table_failed: - other: Creazione tabella non riuscita - install: - create_config_failed: - other: Impossibile creare il file config.yaml. - upload: - unsupported_file_format: - other: Formato file non supportato. - site_info: - config_not_found: - other: Configurazione del sito non trovata. - badge: - object_not_found: - other: Oggetto badge non trovato - reason: - spam: - name: - other: Spam - desc: - other: "Questo post è una pubblicità o spam. Non è utile o rilevante per l'argomento attuale.\n" - rude_or_abusive: - name: - other: scortese o offensivo - desc: - other: "Una persona ragionevole troverebbe questo contenuto inappropriato per un discorso rispettoso." - a_duplicate: - name: - other: duplicato - desc: - other: Questa domanda è già stata posta e ha già una risposta. - placeholder: - other: Inserisci il link alla domanda esistente - not_a_answer: - name: - other: Non è una risposta - desc: - other: "Questo è stato pubblicato come una risposta, ma non tenta di rispondere alla domanda. Dovrebbe forse essere una modifica, un commento, un'altra domanda,o cancellato del tutto." - no_longer_needed: - name: - other: Non più necessario - desc: - other: Questo commento è obsoleto, informale o non rilevante per questo post. - something: - name: - other: Qualcos'altro - desc: - other: Questo post richiede l'attenzione dello staff per un altro motivo non elencato sopra. - placeholder: - other: Facci sapere nello specifico cosa ti preoccupa - community_specific: - name: - other: Un motivo legato alla community - desc: - other: Questa domanda non soddisfa le linee guida della community. - not_clarity: - name: - other: Richiede maggiori dettagli o chiarezza - desc: - other: Questa domanda include più domande in una. Dovrebbe concentrarsi su un unico problema. - looks_ok: - name: - other: sembra OK - desc: - other: Questo post è corretto così com'è e non è di bassa qualità. - needs_edit: - name: - other: Necessita di modifiche che ho effettuato - desc: - other: Migliora e correggi tu stesso i problemi di questo post. - needs_close: - name: - other: necessita di chiusura - desc: - other: A una domanda chiusa non è possibile rispondere, ma è comunque possibile modificare, votare e commentare. - needs_delete: - name: - other: Necessario eliminare - desc: - other: Questo post verrà eliminato. - question: - close: - duplicate: - name: - other: posta indesiderata - desc: - other: Questa domanda è già stata posta e ha già una risposta. - guideline: - name: - other: motivo legato alla community - desc: - other: Questa domanda non soddisfa le linee guida della comunità. - multiple: - name: - other: richiede maggiori dettagli o chiarezza - desc: - other: Questa domanda attualmente include più domande in uno. Dovrebbe concentrarsi su un solo problema. - other: - name: - other: altro - desc: - other: Questo articolo richiede un'altro motivo non listato sopra. - operation_type: - asked: - other: chiesto - answered: - other: Risposto - modified: - other: Modificato - deleted_title: - other: "\nDomanda cancellata" - questions_title: - other: Domande - tag: - tags_title: - other: Tags - no_description: - other: Il tag non ha descrizioni. - notification: - action: - update_question: - other: domanda aggiornata - answer_the_question: - other: domanda risposta - update_answer: - other: risposta aggiornata - accept_answer: - other: risposta accettata - comment_question: - other: domanda commentata - comment_answer: - other: risposta commentata - reply_to_you: - other: hai ricevuto risposta - mention_you: - other: sei stato menzionato - your_question_is_closed: - other: la tua domanda è stata chiusa - your_question_was_deleted: - other: la tua domanda è stata rimossa - your_answer_was_deleted: - other: la tua risposta è stata rimossa - your_comment_was_deleted: - other: il tuo commento è stato rimosso - up_voted_question: - other: domanda approvata - down_voted_question: - other: domanda scartata - up_voted_answer: - other: risposta approvata - down_voted_answer: - other: risposta sfavorevole - up_voted_comment: - other: commento approvato - invited_you_to_answer: - other: sei invitato a rispondere - earned_badge: - other: Hai ottenuto il badge "{{.BadgeName}}" - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Conferma il tuo nuovo indirizzo email" - body: - other: "Conferma il tuo nuovo indirizzo email per {{.SiteName}} cliccando sul seguente link:
        \n{{.ChangeEmailUrl}}

        \n\nSe non hai richiesto questa modifica, ignora questa email.

        \n\n--
        \nNota: Si tratta di un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} ha risposto alla tua domanda" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nVisualizza su {{.SiteName}}

        \n\n--
        \nNota: Si tratta di un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata.

        \n\nCancellazione" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} ti ha invitato a rispondere" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Penso che tu possa sapere la risposta.

        \nVisualizza su {{.SiteName}}

        \n\n--
        \nNota: Questa è un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata.

        \n\nCancellazione" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} ha commentato il tuo post" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nVisualizza su {{.SiteName}}

        \n\n--
        \nNota: Si tratta di un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata.

        \n\nCancellazione" - new_question: - title: - other: "[{{.SiteName}}] Nuova domanda: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNota: Si tratta di un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non sarà visualizzata.

        \n\nCancellati" - pass_reset: - title: - other: "[{{.SiteName }}] Reimpostazione della password" - body: - other: "Qualcuno ha chiesto di reimpostare la tua password su {{.SiteName}}.

        \n\nSe non sei tu, puoi tranquillamente ignorare questa email.

        \n\nClicca sul seguente link per scegliere una nuova password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNota: Si tratta di un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata." - register: - title: - other: "[{{.SiteName}}] Conferma il tuo nuovo account" - body: - other: "Benvenuto in {{.SiteName}}!

        \n\nClicca il seguente link per confermare e attivare il tuo nuovo account:
        \n{{.RegisterUrl}}

        \n\nSe il link di cui sopra non è cliccabile, prova a copiarlo e incollarlo nella barra degli indirizzi del tuo browser web.\n

        \n\n--
        \nNota: Si tratta di un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata." - test: - title: - other: "[{{.SiteName}}] Email di prova" - body: - other: "Questa è una email di prova.\n

        \n\n--
        \nNota: Questa è un'email di sistema automatica, non rispondere a questo messaggio perché la tua risposta non verrà visualizzata." - action_activity_type: - upvote: - other: voto a favore - upvoted: - other: voto a favore - downvote: - other: voto negativo - downvoted: - other: votato negativamente - accept: - other: Accetta - accepted: - other: Accettato - edit: - other: modifica - review: - queued_post: - other: Post in coda - flagged_post: - other: Post contrassegnato - suggested_post_edit: - other: Modifiche suggerite - reaction: - tooltip: - other: "{{ .Names }} e {{ .Count }} più..." - badge: - default_badges: - autobiographer: - name: - other: Autobiografo - desc: - other: Informazioni sul profilo completate. - certified: - name: - other: Certificato - desc: - other: "\nCompletato il nostro nuovo tutorial per l'utente." - editor: - name: - other: Editor - desc: - other: Prima modifica al post. - first_flag: - name: - other: Primo Contrassegno - desc: - other: Primo contrassegno di un post. - first_upvote: - name: - other: Primo Mi Piace - desc: - other: Primo Mi Piace a un post - first_link: - name: - other: Primo Link - desc: - other: Per prima cosa è stato aggiunto un link ad un altro post. - first_reaction: - name: - other: Prima Reazione - desc: - other: Prima reazione al post. - first_share: - name: - other: Prima Condivisione - desc: - other: Prima condivisione a un post. - scholar: - name: - other: Studioso - desc: - other: Ha posto una domanda e ha accettato una risposta - commentator: - name: - other: Commentatore - desc: - other: Lascia 5 commenti. - new_user_of_the_month: - name: - other: Nuovo Utente del Mese - desc: - other: Contributi straordinari nel primo mese. - read_guidelines: - name: - other: Leggi le Linee Guida - desc: - other: Leggi le [linee guida della community]. - reader: - name: - other: Lettore - desc: - other: Leggi ogni risposta in un argomento con più di 10 risposte. - welcome: - name: - other: Benvenuto - desc: - other: Ricevuto un voto positivo. - nice_share: - name: - other: Condivisione positiva. - desc: - other: Ha condiviso un post con 25 visitatori unici. - good_share: - name: - other: Condivisione positiva. - desc: - other: Condiviso un post con 300 visitatori unici. - great_share: - name: - other: Grande Condivisione - desc: - other: Condiviso un post con 1000 visitatori unici. - out_of_love: - name: - other: Fuori Amore - desc: - other: Usato 50 voti in su in un giorno. - higher_love: - name: - other: Amore Superiore - desc: - other: Usato 50 voti in su in un giorno 5 volte. - crazy_in_love: - name: - other: Pazzo innamorato - desc: - other: Utilizzato 50 voti in su in un giorno 20 volte. - promoter: - name: - other: Promotore - desc: - other: Invitato un utente. - campaigner: - name: - other: Campagnia - desc: - other: Invitato a 3 utenti di base. - champion: - name: - other: Campione - desc: - other: Invitati 5 membri. - thank_you: - name: - other: Grazie - desc: - other: Il post ha ricevuto 20 voti positivi e 10 voti positivi. - gives_back: - name: - other: Feedback - desc: - other: Post con 100 voti positivi e 100 voti positivi espressi. - empathetic: - name: - other: Empatico - desc: - other: Ha 500 posti votati e ha rinunciato a 1000 voti. - enthusiast: - name: - other: Entusiasta - desc: - other: Visitato 10 giorni consecutivi. - aficionado: - name: - other: Aficionado - desc: - other: Visitato 100 giorni consecutivi. - devotee: - name: - other: Devotee - desc: - other: Visitato 365 giorni consecutivi. - anniversary: - name: - other: Anniversario - desc: - other: Membro attivo per un anno, pubblicato almeno una volta. - appreciated: - name: - other: Apprezzato - desc: - other: Ricevuto 1 voto su 20 posti. - respected: - name: - other: Rispettati - desc: - other: Ricevuto 2 voto su 100 posti. - admired: - name: - other: Ammirato - desc: - other: Ricevuto 5 voto su 300 posti. - solved: - name: - other: Risolto - desc: - other: Avere una risposta accettata. - guidance_counsellor: - name: - other: Consulente Di Orientamento - desc: - other: Si accettano 10 risposte. - know_it_all: - name: - other: Sa tutto - desc: - other: Si accettano 50 risposte. - solution_institution: - name: - other: Istituzione Di Soluzione - desc: - other: Si accettano 150 risposte. - nice_answer: - name: - other: Bella risposta - desc: - other: Punteggio domande pari o superiore a 10. - good_answer: - name: - other: Buona risposta - desc: - other: Punteggio domande pari o superiore a 25. - great_answer: - name: - other: Risposta molto buona - desc: - other: Punteggio domande pari o superiore a 50. - nice_question: - name: - other: Bella domanda - desc: - other: Punteggio domande pari o superiore a 10. - good_question: - name: - other: Buona domanda - desc: - other: Punteggio della domanda di 25 o più - great_question: - name: - other: Ottima domanda - desc: - other: Punteggio domande pari o superiore a 50. - popular_question: - name: - other: Domanda popolare - desc: - other: "Domanda con 500 visualizzazioni\n" - notable_question: - name: - other: Domanda notevole - desc: - other: Domanda con 1.000 visualizzazioni. - famous_question: - name: - other: Domanda celebre - desc: - other: "Domanda con 5.000 visualizzazioni.\n." - popular_link: - name: - other: Link Popolare - desc: - other: Pubblicato un link esterno con 50 clic. - hot_link: - name: - other: Link popolare - desc: - other: Pubblicato un link esterno con 300 clic. - famous_link: - name: - other: Link celebre - desc: - other: Pubblicato un link esterno con 100 clic. - default_badge_groups: - getting_started: - name: - other: Primi passi - community: - name: - other: Community - posting: - name: - other: Pubblicazione in corso -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Come formattare - desc: >- -
        • menzionare un post: #post_id

        • per creare collegamenti

          <https://url.com>

          [Titolo](https://url.com)
        • mettere ritorni a capo tra i paragrafi

        • corsivo o **grassetto**

        • indentare il codice con 4 spazi

        • citare iniziando la riga con >

        • utilizzare il backtick per scapeggiare il codice `come _questo_`

        • creare recinti di codice con backticks `

          ```
          codice qui
          ```
        - pagination: - prev: Prec - next: Successivo - page_title: - question: Domanda - questions: Domande - tag: Tag - tags: Tags - tag_wiki: tag wiki - create_tag: Crea tag - edit_tag: Modifica Tag - ask_a_question: Crea domanda - edit_question: Modifica Domanda - edit_answer: Modifica risposta - search: Cerca - posts_containing: Post contenenti - settings: Impostazioni - notifications: Notifiche - login: Accedi - sign_up: Registrati - account_recovery: Recupero dell'account - account_activation: Attivazione account - confirm_email: Conferma Email - account_suspended: Account sospeso - admin: Amministratore - change_email: Modifica la tua email - install: Installazione di Answer - upgrade: Upgrade di Answer - maintenance: Manutenzione del sito - users: Utenti - oauth_callback: Elaborazione in corso - http_404: Errore HTTP 404 - http_50X: Errore HTTP 500 - http_403: Errore HTTP 403 - logout: Disconnetti - posts: Posts - notifications: - title: Notifiche - inbox: Posta in arrivo - achievement: Risultati - new_alerts: Nuovi avvisi - all_read: Segna tutto come letto - show_more: Mostra di più - someone: Qualcuno - inbox_type: - all: Tutti - posts: Messaggi - invites: Inviti - votes: Voti - answer: Risposta - question: Domanda - badge_award: Distintivo - suspended: - title: Il tuo account è stato sospeso - until_time: "Il tuo account è stato sospeso fino a {{ time }}." - forever: Questo utente è stato sospeso per sempre. - end: Non soddisfi le linee guida della community. - contact_us: Contattaci - editor: - blockquote: - text: Citazione - bold: - text: Forte - chart: - text: Grafico - flow_chart: Diagramma di flusso - sequence_diagram: Diagramma di sequenza - class_diagram: Diagramma di classe - state_diagram: Diagramma di stato - entity_relationship_diagram: Diagramma Entità-Relazione - user_defined_diagram: "\nDiagramma definito dall'utente" - gantt_chart: Diagramma di Gantt - pie_chart: Grafico a torta - code: - text: Esempio di codice - add_code: Aggiungi un esempio di codice - form: - fields: - code: - label: Codice - msg: - empty: Il codice non può essere vuoto - language: - label: Lingua - placeholder: Rilevamento automatico - btn_cancel: Cancella - btn_confirm: Aggiungi - formula: - text: Formula - options: - inline: Formula nella linea - block: "\nFormula di blocco" - heading: - text: Intestazione - options: - h1: Intestazione 1 - h2: Intestazione 2 - h3: Intestazione 3 - h4: Intestazione 4 - h5: Intestazione 5 - h6: Intestazione 6 - help: - text: Aiuto - hr: - text: Riga orizzontale - image: - text: Immagine - add_image: Aggiungi immagine - tab_image: Carica immagine - form_image: - fields: - file: - label: File d'immagine - btn: Scegli immagine - msg: - empty: Il file non può essere vuoto. - only_image: Sono ammesse solo le immagini - max_size: La dimensione del file non può superare {{size}} MB. - desc: - label: Descrizione - tab_url: Url dell'Immagine - form_url: - fields: - url: - label: URL dell'immagine - msg: - empty: L'URL dell'immagine non può essere vuoto. - name: - label: Descrizione - btn_cancel: Cancella - btn_confirm: Aggiungi - uploading: Caricamento in corso... - indent: - text: Indenta - outdent: - text: Deindenta - italic: - text: Corsivo - link: - text: Collegamento ipertestuale - add_link: Aggiungi collegamento - form: - fields: - url: - label: URL - msg: - empty: L'URL non può essere vuoto - name: - label: Descrizione - btn_cancel: Cancella - btn_confirm: Aggiungi - ordered_list: - text: Elenco numerato - unordered_list: - text: Elenco puntato - table: - text: Tabella - heading: Intestazione - cell: Cella - file: - text: Allega file - not_supported: "Non supportare quel tipo di file. Riprovare con {{file_type}}." - max_size: "Allega la dimensione dei file non può superare {{size}} MB." - close_modal: - title: Sto chiudendo questo post come... - btn_cancel: Cancella - btn_submit: Invia - remark: - empty: Non può essere vuoto. - msg: - empty: Per favore seleziona un motivo - report_modal: - flag_title: Sto segnalando questo post per riportarlo come... - close_title: Sto chiudendo questo post come... - review_question_title: Rivedi la domanda - review_answer_title: Rivedi la risposta - review_comment_title: Rivedi il commento - btn_cancel: Cancella - btn_submit: Invia - remark: - empty: Non può essere vuoto. - msg: - empty: Per favore seleziona un motivo - not_a_url: Formato URL errato. - url_not_match: L'origine dell'URL non corrisponde al sito web corrente. - tag_modal: - title: Crea un nuovo tag - form: - fields: - display_name: - label: Nome da visualizzare - msg: - empty: Il nome utente non può essere vuoto. - range: Nome utente fino a 35 caratteri. - slug_name: - label: Slug dell'URL - desc: URL slug fino a 35 caratteri. - msg: - empty: Lo slug dell'URL non può essere vuoto. - range: Slug dell'URL fino a 35 caratteri. - character: Lo slug dell'URL contiene un set di caratteri non consentiti. - desc: - label: Descrizione - revision: - label: Revisione - edit_summary: - label: Modifica il riepilogo - placeholder: >- - Spiega brevemente le tue modifiche (ortografia rifinita, grammatica corretta, formattazione migliorata) - btn_cancel: Cancella - btn_submit: Invia - btn_post: Pubblica un nuovo tag - tag_info: - created_at: Creato - edited_at: Modificato - history: Cronologia - synonyms: - title: Sinonimi - text: I seguenti tag verranno rimappati a - empty: Nessun sinonimo trovato. - btn_add: Aggiungi un sinonimo - btn_edit: Modifica - btn_save: Salva - synonyms_text: I seguenti tag verranno rimappati a - delete: - title: Elimina questo tag - tip_with_posts: >- -

        Non è consentita l'eliminazione di tag con post.

        Rimuovi prima questo tag dai post.

        - tip_with_synonyms: >- -

        Non è consentita l'eliminazione di tag con sinonimi.

        Per favore, rimuovi prima i sinonimi da questo tag.

        - tip: Sei sicuro di voler cancellare? - close: Chiudi - merge: - title: Unisci tag - source_tag_title: Cerca tag - source_tag_description: Il tag sorgente e i dati associati verranno rimappati al tag di destinazione. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Modifica Tag - default_reason: Modifica tag - default_first_reason: Aggiungi tag - btn_save_edits: Salva modifiche - btn_cancel: Cancella - dates: - long_date: Mese, giorno - long_date_with_year: "Giorno, Mese, Anno" - long_date_with_time: "MMM D, AAAA [at] HH:mm" - now: ora - x_seconds_ago: "{{count}}s fa" - x_minutes_ago: "{{count}}m fa" - x_hours_ago: "{{count}}h fa" - hour: ora - day: giorno - hours: ore - days: giorni - month: month - months: months - year: year - reaction: - heart: cuore - smile: sorriso - frown: disapprovare - btn_label: aggiungere o rimuovere le reazioni - undo_emoji: annulla reazione {{ emoji }} - react_emoji: reagire con {{ emoji }} - unreact_emoji: non reagire con {{ emoji }} - comment: - btn_add_comment: Aggiungi un commento - reply_to: Rispondi a - btn_reply: Rispondi - btn_edit: Modifica - btn_delete: Cancella - btn_flag: Segnala - btn_save_edits: Salva modifiche - btn_cancel: Cancella - show_more: "{{count}} altri commenti" - tip_question: >- - Usa i commenti per chiedere maggiori informazioni o per suggerire miglioramenti. Evita di rispondere alle domande nei commenti. - tip_answer: >- - Utilizza i commenti per rispondere ad altri utenti o avvisarli delle modifiche. Se stai aggiungendo nuove informazioni, modifica il tuo post invece di commentare. - tip_vote: Aggiunge qualcosa di utile al post - edit_answer: - title: Modifica risposta - default_reason: Modifica risposta - default_first_reason: Aggiungi risposta - form: - fields: - revision: - label: Revisione - answer: - label: Risposta - feedback: - characters: Il testo deve contenere almeno 6 caratteri. - edit_summary: - label: Modifica il riepilogo - placeholder: >- - Spiega brevemente le tue modifiche (ortografia rifinita, grammatica corretta, formattazione migliorata) - btn_save_edits: Salva modifiche - btn_cancel: Annulla - tags: - title: Tag - sort_buttons: - popular: Popolari - name: Nome - newest: Più recente - button_follow: Segui - button_following: Segui già - tag_label: domande - search_placeholder: Filtra per nome del tag - no_desc: Il tag non ha descrizioni. - more: Altro - wiki: Wiki - ask: - title: Create Question - edit_title: Modifica Domanda - default_reason: Modifica domanda - default_first_reason: Create question - similar_questions: Domande simili - form: - fields: - revision: - label: Revisione - title: - label: Titolo - placeholder: What's your topic? Be specific. - msg: - empty: Il titolo non può essere vuoto. - range: Il titolo non può superare i 150 caratteri - body: - label: Contenuto - msg: - empty: Il corpo del testo non può essere vuoto. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Tags - msg: - empty: I tag non possono essere vuoti. - answer: - label: Risposta - msg: - empty: La risposta non può essere vuota. - edit_summary: - label: Modifica riepilogo - placeholder: >- - Spiega brevemente le tue modifiche (ortografia corretta, grammatica corretta, formattazione migliorata) - btn_post_question: Posta la tua domanda - btn_save_edits: Salva modifiche - answer_question: Rispondi alla tua domanda - post_question&answer: Posta la tua domanda e risposta - tag_selector: - add_btn: Aggiungi tag - create_btn: Crea un nuovo tag - search_tag: Cerca tag - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: Nessun tag corrispondente - tag_required_text: Tag richiesto (almeno uno) - header: - nav: - question: Domande - tag: Tags - user: Utenti - badges: Badges - profile: Profilo - setting: Impostazioni - logout: Disconnetti - admin: Amministratore - review: Revisione - bookmark: Segnalibri - moderation: Moderazione - search: - placeholder: Cerca - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Modifica - loading: caricamento in corso... - pic_auth_code: - title: Captcha - placeholder: Digita il testo sopra - msg: - empty: Il Captcha non può essere vuoto. - inactive: - first: >- - Hai quasi finito! Abbiamo inviato un'e-mail di attivazione a {{mail}}. Segui le istruzioni contenute nella mail per attivare il tuo account. - info: "Se non arriva, controlla la cartella spam." - another: >- - Ti abbiamo inviato un'altra email di attivazione all'indirizzo {{mail}}. Potrebbero volerci alcuni minuti prima che arrivi; assicurati di controllare la cartella spam. - btn_name: Reinvia l'e-mail di attivazione - change_btn_name: Modifica e-mail - msg: - empty: Non può essere vuoto. - resend_email: - url_label: Sei sicuro di voler inviare nuovamente l'e-mail di attivazione? - url_text: Puoi anche fornire all'utente il link di attivazione riportato sopra. - login: - login_to_continue: Accedi per continuare - info_sign: Non hai un account? <1>Iscriviti - info_login: Hai già un account? <1>Accedi - agreements: Registrandoti, accetti l'<1>informativa sulla privacy e i <3>termini del servizio. - forgot_pass: Password dimenticata? - name: - label: Nome - msg: - empty: Il nome non può essere vuoto. - range: Il nome deve essere di lunghezza compresa tra 2 e 30 caratteri. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: E-mail - msg: - empty: L'email non può essere vuota. - password: - label: Password - msg: - empty: La password non può essere vuota. - different: Le password inserite su entrambi i lati non corrispondono - account_forgot: - page_title: Password dimenticata? - btn_name: Inviami email di recupero - send_success: >- - Se un account corrisponde a {{mail}}, a breve dovresti ricevere un'e-mail con le istruzioni su come reimpostare la password. - email: - label: E-mail - msg: - empty: Il campo email non può essere vuoto. - change_email: - btn_cancel: Cancella - btn_update: Aggiorna indirizzo email - send_success: >- - Se un account corrisponde a {{mail}}, a breve dovresti ricevere un'email con le istruzioni su come reimpostare la password. - email: - label: Nuova email - msg: - empty: L'email non può essere vuota. - oauth: - connect: Connettiti con {{ auth_name }} - remove: Rimuovi {{ auth_name }} - oauth_bind_email: - subtitle: Aggiungi un'email di recupero al tuo account. - btn_update: Aggiorna l'indirizzo email - email: - label: E-mail - msg: - empty: L'email non può essere vuota. - modal_title: Email già esistente - modal_content: Questo indirizzo email è già registrato. Sei sicuro che vuoi connetterti all'account esistente? - modal_cancel: Cambia email - modal_confirm: Connettiti all'account esistente - password_reset: - page_title: Reimposta la password - btn_name: Reimposta la mia password - reset_success: >- - Hai cambiato con successo la tua password; sarai reindirizzato alla pagina di accesso. - link_invalid: >- - Siamo spiacenti, questo link di reset della password non è più valido. Forse la password è già stata reimpostata? - to_login: Continua per effettuare il login - password: - label: Password - msg: - empty: La password non può essere vuota - length: La lunghezza deve essere compresa tra 8 e 32 - different: Le password inserite non corrispondono - password_confirm: - label: Conferma la nuova password - settings: - page_title: Impostazioni - goto_modify: Vai alle modifiche - nav: - profile: Profilo - notification: Notifiche - account: Profilo - interface: Interfaccia - profile: - heading: Profilo - btn_name: Salva - display_name: - label: Visualizza nome - msg: Il nome utente non può essere vuoto. - msg_range: Display name must be 2-30 characters in length. - username: - label: Nome utente - caption: Gli altri utenti possono menzionarti con @{{username}}. - msg: Il nome utente non può essere vuoto. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Immagine del profilo - gravatar: Gravatar - gravatar_text: Puoi cambiare l'immagine - custom: Personalizzato - custom_text: Puoi caricare la tua immagine. - default: Sistema - msg: Per favore carica un avatar - bio: - label: Chi sono - website: - label: Sito web - placeholder: "https://esempio.com" - msg: Formato non corretto del sito web - location: - label: Luogo - placeholder: "Città, Paese" - notification: - heading: Notifiche email - turn_on: Accendi - inbox: - label: Notifiche in arrivo - description: Risposte alle tue domande, commenti, inviti e altro ancora. - all_new_question: - label: Tutte le nuove domande - description: Ricevi una notifica per tutte le nuove domande. Fino a 50 domande a settimana. - all_new_question_for_following_tags: - label: Tutte le nuove domande per i seguenti tag - description: Ricevi una notifica delle nuove domande per i seguenti tag. - account: - heading: Profilo - change_email_btn: Modifica e-mail - change_pass_btn: Modifica password - change_email_info: >- - Abbiamo inviato una mail a quell'indirizzo. Si prega di seguire le istruzioni di conferma. - email: - label: E-mail - new_email: - label: Nuova mail - msg: La nuova email non può essere vuota. - pass: - label: Password attuale - msg: La password non può essere vuota - password_title: Password - current_pass: - label: Password attuale - msg: - empty: La password attuale non può essere vuota. - length: La lunghezza deve essere compresa tra 8 e 32. - different: Le due password inserite non corrispondono. - new_pass: - label: Nuova password - pass_confirm: - label: Conferma la nuova password - interface: - heading: Interfaccia - lang: - label: Lingua dell'interfaccia - text: La lingua dell'interfaccia utente cambierà quando aggiorni la pagina. - my_logins: - title: I miei login - label: Accedi o registrati su questo sito utilizzando questi account. - modal_title: Rimuovi login - modal_content: Sei sicuro di voler rimuovere questo login dal tuo account? - modal_confirm_btn: Rimuovi - remove_success: Rimosso con successo - toast: - update: Aggiornamento riuscito - update_password: Password modificata con successo. - flag_success: Grazie per la segnalazione. - forbidden_operate_self: Vietato operare su se stessi. - review: Le tue modifiche verranno visualizzata dopo la revisione. - sent_success: Inviato correttamente - related_question: - title: Related - answers: risposte - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Persone Interpellate - desc: Seleziona le persone che pensi potrebbero conoscere la risposta. - invite: Invita a rispondere - add: Aggiungi contatti - search: Cerca persone - question_detail: - action: Azione - created: Created - Asked: Chiesto - asked: chiesto - update: Modificato - Edited: Edited - edit: modificato - commented: commentato - Views: Visualizzati - Follow: Segui - Following: Segui già - follow_tip: Segui questa domanda per ricevere notifiche - answered: Risposto - closed_in: Chiuso in - show_exist: Mostra domanda esistente. - useful: Utile - question_useful: È utile e chiaro - question_un_useful: Non è chiaro né utile - question_bookmark: Aggiungi questa domanda ai segnalibri - answer_useful: È utile - answer_un_useful: Non è utile - answers: - title: Risposte - score: Punteggio - newest: Più recenti - oldest: Meno recente - btn_accept: Accetta - btn_accepted: Accettato - write_answer: - title: La tua risposta - edit_answer: Modifica la mia risposta attuale - btn_name: Pubblica la tua risposta - add_another_answer: Aggiungi un'altra risposta - confirm_title: Continua a rispondere - continue: Continua - confirm_info: >- -

        Sei sicuro di voler aggiungere un'altra risposta?

        In alternativa, puoi usare il link di modifica per perfezionare e migliorare la tua risposta esistente.

        - empty: La risposta non può essere vuota. - characters: Il contenuto deve avere una lunghezza di almeno 6 caratteri. - tips: - header_1: Grazie per la risposta - li1_1: Assicurati di rispondere alla domanda. Fornisci dettagli e condividi la tua ricerca. - li1_2: Effettua il backup di qualsiasi dichiarazione fatta con riferimenti o esperienze personali. - header_2: Ma evita... - li2_1: Chiedere aiuto, cercare chiarimenti o rispondere ad altre risposte. - reopen: - confirm_btn: Riapri - title: Riapri questo post - content: Sei sicuro di voler riaprire? - list: - confirm_btn: Listare - title: Lista questo post - content: Sei sicuro di volerlo listare? - unlist: - confirm_btn: Rimuovi dall'elenco - title: Rimuovi questo post - content: Sei sicuro di voler rimuovere dall'elenco? - pin: - title: Fissa questo post in cima al profilo - content: Sei sicuro di voler fissare in blocco? Questo post apparirà in cima a tutte le liste. - confirm_btn: Fissa sul profilo - delete: - title: Cancella questo post - question: >- - Non consigliamo di eliminaredomande con risposte perché ciò priva i futuri lettori di questa conoscenza.

        L'eliminazione ripetuta di domande con risposte può comportare il blocco delle domande nel tuo account. Sei sicuro di voler eliminare? - answer_accepted: >- -

        Non consigliamo di eliminare la risposta accettata perché così facendo si priva i futuri lettori di questa conoscenza.

        La cancellazione ripetuta delle risposte accettate può causare il blocco del tuo account dalla risposta. Sei sicuro di voler eliminare? - other: Sei sicuro di voler eliminare? - tip_answer_deleted: Questa risposta è stata cancellata - undelete_title: Ripristina questo post - undelete_desc: Sei sicuro di voler ripristinare? - btns: - confirm: Conferma - cancel: Cancella - edit: Modifica - save: Salva - delete: Elimina - undelete: Ripristina - list: Aggiungi all'elenco - unlist: Rimuovi dall'elenco - unlisted: Rimosso dall'elenco - login: Accedi - signup: Registrati - logout: Disconnetti - verify: Verifica - create: Create - approve: Approva - reject: Rifiuta - skip: Salta - discard_draft: Elimina bozza - pinned: Fissato in cima - all: Tutti - question: Domanda - answer: Risposta - comment: Commento - refresh: Aggiorna - resend: Rinvia - deactivate: Disattivare - active: Attivo - suspend: Sospendi - unsuspend: Riabilita - close: Chiudi - reopen: Riapri - ok: OK - light: Illuminazione - dark: Scuro - system_setting: Configurazione di sistema - default: Predefinito - reset: Resetta - tag: Tag - post_lowercase: post - filter: 'Filtra' - ignore: Ignora - submit: Invia - normal: Normale - closed: Chiuso - deleted: Eliminato - deleted_permanently: Deleted permanently - pending: In attesa - more: Altro - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Risultati della ricerca - keywords: Parole chiave - options: Opzioni - follow: Segui - following: Segui già - counts: "{{count}} Risultati" - counts_loading: "... Results" - more: Altro - sort_btns: - relevance: Rilevanza - newest: Più recenti - active: Attivo - score: Punteggio - more: Altro - tips: - title: Suggerimenti per ricerca avanzata - tag: "<1>[tag] cerca dentro un tag" - user: "<1>user:username ricerca per autore" - answer: "<1>risposte:0 domande senza risposta" - score: "<1>punteggio:3 messaggi con un punteggio di 3+" - question: "<1>is:question cerca domande" - is_answer: "<1>is:answer cerca risposte" - empty: Non siamo riusciti a trovare nulla.
        Prova parole chiave diverse o meno specifiche. - share: - name: Condividi - copy: Copia il link - via: Condividi il post via... - copied: Copiato - facebook: Condividi su Facebook - twitter: Share to X - cannot_vote_for_self: Non puoi votare un tuo post! - modal_confirm: - title: Errore... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Il tuo nuovo account è confermato; sarai reindirizzato alla home page. - link: Continua alla Homepage - oops: Oops! - invalid: Il link che hai usato non è più attivo. - confirm_new_email: La tua email è stata aggiornata. - confirm_new_email_invalid: >- - Siamo spiacenti, questo link di conferma non è più valido. Forse la tua email è già stata modificata? - unsubscribe: - page_title: Annulla l'iscrizione - success_title: Cancellazione effettuata con successo - success_desc: Sei stato rimosso con successo da questa lista e non riceverai ulteriori email - link: Cambia impostazioni - question: - following_tags: Tag seguenti - edit: Modifica - save: Salva - follow_tag_tip: Segui i tag per curare la tua lista di domande. - hot_questions: Domande scottanti - all_questions: Tutte le domande - x_questions: "{{ count }} Domande" - x_answers: "{{count}} risposte" - x_posts: "{{ count }} Posts" - questions: Domande - answers: Risposte - newest: Più recenti - active: Attivo - hot: Caldo - frequent: Frequenti - recommend: Raccomandato - score: Punteggio - unanswered: Senza risposta - modified: Modificato - answered: Risposte - asked: chiesto - closed: Chiuso - follow_a_tag: Segui un tag - more: Altro - personal: - overview: Informazioni Generali - answers: Risposte - answer: Risposta - questions: Domande - question: Domanda - bookmarks: Segnalibri - reputation: Reputazione - comments: Commenti - votes: Voti - badges: Badges - newest: Più recenti - score: Punteggio - edit_profile: Modifica profilo - visited_x_days: "{{ count }} giorni visitati" - viewed: Visualizzati - joined: Iscritto - comma: "," - last_login: Visto - about_me: Chi sono - about_me_empty: "// Ciao, mondo !" - top_answers: Migliori risposte - top_questions: Domande principali - stats: Statistiche - list_empty: Nessun post trovato.
        Forse desideri selezionare una scheda diversa? - content_empty: Nessun post trovato. - accepted: Accettato - answered: risposto - asked: chiesto - downvoted: votato negativamente - mod_short: Moderatore - mod_long: Moderatori - x_reputation: reputazione - x_votes: voti ricevuti - x_answers: risposte - x_questions: domande - recent_badges: Badges Recenti - install: - title: Installazione - next: Avanti - done: Fatto - config_yaml_error: Impossibile creare il file config.yaml. - lang: - label: Scegli una lingua - db_type: - label: Motore database - db_username: - label: Nome utente - placeholder: root - msg: Il nome utente non può essere vuoto. - db_password: - label: Password - placeholder: root - msg: La password non può essere vuota. - db_host: - label: Host del database - placeholder: "db:3306" - msg: L'host del database non può essere vuoto. - db_name: - label: Nome database - placeholder: risposta - msg: Il nome del database non può essere vuoto. - db_file: - label: File del database - placeholder: /data/answer.db - msg: Il file del database non può essere vuoto. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Crea config.yaml - label: File config.yaml creato. - desc: >- - Puoi creare manualmente il file <1>config.yaml nella directory <1>/var/wwww/xxx/ e incollarvi il seguente testo. - info: Una volta fatto, fai clic sul pulsante "Avanti". - site_information: Informazioni sul sito - admin_account: Account Amministratore - site_name: - label: Nome del sito - msg: Il nome del sito non può essere vuoto. - msg_max_length: Il nome del sito deve contenere un massimo di 30 caratteri. - site_url: - label: URL del sito - text: L'indirizzo del tuo sito. - msg: - empty: L'URL del sito non può essere vuoto. - incorrect: Formato errato dell'URL del sito. - max_length: L'URL del sito deve contenere un massimo di 512 caratteri. - contact_email: - label: Email di contatto - text: Indirizzo e-mail del contatto chiave responsabile di questo sito. - msg: - empty: L'email del contatto non può essere vuota. - incorrect: Formato errato dell'e-mail di contatto. - login_required: - label: Privato - switch: Login obbligatorio - text: Solo gli utenti registrati possono accedere a questa community. - admin_name: - label: Nome - msg: Il nome non può essere vuoto. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Password - text: >- - Avrai bisogno di questa password per accedere. Conservala in un luogo sicuro. - msg: La password non può essere vuota - msg_min_length: La password deve contenere almeno 8 caratteri. - msg_max_length: La password deve contenere un massimo di 32 caratteri. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: E-mail - text: Avrai bisogno di questa email per accedere. - msg: - empty: Il campo email non può essere vuoto. - incorrect: Formato dell'email errato. - ready_title: Il tuo sito è pronto - ready_desc: >- - Se vuoi cambiare più impostazioni, visita la sezione <1>admin che si trova nel menu del sito. - good_luck: "Divertiti e buona fortuna!" - warn_title: Pericolo - warn_desc: >- - Il file <1>config.yaml esiste già. Se vuoi reimpostare uno qualsiasi degli elementi di configurazione in questo file, eliminalo prima. - install_now: Puoi provare a <1>installare ora. - installed: Già installato - installed_desc: >- - Sembra che tu abbia già installato. Per reinstallare, cancella prima le vecchie tabelle del database. - db_failed: Connessione al database fallita - db_failed_desc: >- - Questo significa che le informazioni sul database nel file <1>config.yaml non sono corrette o che non è stato possibile stabilire il contatto con il server del database. Ciò potrebbe significare che il server del database del tuo host è inattivo. - counts: - views: visualizzazioni - votes: Voti - answers: risposte - accepted: Accettato - page_error: - http_error: Errore HTTP {{ code }} - desc_403: Non hai i permessi per accedere a questa pagina. - desc_404: Sfortunatamente, questa pagina non esiste. - desc_50X: Il server ha riscontrato un errore e non è stato possibile completare la richiesta. - back_home: Torna alla home page - page_maintenance: - desc: "Siamo in manutenzione, torneremo presto." - nav_menus: - dashboard: Pannello di controllo - contents: Contenuti - questions: Domande - answers: Risposte - users: Utenti - badges: Badges - flags: Contrassegni - settings: Impostazioni - general: Generale - interface: Interfaccia - smtp: Protocollo di Trasferimento Posta Semplice - branding: Marchio - legal: Legale - write: Scrivi - terms: Terms - tos: Termini del servizio - privacy: Privacy - seo: SEO - customize: Personalizza - themes: Temi - login: Accedi - privileges: Privilegi - plugins: Plugin - installed_plugins: Plugin installati - apperance: Appearance - website_welcome: Benvenuto/a su {{site_name}}! - user_center: - login: Accedi - qrcode_login_tip: Si prega di utilizzare {{ agentName }} per scansionare il codice QR e accedere. - login_failed_email_tip: Accesso non riuscito. Consenti a questa app di accedere alle tue informazioni email prima di riprovare. - badges: - modal: - title: Congratulazioni - content: Hai guadagnato un nuovo distintivo. - close: Chiudi - confirm: Visualizza badge - title: Badges - awarded: Premiati - earned_×: Ottenuto ×{{ number }} - ×_awarded: "{{ number }} premiato" - can_earn_multiple: Puoi guadagnare questo più volte. - earned: Ottenuti - admin: - admin_header: - title: Amministratore - dashboard: - title: Pannello di controllo - welcome: Benvenuto ad Admin! - site_statistics: Statistiche del sito - questions: "Domande:" - resolved: "Risolto:" - unanswered: "Senza risposta:" - answers: "Risposte:" - comments: "Commenti:" - votes: "Voti:" - users: "Utenti:" - flags: "Flags" - reviews: "Revisioni" - site_health: Stato del sito - version: "Versione:" - https: "HTTPS:" - upload_folder: "Carica Cartella" - run_mode: "Modalità di esecuzione:" - private: Privato - public: Pubblico - smtp: "Protocollo di Trasferimento Posta Semplice" - timezone: "Fuso orario:" - system_info: Info sistema - go_version: "Versione Go:" - database: "Banca dati:" - database_size: "Dimensioni del database" - storage_used: "Spazio di archiviazione utilizzato:" - uptime: "Tempo di attività:" - links: Collegamenti - plugins: Plugin - github: GitHub - blog: Blog - contact: Contatti - forum: Forum - documents: Documenti - feedback: Feedback - support: Assistenza - review: Revisione - config: Configurazione - update_to: Aggiornato a - latest: Recenti - check_failed: Controllo fallito - "yes": "Sì" - "no": "No" - not_allowed: Non autorizzato - allowed: Consentito - enabled: Abilitato - disabled: Disabilitato - writable: Editabile - not_writable: Non editabile - flags: - title: Contrassegni - pending: In attesa - completed: Completato - flagged: Contrassegnato - flagged_type: Contrassegnato {{ type }} - created: Creato - action: Azione - review: Revisione - user_role_modal: - title: Cambia ruolo utente in... - btn_cancel: Cancella - btn_submit: Invia - new_password_modal: - title: Imposta una nuova password - form: - fields: - password: - label: Password - text: L'utente sarà disconnesso e dovrà effettuare nuovamente il login. - msg: La password deve contenere da 8 a 32 caratteri. - btn_cancel: Cancella - btn_submit: Invia - edit_profile_modal: - title: Modifica profilo - form: - fields: - display_name: - label: Visualizza nome - msg_range: Il nome visualizzato deve essere di 2-30 caratteri di lunghezza. - username: - label: Nome utente - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Indirizzo e-mail non valido. - edit_success: Modificato con successo - btn_cancel: Annulla - btn_submit: Invia - user_modal: - title: Aggiungi un nuovo utente - form: - fields: - users: - label: Aggiungi utenti in blocco - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separare “nome, email, password” con delle virgole. Un utente per riga. - msg: "Inserisci l'email dell'utente, una per riga." - display_name: - label: Nome da visualizzare - msg: Il nome visualizzato deve essere di 2-30 caratteri di lunghezza. - email: - label: E-mail - msg: L'email non è valida. - password: - label: Password - msg: La password deve contenere da 8 a 32 caratteri. - btn_cancel: Cancella - btn_submit: Invia - users: - title: Utenti - name: Nome - email: E-mail - reputation: Reputazione - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Sospendi fino al - status: Stato - role: Ruolo - action: Azione - change: Modifica - all: Tutti - staff: Personale - more: Altro - inactive: Inattivo - suspended: Sospeso - deleted: Eliminato - normal: Normale - Moderator: Moderatore - Admin: Amministratore - User: Utente - filter: - placeholder: "Filtra per nome, utente:id" - set_new_password: Imposta una nuova password - edit_profile: Modifica profilo - change_status: Modifica lo stato - change_role: Cambia il ruolo - show_logs: Visualizza i log - add_user: Aggiungi utente - deactivate_user: - title: Disattiva utente - content: Un utente inattivo deve riconvalidare la propria email. - delete_user: - title: Rimuovi questo utente - content: Sei sicuro di voler eliminare questo utente? L'operazione è permanente. - remove: Rimuovi il loro contenuto - label: Rimuovi tutte le domande, risposte, commenti, ecc. - text: Non selezionare questa opzione se desideri eliminare solo l'account dell'utente. - suspend_user: - title: Sospendi questo utente - content: Un utente sospeso non può accedere. - label: Per quanto tempo vuoi sospendere l'utente? - forever: Per sempre - questions: - page_title: Domande - unlisted: Rimosso dall'elenco - post: Posta - votes: Voti - answers: Risposte - created: Creato - status: Stato - action: Azione - change: Modifica - pending: In attesa - filter: - placeholder: "Filtra per titolo, domanda:id" - answers: - page_title: Risposte - post: Post - votes: Voti - created: Creato - status: Stato - action: Azione - change: Cambio - filter: - placeholder: "Filtra per titolo, domanda:id" - general: - page_title: Generale - name: - label: Nome del sito - msg: Il nome del sito non può essere vuoto. - text: "Il nome di questo sito, come usato nel tag del titolo." - site_url: - label: URL del sito - msg: L'url del sito non può essere vuoto. - validate: Inserisci un URL valido. - text: L'indirizzo del tuo sito. - short_desc: - label: Descrizione breve del sito - msg: La descrizione breve del sito non può essere vuota. - text: "Breve descrizione, come utilizzata nel tag del titolo sulla home page." - desc: - label: Descrizione del sito - msg: La descrizione del sito non può essere vuota. - text: "Descrivi questo sito in una frase, come utilizzato nel tag meta description." - contact_email: - label: Email di contatto - msg: L'email del contatto non può essere vuota. - validate: Email di contatto non valida. - text: Indirizzo e-mail del contatto chiave responsabile di questo sito. - check_update: - label: Aggiornamenti Software - text: Controlla automaticamente gli aggiornamenti - interface: - page_title: Interfaccia - language: - label: Lingua dell'interfaccia - msg: La lingua dell'interfaccia non può essere vuota. - text: La lingua dell'interfaccia utente cambierà quando aggiorni la pagina. - time_zone: - label: Fuso orario - msg: Il fuso orario non può essere vuoto. - text: Scegli una città con il tuo stesso fuso orario. - avatar: - label: Avatar Predefinito - text: Per gli utenti senza un proprio avatar personalizzato. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: Protocollo di Trasferimento Posta Semplice - from_email: - label: Dall'email - msg: L'email del contatto non può essere vuota. - text: L'indirizzo email da cui vengono inviate le email. - from_name: - label: Dal nome - msg: "Il nome del mittente non può essere vuoto.\n" - text: Il nome da cui vengono inviate le email. - smtp_host: - label: Host SMTP - msg: L'host SMTP non può essere vuoto. - text: Il tuo server di posta. - encryption: - label: Crittografia - msg: La crittografia non può essere vuota. - text: Per la maggior parte dei server SSL è l'opzione consigliata. - ssl: SSL - tls: TLS - none: Nessuna - smtp_port: - label: Porta SMTP - msg: La porta SMTP deve essere numero 1 ~ 65535. - text: La porta del tuo server di posta. - smtp_username: - label: Nome utente SMTP - msg: Il nome utente SMTP non può essere vuoto. - smtp_password: - label: Password SMTP - msg: La password SMTP non può essere vuota. - test_email_recipient: - label: Verifica destinatari email - text: Fornisci l'indirizzo email che riceverà i test inviati. - msg: Destinatari email di prova non validi - smtp_authentication: - label: "\nAbilita l'autenticazione" - title: Autenticazione SMTP - msg: L'autenticazione SMTP non può essere vuota. - "yes": "Sì" - "no": "No" - branding: - page_title: Marchio - logo: - label: Logo - msg: Il logo non può essere vuoto. - text: L'immagine del logo in alto a sinistra del tuo sito. Utilizza un'immagine rettangolare ampia con un'altezza di 56 e proporzioni superiori a 3:1. Se lasciato vuoto, il testo del titolo del sito verrà mostrato. - mobile_logo: - label: Logo per versione mobile - text: "\nIl logo utilizzato nella versione mobile del tuo sito. Utilizza un'immagine rettangolare ampia con un'altezza di 56. Se lasciata vuota, verrà utilizzata l'immagine dell'impostazione \"logo\"." - square_icon: - label: Icona quadrata - msg: L'icona quadrata non può essere vuota. - text: "Immagine utilizzata come base per le icone dei metadata. Idealmente dovrebbe essere più grande di 512x512.\n" - favicon: - label: Favicon - text: Una icona favorita per il tuo sito. Per funzionare correttamente su un CDN deve essere un png. Verrà ridimensionato a 32x32. Se lasciato vuoto, verrà utilizzata l'"icona quadrata". - legal: - page_title: Legale - terms_of_service: - label: Termini del servizio - text: "Puoi aggiungere qui i termini del contenuto del servizio. Se hai già un documento ospitato altrove, fornisci qui l'URL completo." - privacy_policy: - label: Informativa sulla privacy - text: "Puoi aggiungere il contenuto della politica sulla privacy qui. Se hai già un documento ospitato altrove, fornisci l'URL completo qui." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Scrivi - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Risposta a scrivere - label: Ogni utente può scrivere una sola risposta per ogni domanda - text: "Disattiva per consentire agli utenti di scrivere risposte multiple alla stessa domanda, il che potrebbe causare una risposta sfocata." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Raccomanda tag - text: "I tag consigliati verranno mostrati nell'elenco a discesa per impostazione predefinita." - msg: - contain_reserved: "i tag consigliati non possono contenere tag riservati" - required_tag: - title: Imposta tag necessari - label: Imposta “Raccomanda tag” come tag richiesti - text: "Ogni nuova domanda deve avere almeno un tag raccomandato." - reserved_tags: - label: Tag riservati - text: "I tag riservati possono essere utilizzati solo dal moderatore." - image_size: - label: Dimensione massima dell'immagine (MB) - text: "La dimensione massima del caricamento dell'immagine." - attachment_size: - label: Dimensione massima degli allegati (MB) - text: "Dimensione massima del caricamento dei file allegati." - image_megapixels: - label: Massima immagine megapixel - text: "Numero massimo di megapixel consentiti per un'immagine." - image_extensions: - label: Estensioni di immagini autorizzate - text: "Un elenco di estensioni di file consentite per la visualizzazione dell'immagine, separate da virgole." - attachment_extensions: - label: Estensioni di allegati autorizzate - text: "Una lista di estensioni di file consentite per il caricamento, separate con virgole. ATTENZIONE: Consentire i caricamenti potrebbe causare problemi di sicurezza." - seo: - page_title: SEO - permalink: - label: Permalink - text: Le strutture URL personalizzate possono migliorare l'usabilità e la compatibilità futura dei tuoi link. - robots: - label: robots.txt - text: Questo sovrascriverà definitivamente tutte le impostazioni relative al sito. - themes: - page_title: Temi - themes: - label: Temi - text: Seleziona un tema esistente. - color_scheme: - label: Schema colore - navbar_style: - label: Navbar background style - primary_color: - label: Colore primario - text: Modifica i colori utilizzati dai tuoi temi - css_and_html: - page_title: CSS e HTML - custom_css: - label: CSS personalizzato - text: > - - head: - label: Testata - text: > - - header: - label: Intestazione - text: > - - footer: - label: Piè di pagina - text: Questo verrà inserito prima di </body>. - sidebar: - label: Barra laterale - text: Questo verrà inserito nella barra laterale. - login: - page_title: Accedi - membership: - title: Adesione - label: Consenti nuove registrazioni - text: Disattiva per impedire a chiunque di creare un nuovo account. - email_registration: - title: Registrazione email - label: Consenti registrazione email - text: Disattiva per impedire a chiunque di creare un nuovo account tramite email. - allowed_email_domains: - title: Domini email consentiti - text: "Domini email con cui gli utenti devono registrare gli account. Un dominio per riga. Verrà ignorato quando vuoto.\n" - private: - title: Privato - label: Login obbligatorio - text: Solo gli utenti registrati possono accedere a questa community. - password_login: - title: Password di accesso - label: Consenti il login di email e password - text: "ATTENZIONE: Se disattivi, potresti non essere in grado di accedere se non hai precedentemente configurato un altro metodo di login." - installed_plugins: - title: Plugin installati - plugin_link: I plugin estendono ed espandono le funzionalità. È possibile trovare plugin nel repository <1>Plugin. - filter: - all: Tutto - active: Attivo - inactive: Inattivo - outdated: Obsoleto - plugins: - label: Plugin - text: Seleziona un plugin esistente. - name: Nome - version: Versione - status: Stato - action: Azione - deactivate: Disattivare - activate: Attivare - settings: Impostazioni - settings_users: - title: Utenti - avatar: - label: Avatar Predefinito - text: Per gli utenti senza un proprio avatar personalizzato. - gravatar_base_url: - label: Gravatar Base URL - text: "\nURL della base API del provider Gravatar. Ignorato quando vuoto." - profile_editable: - title: Profilo modificabile - allow_update_display_name: - label: Consenti di cambiare il nome utente - allow_update_username: - label: Consenti di modificare il proprio nome utente - allow_update_avatar: - label: Consenti agli utenti di modificare l'immagine del profilo - allow_update_bio: - label: Consenti agli utenti di modificare la sezione "su di me" - allow_update_website: - label: Consenti agli utenti di modificare il proprio sito web - allow_update_location: - label: Consenti agli utenti di modificare la propria posizione - privilege: - title: Privilegi - level: - label: Livello di reputazione richiesto - text: Scegli la reputazione richiesta per i privilegi - msg: - should_be_number: l'input dovrebbe essere un numero - number_larger_1: il numero dovrebbe essere uguale o superiore a 1 - badges: - action: Azione - active: Attivo - activate: Attivare - all: Tutto - awards: Ricompense - deactivate: Disattivare - filter: - placeholder: Filtra per nome, badge:id - group: Gruppo - inactive: Inattivo - name: Nome - show_logs: Visualizza i log - status: Stato - title: Badges - form: - optional: (opzionale) - empty: non può essere vuoto - invalid: non è valido - btn_submit: Salva - not_found_props: "Proprietà richiesta {{ key }} non trovata." - select: Seleziona - page_review: - review: Revisione - proposed: Proposto - question_edit: Edita domanda - answer_edit: Edita risposta - tag_edit: Edita tag - edit_summary: Edita il riepilogo - edit_question: Edita la domanda - edit_answer: Edita la risposta - edit_tag: Edita tag - empty: Nessuna attività di revisione rimasta. - approve_revision_tip: Approvi questa revisione? - approve_flag_tip: Approvi questo contrassegno? - approve_post_tip: Approvi questo post? - approve_user_tip: Approvate questo utente? - suggest_edits: Modifiche suggerite - flag_post: Post contrassegnato - flag_user: Utente contrassegno - queued_post: "Posta in coda\n" - queued_user: Utente in coda - filter_label: Digita - reputation: reputazione - flag_post_type: Post contrassegnato come {{ type }}. - flag_user_type: Utente contrassegnato come {{ type }}. - edit_post: Modifica il post - list_post: Lista il post - unlist_post: Rimuovi post - timeline: - undeleted: Non cancellato - deleted: eliminato - downvote: voto negativo - upvote: voto a favore - accept: accetta - cancelled: Cancellato - commented: commentato - rollback: ripristino - edited: modificato - answered: risposto - asked: chiesto - closed: chiuso - reopened: riaperto - created: creato - pin: Fissa in cima - unpin: Rimosso dalla cima - show: elencato - hide: non elencato - title: "Cronologia per" - tag_title: "Timeline per" - show_votes: "Mostra voti" - n_or_a: N/D - title_for_question: "Timeline per" - title_for_answer: "Timeline per rispondere a {{ title }} di {{ author }}" - title_for_tag: "Timeline per tag" - datetime: Data e ora - type: Tipo - by: Di - comment: Commento - no_data: "Non abbiamo trovato nulla" - users: - title: Utenti - users_with_the_most_reputation: Utenti con i punteggi di reputazione più alti questa settimana - users_with_the_most_vote: Utenti che hanno votato di più questa settimana - staffs: Lo staff della community - reputation: reputazione - votes: voti - prompt: - leave_page: Sei sicuro di voler lasciare questa pagina? - changes_not_save: Le modifiche potrebbero non essere salvate. - draft: - discard_confirm: Sei sicuro di voler eliminare la bozza? - messages: - post_deleted: Questo post è stato eliminato. - post_cancel_deleted: Questo post è stato ripristinato. - post_pin: Questo post è stato selezionato. - post_unpin: Questo post è stato sbloccato. - post_hide_list: Questo post è stato nascosto dall'elenco. - post_show_list: Questo post è stato mostrato in elenco. - post_reopen: Questo post è stato riaperto. - post_list: Questo post è stato inserito. - post_unlist: Questo post è stato rimosso. - post_pending: Il tuo post è in attesa di revisione. Sarà visibile dopo essere stato approvato. - post_closed: Questo post è stato chiuso. - answer_deleted: Questa risposta è stata eliminata. - answer_cancel_deleted: Questa risposta è stata ripristinata. - change_user_role: Il ruolo di questo utente è stato cambiato. - user_inactive: Questo utente è già inattivo. - user_normal: Questo utente è già normale. - user_suspended: Questo utente è stato sospeso. - user_deleted: Questo utente è stato eliminato. - badge_activated: Questo badge è stato attivato. - badge_inactivated: Questo badge è stato disattivato. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/ja_JP.yaml b/data/i18n/ja_JP.yaml deleted file mode 100644 index c0a24f57e..000000000 --- a/data/i18n/ja_JP.yaml +++ /dev/null @@ -1,2360 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: 成功 - unknown: - other: 不明なエラー - request_format_error: - other: リクエスト形式が無効です。 - unauthorized_error: - other: 権限がありません。 - database_error: - other: データサーバーエラー - forbidden_error: - other: アクセス権限がありません。 - duplicate_request_error: - other: 重複しています - action: - report: - other: 通報 - edit: - other: 編集 - delete: - other: 削除 - close: - other: 解決済み - reopen: - other: 再オープン - forbidden_error: - other: アクセス権限がありません。 - pin: - other: ピン留めする - hide: - other: 限定公開にする - unpin: - other: ピン留め解除 - show: - other: 限定公開を解除する - invite_someone_to_answer: - other: 編集 - undelete: - other: 復元する - merge: - other: Merge - role: - name: - user: - other: ユーザー - admin: - other: 管理者 - moderator: - other: モデレーター - description: - user: - other: 一般的なアクセスしか持ちません。 - admin: - other: すべてにアクセスできる大いなる力を持っています。 - moderator: - other: 管理者以外のすべての投稿へのアクセス権を持っています。 - privilege: - level_1: - description: - other: レベル1 必要最低の評判レベルで利用可(クローズサイト・グループ・特定の人数下での利用) - level_2: - description: - other: レベル2 少しだけ評判レベルが必要(スタートアップコミュニティ・不特定多数の人数での利用) - level_3: - description: - other: レベル3 高い評判レベルが必要(成熟したコミュニティ) - level_custom: - description: - other: カスタムレベル - rank_question_add_label: - other: 質問する - rank_answer_add_label: - other: 回答を書く - rank_comment_add_label: - other: コメントを書く - rank_report_add_label: - other: 通報 - rank_comment_vote_up_label: - other: コメントを高評価 - rank_link_url_limit_label: - other: 一度に2つ以上のリンクを投稿する - rank_question_vote_up_label: - other: 質問を高評価 - rank_answer_vote_up_label: - other: 回答を高評価 - rank_question_vote_down_label: - other: 質問を低評価 - rank_answer_vote_down_label: - other: 回答を低評価 - rank_invite_someone_to_answer_label: - other: 誰かを回答に招待する - rank_tag_add_label: - other: 新しいタグを作成 - rank_tag_edit_label: - other: タグの説明を編集(レビューが必要) - rank_question_edit_label: - other: 他の質問を編集(レビューが必要) - rank_answer_edit_label: - other: 他の回答を編集(レビューが必要) - rank_question_edit_without_review_label: - other: レビューなしで他の質問を編集する - rank_answer_edit_without_review_label: - other: レビューなしで他の回答を編集する - rank_question_audit_label: - other: 質問の編集をレビュー - rank_answer_audit_label: - other: 回答の編集をレビュー - rank_tag_audit_label: - other: タグの編集をレビュー - rank_tag_edit_without_review_label: - other: レビューなしでタグの説明を編集 - rank_tag_synonym_label: - other: タグの同義語を管理する - email: - other: メールアドレス - e_mail: - other: メールアドレス - password: - other: パスワード - pass: - other: パスワード - old_pass: - other: Current password - original_text: - other: 投稿 - email_or_password_wrong_error: - other: メールアドレスとパスワードが一致しません。 - error: - common: - invalid_url: - other: 無効なURL - status_invalid: - other: 無効なステータス - password: - space_invalid: - other: パスワードにスペースを含めることはできません。 - admin: - cannot_update_their_password: - other: パスワードは変更できません。 - cannot_edit_their_profile: - other: プロフィールを変更できません。 - cannot_modify_self_status: - other: ステータスを変更できません。 - email_or_password_wrong: - other: メールアドレスとパスワードが一致しません。 - answer: - not_found: - other: 回答が見つかりません。 - cannot_deleted: - other: 削除する権限がありません。 - cannot_update: - other: 更新する権限がありません。 - question_closed_cannot_add: - other: 質問はクローズされて、追加できません。 - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: コメントを編集することはできません。 - not_found: - other: コメントが見つかりません。 - cannot_edit_after_deadline: - other: コメント時間が長すぎて変更できません。 - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: メールアドレスは既に存在しています。 - need_to_be_verified: - other: 電子メールを確認する必要があります。 - verify_url_expired: - other: メール認証済みURLの有効期限が切れています。メールを再送信してください。 - illegal_email_domain_error: - other: そのメールドメインからのメールは許可されていません。別のメールアドレスを使用してください。 - lang: - not_found: - other: 言語ファイルが見つかりません。 - object: - captcha_verification_failed: - other: Captchaが間違っています。 - disallow_follow: - other: フォローが許可されていません。 - disallow_vote: - other: 投票が許可されていません。 - disallow_vote_your_self: - other: 自分の投稿には投票できません。 - not_found: - other: オブジェクトが見つかりません。 - verification_failed: - other: 認証に失敗しました。 - email_or_password_incorrect: - other: メールアドレスとパスワードが一致しません。 - old_password_verification_failed: - other: 古いパスワードの確認に失敗しました。 - new_password_same_as_previous_setting: - other: 新しいパスワードは前のパスワードと同じです。 - already_deleted: - other: この投稿は削除されました。 - meta: - object_not_found: - other: メタオブジェクトが見つかりません - question: - already_deleted: - other: この投稿は削除されました。 - under_review: - other: あなたの投稿はレビュー待ちです。承認されると表示されます。 - not_found: - other: 質問が見つかりません。 - cannot_deleted: - other: 削除する権限がありません。 - cannot_close: - other: クローズする権限がありません。 - cannot_update: - other: 更新する権限がありません。 - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: 評判ランクが条件を満たしていません - vote_fail_to_meet_the_condition: - other: フィードバックをありがとうございます。投票には少なくとも {{.Rank}} の評判が必要です。 - no_enough_rank_to_operate: - other: 少なくとも {{.Rank}} の評判が必要です。 - report: - handle_failed: - other: レポートの処理に失敗しました。 - not_found: - other: レポートが見つかりません。 - tag: - already_exist: - other: タグは既に存在します。 - not_found: - other: タグが見つかりません。 - recommend_tag_not_found: - other: おすすめタグは存在しません。 - recommend_tag_enter: - other: 少なくとも 1 つの必須タグを入力してください。 - not_contain_synonym_tags: - other: 同義語のタグを含めないでください。 - cannot_update: - other: 更新する権限がありません。 - is_used_cannot_delete: - other: 使用中のタグは削除できません。 - cannot_set_synonym_as_itself: - other: 現在のタグの同義語をそのものとして設定することはできません。 - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: Fromの名前はメールアドレスにできません。 - theme: - not_found: - other: テーマが見つかりません。 - revision: - review_underway: - other: 現在編集できません。レビューキューにバージョンがあります。 - no_permission: - other: 編集する権限がありません。 - user: - external_login_missing_user_id: - other: サードパーティのプラットフォームは一意のユーザーIDを提供していないため、ログインできません。ウェブサイト管理者にお問い合わせください。 - external_login_unbinding_forbidden: - other: ログインを削除する前に、アカウントのログインパスワードを設定してください。 - email_or_password_wrong: - other: - other: メールアドレスとパスワードが一致しません。 - not_found: - other: ユーザーが見つかりません。 - suspended: - other: このユーザーは凍結されています - username_invalid: - other: 無効なユーザー名です! - username_duplicate: - other: ユーザー名は既に使用されています! - set_avatar: - other: アバターを設定できませんでした - cannot_update_your_role: - other: ロールを変更できません - not_allowed_registration: - other: 現在、このサイトは新規登録を受け付けておりません - not_allowed_login_via_password: - other: 現在、このサイトはパスワードでログインできません - access_denied: - other: アクセスが拒否されました - page_access_denied: - other: このページへのアクセス権がありません - add_bulk_users_format_error: - other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "一度に追加するユーザーの数は、1 -{{.MaxAmount}} の範囲にする必要があります。" - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: configの読み込みに失敗しました - database: - connection_failed: - other: データベースの接続が失敗しました - create_table_failed: - other: テーブルの作成に失敗しました - install: - create_config_failed: - other: config.yaml を作成できません。 - upload: - unsupported_file_format: - other: サポートされていないファイル形式です。 - site_info: - config_not_found: - other: configが見つかりません。 - badge: - object_not_found: - other: バッジオブジェクトが見つかりません - reason: - spam: - name: - other: スパム - desc: - other: この投稿は広告です。現在のトピックには有用ではありません。 - rude_or_abusive: - name: - other: 誹謗中傷 - desc: - other: "合理的な人は、このコンテンツを尊重する言説には不適切と判断するでしょう。" - a_duplicate: - name: - other: 重複 - desc: - other: この質問は以前に質問されており、すでに回答があります。 - placeholder: - other: 既存の質問リンクを入力してください - not_a_answer: - name: - other: 回答では無い - desc: - other: "これは答えとして投稿されましたが、質問に答えようとしません。 それはおそらく編集、コメント、別の質問、または完全に削除されるべきです。" - no_longer_needed: - name: - other: 必要では無い - desc: - other: このコメントは古く、この投稿とは関係がありません。 - something: - name: - other: その他 - desc: - other: 上記以外の理由でスタッフの注意が必要です。 - placeholder: - other: あなたが懸念していることを私たちに教えてください - community_specific: - name: - other: コミュニティ固有の理由です - desc: - other: この質問はコミュニティガイドラインを満たしていません - not_clarity: - name: - other: 詳細や明快さが必要です - desc: - other: この質問には現在複数の質問が含まれています。1つの問題にのみ焦点を当てる必要があります。 - looks_ok: - name: - other: LGTM - desc: - other: この投稿はそのままで良く、改善する必要はありません! - needs_edit: - name: - other: 編集する必要があったため変更しました。 - desc: - other: 自分自身でこの投稿の問題を改善し修正します。 - needs_close: - name: - other: クローズする必要がある - desc: - other: クローズされた質問は回答できませんが、編集、投票、コメントはできます。 - needs_delete: - name: - other: 削除が必要です - desc: - other: この投稿は削除されました - question: - close: - duplicate: - name: - other: スパム - desc: - other: この質問は以前に質問されており、すでに回答があります。 - guideline: - name: - other: コミュニティ固有の理由です - desc: - other: この質問はコミュニティガイドラインを満たしていません - multiple: - name: - other: 詳細や明快さが必要です - desc: - other: この質問には現在複数の質問が含まれています。1つの問題にのみ焦点を当てる必要があります。 - other: - name: - other: その他 - desc: - other: 上記以外の理由でスタッフの注意が必要です。 - operation_type: - asked: - other: 質問済み - answered: - other: 回答済み - modified: - other: 修正済み - deleted_title: - other: 質問を削除 - questions_title: - other: 質問 - tag: - tags_title: - other: タグ - no_description: - other: タグには説明がありません。 - notification: - action: - update_question: - other: 質問を更新 - answer_the_question: - other: 回答済みの質問 - update_answer: - other: 回答を更新 - accept_answer: - other: 承認された回答 - comment_question: - other: コメントされた質問 - comment_answer: - other: コメントされた回答 - reply_to_you: - other: あなたへの返信 - mention_you: - other: メンションされました - your_question_is_closed: - other: あなたの質問はクローズされました - your_question_was_deleted: - other: あなたの質問は削除されました - your_answer_was_deleted: - other: あなたの質問は削除されました - your_comment_was_deleted: - other: あなたのコメントは削除されました - up_voted_question: - other: 質問を高評価 - down_voted_question: - other: 質問を低評価 - up_voted_answer: - other: 回答を高評価 - down_voted_answer: - other: 回答を低評価 - up_voted_comment: - other: コメントを高評価 - invited_you_to_answer: - other: あなたを回答に招待しました - earned_badge: - other: '"{{.BadgeName}}"バッジを獲得しました' - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] 新しいメールアドレスを確認してください" - body: - other: "{{.SiteName}}の新しいメールアドレスを確認しリンクをクリックしてください。
        \n{{.ChangeEmailUrl}}

        \n\n身に覚えがない場合はこのメールを無視してください。\n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。" - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} があなたの質問に回答しました" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \n{{.SiteName}}で確認

        \n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} があなたを回答に招待しました" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        あなたなら答えを知っているかもしれません。

        \n{{.SiteName}}で確認

        \n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。

        \n\n配信停止\n" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} があなたの投稿にコメントしました" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nで確認{{.SiteName}}

        \n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。

        \n\n配信停止" - new_question: - title: - other: "[{{.SiteName}}] 新しい質問: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] パスワードリセット" - body: - other: "{{.SiteName}}であなたのパスワードをリセットしようとしました。

        \n\nもしお心当たりがない場合は、このメールを無視してください。

        \n\n新しいパスワードを設定するには、以下のリンクをクリックしてください。
        \n{{.PassResetUrl}}\n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。

        \n" - register: - title: - other: "[{{.SiteName}}] 新しいアカウントを確認" - body: - other: "{{.SiteName}}へようこそ!

        \n\n以下のリンクをクリックして、新しいアカウントを確認・有効化してください。
        \n{{.RegisterUrl}}

        \n\n上記のリンクがクリックできない場合は、リンクをコピーしてブラウザのアドレスバーに貼り付けてみてください。\n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。

        " - test: - title: - other: "[{{.SiteName}}] テストメール" - body: - other: "これはテストメールです。\n

        \n\n--
        \n注: これはシステムからの自動メールです。このメッセージに返信しないでください。

        " - action_activity_type: - upvote: - other: 高評価 - upvoted: - other: 高評価しました - downvote: - other: 低評価 - downvoted: - other: 低評価しました - accept: - other: 承認 - accepted: - other: 承認済み - edit: - other: 編集 - review: - queued_post: - other: キューに入れられた投稿 - flagged_post: - other: 投稿を通報 - suggested_post_edit: - other: 提案された編集 - reaction: - tooltip: - other: "{{ .Names }} と {{ .Count }} もっと..." - badge: - default_badges: - autobiographer: - name: - other: 自伝作家 - desc: - other: プロファイル 情報を入力しました。 - certified: - name: - other: 認定済み - desc: - other: 新しいユーザーがチュートリアルを完了しました。 - editor: - name: - other: 編集者 - desc: - other: 最初の投稿の編集 - first_flag: - name: - other: 初めての報告 - desc: - other: 初めての報告 - first_upvote: - name: - other: はじめての高評価 - desc: - other: はじめて投稿に高評価した - first_link: - name: - other: はじめてのリンク - desc: - other: First added a link to another post. - first_reaction: - name: - other: 初めてのリアクション - desc: - other: はじめて投稿にリアクションした - first_share: - name: - other: はじめての共有 - desc: - other: はじめて投稿を共有した - scholar: - name: - other: 研究生 - desc: - other: 質問をして回答が承認された - commentator: - name: - other: コメントマン - desc: - other: 5つコメントをした - new_user_of_the_month: - name: - other: 今月の新しいユーザー - desc: - other: 最初の月に優れた貢献 - read_guidelines: - name: - other: ガイドラインを読んだ - desc: - other: '「コミュニティガイドライン」をご覧ください。' - reader: - name: - other: リーダー - desc: - other: 10以上の回答を持つトピックのすべての回答を読んだ - welcome: - name: - other: ようこそ! - desc: - other: 高評価をされた - nice_share: - name: - other: Nice Share - desc: - other: 25人の訪問者と投稿を共有した - good_share: - name: - other: Good Share - desc: - other: 300の訪問者と投稿を共有した - great_share: - name: - other: Great Share - desc: - other: 1000人の訪問者と投稿を共有した - out_of_love: - name: - other: お隣さん - desc: - other: 1日に50票いれた - higher_love: - name: - other: お友達 - desc: - other: 5日目に50回投票した - crazy_in_love: - name: - other: 崇拝 - desc: - other: 一日に50回投票を20回した - promoter: - name: - other: プロモーター - desc: - other: ユーザーを招待した - campaigner: - name: - other: キャンペーン - desc: - other: 3人のベーシックユーザーを招待しました。 - champion: - name: - other: チャンピオン - desc: - other: 5人のメンバーを招待しました。 - thank_you: - name: - other: Thank you - desc: - other: 投稿が20件!投票数が10件! - gives_back: - name: - other: 返品 - desc: - other: 投稿が100件 !?!? 投票数が100件 !?!? - empathetic: - name: - other: 共感性 - desc: - other: 500の投稿を投票し、1000の投票を与えた。 - enthusiast: - name: - other: 楽天家 - desc: - other: 10日間連続ログイン - aficionado: - name: - other: Aficionado - desc: - other: 100日連続ログイン!!! - devotee: - name: - other: 献身者 - desc: - other: 365日連続訪問!!!!!!!! - anniversary: - name: - other: 周年記念 - desc: - other: 年に一回は... - appreciated: - name: - other: ありがとう! - desc: - other: 20件の投稿に1件の投票を受け取った - respected: - name: - other: 尊敬される - desc: - other: 100件の投稿で2件の投票を受け取った - admired: - name: - other: 崇拝された - desc: - other: 300の投稿に5票を獲得した - solved: - name: - other: 解決 - desc: - other: 答えを受け入れられた - guidance_counsellor: - name: - other: アドバイザー - desc: - other: 10個の回答が承認された - know_it_all: - name: - other: 物知り博士 - desc: - other: 50個の回答が承認された - solution_institution: - name: - other: 解決機関 - desc: - other: 150個の回答が承認された - nice_answer: - name: - other: 素敵な回答 - desc: - other: 回答スコアは10以上!! - good_answer: - name: - other: 良い回答 - desc: - other: 回答スコアは25以上!?! - great_answer: - name: - other: 素晴らしい回答 - desc: - other: 回答スコアは50以上!!!!1 - nice_question: - name: - other: ナイスな質問 - desc: - other: 質問スコアは10以上!! - good_question: - name: - other: よい質問 - desc: - other: 質問スコアは25以上!?! - great_question: - name: - other: 素晴らしい質問 - desc: - other: 50人の閲覧者!! - popular_question: - name: - other: 人気のある質問 - desc: - other: 500人の閲覧者!!! - notable_question: - name: - other: 注目すべき質問 - desc: - other: 1,000人の閲覧者!!!! - famous_question: - name: - other: 偉大な質問 - desc: - other: 5,000人の閲覧者!!!!! - popular_link: - name: - other: 人気のリンク - desc: - other: 外部リンクを50回クリック - hot_link: - name: - other: 激アツリンク - desc: - other: 外部リンクを300回クリック - famous_link: - name: - other: 有名なリンク - desc: - other: 外部リンクを100回クリック - default_badge_groups: - getting_started: - name: - other: はじめに - community: - name: - other: コミュニティ - posting: - name: - other: 投稿中 -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: 書式設定 - desc: \n - pagination: - prev: 前へ - next: 次へ - page_title: - question: 質問 - questions: 質問 - tag: タグ - tags: タグ - tag_wiki: タグ wiki - create_tag: タグを作成 - edit_tag: タグを編集 - ask_a_question: Create Question - edit_question: 質問を編集 - edit_answer: 回答を編集 - search: 検索 - posts_containing: 記事を含む投稿 - settings: 設定 - notifications: お知らせ - login: ログイン - sign_up: 新規登録 - account_recovery: アカウントの復旧 - account_activation: アカウント有効化 - confirm_email: メールアドレスを確認 - account_suspended: アカウントは凍結されています - admin: 管理者 - change_email: メールアドレスを変更 - install: 回答に応答する - upgrade: 回答を改善する - maintenance: ウェブサイトのメンテナンス - users: ユーザー - oauth_callback: 処理中 - http_404: HTTP エラー 404 - http_50X: HTTP エラー 500 - http_403: HTTP エラー 403 - logout: ログアウト - posts: Posts - notifications: - title: 通知 - inbox: 受信トレイ - achievement: 実績 - new_alerts: 新しい通知 - all_read: すべて既読にする - show_more: もっと見る - someone: 誰か - inbox_type: - all: すべて - posts: 投稿 - invites: 招待 - votes: 投票 - answer: 回答 - question: 質問 - badge_award: バッジ - suspended: - title: あなたのアカウントは停止されています。 - until_time: "あなたのアカウントは {{ time }} まで停止されました。" - forever: このユーザーは永久に停止されました。 - end: コミュニティガイドラインを満たしていません。 - contact_us: お問い合わせ - editor: - blockquote: - text: 引用 - bold: - text: 強い - chart: - text: チャート - flow_chart: フローチャート - sequence_diagram: シーケンス図 - class_diagram: クラス図 - state_diagram: 状態図 - entity_relationship_diagram: ER図 - user_defined_diagram: ユーザー定義図 - gantt_chart: ガントチャート - pie_chart: 円グラフ - code: - text: コードサンプル - add_code: コードサンプルを追加 - form: - fields: - code: - label: コード - msg: - empty: Code を空にすることはできません。 - language: - label: 言語 - placeholder: 自動検出 - btn_cancel: キャンセル - btn_confirm: 追加 - formula: - text: 数式 - options: - inline: インライン数式 - block: ブロック数式 - heading: - text: 見出し - options: - h1: 見出し1 - h2: 見出し2 - h3: 見出し3 - h4: 見出し4 - h5: 見出し5 - h6: 見出し6 - help: - text: ヘルプ - hr: - text: 水平方向の罫線 - image: - text: 画像 - add_image: 画像を追加する - tab_image: 画像をアップロードする - form_image: - fields: - file: - label: 画像ファイル - btn: 画像を選択する - msg: - empty: ファイルは空にできません。 - only_image: 画像ファイルのみが許可されています。 - max_size: ファイルサイズは {{size}} MBを超えることはできません。 - desc: - label: 説明 - tab_url: 画像URL - form_url: - fields: - url: - label: 画像URL - msg: - empty: 画像のURLは空にできません。 - name: - label: 説明 - btn_cancel: キャンセル - btn_confirm: 追加 - uploading: アップロード中 - indent: - text: インデント - outdent: - text: アウトデント - italic: - text: 斜体 - link: - text: ハイパーリンク - add_link: ハイパーリンクを追加 - form: - fields: - url: - label: URL - msg: - empty: URLを入力してください。 - name: - label: 説明 - btn_cancel: キャンセル - btn_confirm: 追加 - ordered_list: - text: 順序付きリスト - unordered_list: - text: 箇条書きリスト - table: - text: ' テーブル' - heading: 見出し - cell: セル - file: - text: ファイルを添付 - not_supported: "そのファイルタイプをサポートしていません。 {{file_type}} でもう一度お試しください。" - max_size: "添付ファイルサイズは {{size}} MB を超えることはできません。" - close_modal: - title: この投稿を次のように閉じます... - btn_cancel: キャンセル - btn_submit: 送信 - remark: - empty: 入力してください。 - msg: - empty: 理由を選んでください。 - report_modal: - flag_title: この投稿を報告するフラグを立てています... - close_title: この投稿を次のように閉じます... - review_question_title: 質問の編集をレビュー - review_answer_title: 答えをレビューする - review_comment_title: レビューコメント - btn_cancel: キャンセル - btn_submit: 送信 - remark: - empty: 入力してください。 - msg: - empty: 理由を選んでください。 - not_a_url: URL形式が正しくありません。 - url_not_match: URL の原点が現在のウェブサイトと一致しません。 - tag_modal: - title: 新しいタグを作成 - form: - fields: - display_name: - label: 表示名 - msg: - empty: 表示名を入力してください。 - range: 表示名は最大 35 文字までです。 - slug_name: - label: URLスラッグ - desc: '文字セット「a-z」、「0-9」、「+ # -」を使用する必要があります。' - msg: - empty: URL スラッグを空にすることはできません。 - range: タイトルは最大35文字までです. - character: URL スラグに許可されていない文字セットが含まれています。 - desc: - label: 説明 - revision: - label: 修正 - edit_summary: - label: 概要を編集 - placeholder: >- - 簡単にあなたの変更を説明します(修正スペル、固定文法、改善されたフォーマット) - btn_cancel: キャンセル - btn_submit: 送信 - btn_post: 新しいタグを投稿 - tag_info: - created_at: 作成 - edited_at: 編集済 - history: 履歴 - synonyms: - title: 類義語 - text: 次のタグが再マップされます - empty: 同義語は見つかりません。 - btn_add: 同義語を追加 - btn_edit: 編集 - btn_save: 保存 - synonyms_text: 次のタグが再マップされます - delete: - title: このタグを削除 - tip_with_posts: >- -

        同義語でタグを削除することはできません。

        最初にこのタグから同義語を削除してください。

        - tip_with_synonyms: >- -

        同義語でタグを削除することはできません。

        最初にこのタグから同義語を削除してください。

        - tip: 本当に削除してもよろしいですか? - close: クローズ - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: タグを編集 - default_reason: タグを編集 - default_first_reason: タグを追加 - btn_save_edits: 編集を保存 - btn_cancel: キャンセル - dates: - long_date: MMM D - long_date_with_year: "YYYY年MM月D日" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: 今 - x_seconds_ago: "{{count}}秒前" - x_minutes_ago: "{{count}}分前" - x_hours_ago: "{{count}}時間前" - hour: 時 - day: 日 - hours: 時 - days: 日 - month: month - months: months - year: year - reaction: - heart: ハート - smile: 笑顔 - frown: 眉をひそめる - btn_label: リアクションの追加または削除 - undo_emoji: '{{ emoji }} のリアクションを元に戻す' - react_emoji: '{{ emoji }} に反応する' - unreact_emoji: '{{ emoji }} に反応しない' - comment: - btn_add_comment: コメントを追加 - reply_to: 返信: - btn_reply: 返信 - btn_edit: 編集 - btn_delete: 削除 - btn_flag: フラグ - btn_save_edits: 編集内容を保存 - btn_cancel: キャンセル - show_more: "{{count}} 件のその他のコメント" - tip_question: >- - コメントを使用して、より多くの情報を求めたり、改善を提案したりします。コメントで質問に答えることは避けてください。 - tip_answer: >- - コメントを使用して他のユーザーに返信したり、変更を通知します。新しい情報を追加する場合は、コメントの代わりに投稿を編集します。 - tip_vote: 投稿に役に立つものを追加します - edit_answer: - title: 回答を編集 - default_reason: 回答を編集 - default_first_reason: 回答を追加 - form: - fields: - revision: - label: 修正 - answer: - label: 回答 - feedback: - characters: コンテンツは6文字以上でなければなりません。 - edit_summary: - label: 概要を編集 - placeholder: >- - 簡単にあなたの変更を説明します(修正スペル、固定文法、改善されたフォーマット) - btn_save_edits: 編集を保存 - btn_cancel: キャンセル - tags: - title: タグ - sort_buttons: - popular: 人気 - name: 名前 - newest: 最新 - button_follow: フォロー - button_following: フォロー中 - tag_label: 質問 - search_placeholder: タグ名でフィルタ - no_desc: タグには説明がありません。 - more: もっと見る - wiki: Wiki - ask: - title: Create Question - edit_title: 質問を編集 - default_reason: 質問を編集 - default_first_reason: Create question - similar_questions: 類似の質問 - form: - fields: - revision: - label: 修正 - title: - label: タイトル - placeholder: What's your topic? Be specific. - msg: - empty: タイトルを空にすることはできません。 - range: タイトルは最大150文字までです - body: - label: 本文 - msg: - empty: 本文を空にすることはできません。 - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: タグ - msg: - empty: 少なくとも一つ以上のタグが必要です。 - answer: - label: 回答 - msg: - empty: 回答は空欄にできません - edit_summary: - label: 概要を編集 - placeholder: >- - 簡単にあなたの変更を説明します(修正スペル、固定文法、改善されたフォーマット) - btn_post_question: 質問を投稿する - btn_save_edits: 編集内容を保存 - answer_question: ご自身の質問に答えてください - post_question&answer: 質問と回答を投稿する - tag_selector: - add_btn: タグを追加 - create_btn: 新しタグを作成 - search_tag: タグを検索 - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: 一致するタグはありません - tag_required_text: 必須タグ (少なくとも 1 つ) - header: - nav: - question: 質問 - tag: タグ - user: ユーザー - badges: バッジ - profile: プロフィール - setting: 設定 - logout: ログアウト - admin: 管理者 - review: レビュー - bookmark: ブックマーク - moderation: モデレーション - search: - placeholder: 検索 - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: 変更 - loading: 読み込み中… - pic_auth_code: - title: CAPTCHA - placeholder: 上記のテキストを入力してください - msg: - empty: Code を空にすることはできません。 - inactive: - first: >- - {{mail}}にアクティベーションメールを送信しました。メールの指示に従ってアカウントをアクティベーションしてください。 - info: "届かない場合は、迷惑メールフォルダを確認してください。" - another: >- - {{mail}}に別のアクティベーションメールを送信しました。 到着には数分かかる場合があります。スパムフォルダを確認してください。 - btn_name: 認証メールを再送信 - change_btn_name: メールアドレスを変更 - msg: - empty: 空にすることはできません - resend_email: - url_label: 本当に認証メールを再送信してもよろしいですか? - url_text: ユーザーに上記のアクティベーションリンクを渡すこともできます。 - login: - login_to_continue: ログインして続行 - info_sign: アカウントをお持ちではありませんか?<1>サインアップ - info_login: すでにアカウントをお持ちですか?<1>ログイン - agreements: 登録することにより、<1>プライバシーポリシーおよび<3>サービス規約に同意するものとします。 - forgot_pass: パスワードをお忘れですか? - name: - label: 名前 - msg: - empty: 名前を空にすることはできません。 - range: 2~30文字の名前を設定してください。 - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: メールアドレス - msg: - empty: メールアドレスを入力してください。 - password: - label: パスワード - msg: - empty: パスワードを入力してください。 - different: 入力されたパスワードが一致しません - account_forgot: - page_title: パスワードを忘れた方はこちら - btn_name: 回復用のメールを送る - send_success: >- - アカウントが {{mail}}と一致する場合は、パスワードをすぐにリセットする方法に関するメールが送信されます。 - email: - label: メールアドレス - msg: - empty: メールアドレスを入力してください。 - change_email: - btn_cancel: キャンセル - btn_update: メールアドレスを更新 - send_success: >- - アカウントが {{mail}}と一致する場合は、パスワードをすぐにリセットする方法に関するメールが送信されます。 - email: - label: 新しいメールアドレス - msg: - empty: メールアドレス欄を空白にしておくことはできません - oauth: - connect: '{{ auth_name }} と接続' - remove: '{{ auth_name }} を削除' - oauth_bind_email: - subtitle: アカウントに回復用のメールアドレスを追加します。 - btn_update: メールアドレスを更新 - email: - label: メールアドレス - msg: - empty: メールアドレスは空にできません。 - modal_title: このメールアドレスはすでに存在しています。 - modal_content: このメールアドレスは既に登録されています。既存のアカウントに接続してもよろしいですか? - modal_cancel: メールアドレスを変更する - modal_confirm: 既存のアカウントに接続 - password_reset: - page_title: パスワード再設定 - btn_name: パスワードをリセット - reset_success: >- - パスワードを変更しました。ログインページにリダイレクトされます。 - link_invalid: >- - 申し訳ありませんが、このパスワードリセットのリンクは無効になりました。パスワードが既にリセットされている可能性がありますか? - to_login: ログインページへ - password: - label: パスワード - msg: - empty: パスワードを入力してください。 - length: 長さは 8 から 32 の間である必要があります - different: 両側に入力されたパスワードが一致しません - password_confirm: - label: 新しいパスワードの確認 - settings: - page_title: 設定 - goto_modify: 変更を開く - nav: - profile: プロフィール - notification: お知らせ - account: アカウント - interface: 外観 - profile: - heading: プロフィール - btn_name: 保存 - display_name: - label: 表示名 - msg: 表示名は必須です。 - msg_range: Display name must be 2-30 characters in length. - username: - label: ユーザー名 - caption: ユーザーは "@username" としてあなたをメンションできます。 - msg: ユーザー名は空にできません。 - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: プロフィール画像 - gravatar: Gravatar - gravatar_text: 画像を変更できます: - custom: カスタム - custom_text: 画像をアップロードできます。 - default: システム - msg: アバターをアップロードしてください - bio: - label: 自己紹介 - website: - label: ウェブサイト - placeholder: "http://example.com" - msg: ウェブサイトの形式が正しくありません - location: - label: ロケーション - placeholder: "都道府県,国" - notification: - heading: メール通知 - turn_on: ONにする - inbox: - label: 受信トレイの通知 - description: 質問、コメント、招待状などへの回答。 - all_new_question: - label: すべての新規質問 - description: すべての新しい質問の通知を受け取ります。週に最大50問まで。 - all_new_question_for_following_tags: - label: 以下のタグに対するすべての新しい質問 - description: タグをフォローするための新しい質問の通知を受け取る。 - account: - heading: アカウント - change_email_btn: メールアドレスを変更する - change_pass_btn: パスワードを変更する - change_email_info: >- - このアドレスにメールを送信しました。メールの指示に従って確認処理を行ってください。 - email: - label: メールアドレス - new_email: - label: 新しいメールアドレス - msg: 新しいメールアドレスは空にできません。 - pass: - label: 現在のパスワード - msg: パスワードは空白にできません - password_title: パスワード - current_pass: - label: 現在のパスワード - msg: - empty: 現在のパスワードが空欄です - length: 長さは 8 から 32 の間である必要があります. - different: パスワードが一致しません。 - new_pass: - label: 新しいパスワード - pass_confirm: - label: 新しいパスワードの確認 - interface: - heading: 外観 - lang: - label: インタフェース言語 - text: ユーザーインターフェイスの言語。ページを更新すると変更されます。 - my_logins: - title: ログイン情報 - label: これらのアカウントを使用してログインまたはこのサイトでサインアップします。 - modal_title: ログイン情報を削除 - modal_content: このログイン情報をアカウントから削除してもよろしいですか? - modal_confirm_btn: 削除 - remove_success: 削除に成功しました - toast: - update: 更新に成功しました - update_password: パスワードの変更に成功しました。 - flag_success: フラグを付けてくれてありがとう - forbidden_operate_self: 自分自身で操作することはできません - review: レビュー後にあなたのリビジョンが表示されます。 - sent_success: 正常に送信されました。 - related_question: - title: Related - answers: 回答 - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: People Asked - desc: Select people who you think might know the answer. - invite: 回答に招待する - add: ユーザーを追加 - search: ユーザーを検索 - question_detail: - action: 動作 - created: Created - Asked: 質問済み - asked: 質問済み - update: 修正済み - Edited: Edited - edit: 編集済み - commented: コメントしました - Views: 閲覧回数 - Follow: フォロー - Following: フォロー中 - follow_tip: この質問をフォローして通知を受け取る - answered: 回答済み - closed_in: クローズまで - show_exist: 既存の質問を表示します - useful: 役に立った - question_useful: それは有用で明確です。 - question_un_useful: 不明確または有用ではない - question_bookmark: この質問をブックマークする - answer_useful: 役に立った - answer_un_useful: 役に立たない - answers: - title: 回答 - score: スコア - newest: 最新 - oldest: 古い順 - btn_accept: 承認 - btn_accepted: 承認済み - write_answer: - title: あなたの回答 - edit_answer: 既存の回答を編集する - btn_name: 回答を投稿する - add_another_answer: 別の回答を追加 - confirm_title: 回答を続ける - continue: 続行 - confirm_info: >- -

        本当に別の答えを追加したいのですか?

        代わりに、編集リンクを使って既存の答えを洗練させ、改善することができます。

        - empty: 回答は空欄にできません - characters: コンテンツは6文字以上でなければなりません。 - tips: - header_1: ご回答ありがとうございます。 - li1_1: " 必ず質問に答えてください。詳細を述べ、あなたの研究を共有してください。\n" - li1_2: 参考文献や個人的な経験による裏付けを取ること。. - header_2: しかし、 を避けてください... - li2_1: 助けを求める、説明を求める、または他の答えに応答する。 - reopen: - confirm_btn: 再オープン - title: この投稿を再度開く - content: 再オープンしてもよろしいですか? - list: - confirm_btn: 一覧 - title: この投稿の一覧 - content: 一覧表示してもよろしいですか? - unlist: - confirm_btn: 限定公開にする - title: この投稿を元に戻す - content: 本当に元に戻しますか? - pin: - title: この投稿をピン留めする - content: "グローバルに固定してもよろしいですか?\nこの投稿はすべての投稿リストの上部に表示されます。" - confirm_btn: ピン留めする - delete: - title: この投稿を削除 - question: >- -

        承認された回答を削除することはお勧めしません。削除すると、今後の読者がこの知識を得られなくなってしまうからです。

        承認された回答を繰り返し削除すると、回答機能が制限され、アカウントがブロックされる場合があります。本当に削除しますか? - - answer_accepted: >- -

        承認された回答を削除することはお勧めしません。削除すると、今後の読者がこの知識を得られなくなってしまうからです。

        承認された回答を繰り返し削除すると、回答機能が制限され、アカウントがブロックされる場合があります。本当に削除しますか? - - other: 本当に削除してもよろしいですか? - tip_answer_deleted: この回答は削除されました - undelete_title: この投稿を元に戻す - undelete_desc: 本当に元に戻しますか? - btns: - confirm: 確認 - cancel: キャンセル - edit: 編集 - save: 保存 - delete: 削除 - undelete: 元に戻す - list: 限定公開を解除する - unlist: 限定公開にする - unlisted: 限定公開済み - login: ログイン - signup: 新規登録 - logout: ログアウト - verify: 認証 - create: Create - approve: 承認 - reject: 却下 - skip: スキップする - discard_draft: 下書きを破棄 - pinned: ピン留めしました - all: すべて - question: 質問 - answer: 回答 - comment: コメント - refresh: 更新 - resend: 再送 - deactivate: 無効化する - active: 有効 - suspend: 凍結 - unsuspend: 凍結解除 - close: クローズ - reopen: 再オープン - ok: OK - light: ライト - dark: ダーク - system_setting: システム設定 - default: 既定 - reset: リセット - tag: タグ - post_lowercase: 投稿 - filter: フィルター - ignore: 除外 - submit: 送信 - normal: 通常 - closed: クローズ済み - deleted: 削除済み - deleted_permanently: Deleted permanently - pending: 処理待ち - more: もっと見る - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: 検索結果 - keywords: キーワード - options: オプション - follow: フォロー - following: フォロー中 - counts: "結果:{{count}}" - counts_loading: "... Results" - more: もっと見る - sort_btns: - relevance: 関連性 - newest: 最新 - active: アクティブ - score: スコア - more: もっと見る - tips: - title: 詳細検索のヒント - tag: "<1>[tag] タグで検索" - user: "<1>ユーザー:ユーザー名作成者による検索" - answer: "<1>回答:0未回答の質問" - score: "<1>スコア:33以上のスコアを持つ投稿" - question: "<1>質問質問を検索" - is_answer: "<1>は答え答えを検索" - empty: 何も見つかりませんでした。
        別のキーワードまたはそれ以下の特定のキーワードをお試しください。 - share: - name: シェア - copy: リンクをコピー - via: 投稿を共有... - copied: コピーしました - facebook: Facebookで共有 - twitter: Share to X - cannot_vote_for_self: 自分の投稿には投票できません。 - modal_confirm: - title: エラー... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: 新しいアカウントが確認されました。ホームページにリダイレクトされます。 - link: ホームページへ - oops: おっと! - invalid: 使用したリンクは機能しません。 - confirm_new_email: メールアドレスが更新されました。 - confirm_new_email_invalid: >- - 申し訳ありませんが、この確認リンクは無効です。メールアドレスが既に変更されている可能性があります。 - unsubscribe: - page_title: 購読解除 - success_title: 購読解除成功 - success_desc: 配信リストから削除され、その他のメールの送信が停止されました。 - link: 設定の変更 - question: - following_tags: フォロー中のタグ - edit: 編集 - save: 保存 - follow_tag_tip: タグに従って質問のリストをキュレートします。 - hot_questions: ホットな質問 - all_questions: すべての質問 - x_questions: "{{ count }} の質問" - x_answers: "{{ count }} の回答" - x_posts: "{{ count }} Posts" - questions: 質問 - answers: 回答 - newest: 最新 - active: 有効 - hot: 人気 - frequent: Frequent - recommend: おすすめ - score: スコア - unanswered: 未回答 - modified: 修正済み - answered: 回答済み - asked: 質問済み - closed: 解決済み - follow_a_tag: タグをフォロー - more: その他 - personal: - overview: 概要 - answers: 回答 - answer: 回答 - questions: 質問 - question: 質問 - bookmarks: ブックマーク - reputation: 評判 - comments: コメント - votes: 投票 - badges: バッジ - newest: 最新 - score: スコア - edit_profile: プロファイルを編集 - visited_x_days: "{{ count }}人の閲覧者" - viewed: 閲覧回数 - joined: 参加しました - comma: "," - last_login: 閲覧数 - about_me: 自己紹介 - about_me_empty: "// Hello, World !" - top_answers: よくある回答 - top_questions: よくある質問 - stats: 統計情報 - list_empty: 投稿が見つかりませんでした。
        他のタブを選択しますか? - content_empty: 投稿が見つかりませんでした。 - accepted: 承認済み - answered: 回答済み - asked: 質問済み - downvoted: 低評価しました - mod_short: MOD - mod_long: モデレーター - x_reputation: 評価 - x_votes: 投票を受け取りました - x_answers: 回答 - x_questions: 質問 - recent_badges: 最近のバッジ - install: - title: Installation - next: 次へ - done: 完了 - config_yaml_error: config.yaml を作成できません。 - lang: - label: 言語を選択してください - db_type: - label: データベースエンジン - db_username: - label: ユーザー名 - placeholder: root - msg: ユーザー名は空にできません。 - db_password: - label: パスワード - placeholder: root - msg: パスワードを入力してください。 - db_host: - label: データベースのホスト。 - placeholder: "db:3306" - msg: データベースホストは空にできません。 - db_name: - label: データベース名 - placeholder: 回答 - msg: データベース名を空にすることはできません。 - db_file: - label: データベースファイル - placeholder: /data/answer.db - msg: データベースファイルは空にできません。 - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: config.yamlを作成 - label: config.yaml ファイルが作成されました。 - desc: >- - <1>/var/www/xxx/ディレクトリに<1>config.yamlファイルを手動で作成し、その中に次のテキストを貼り付けます。 - info: 完了したら、「次へ」ボタンをクリックします。 - site_information: サイト情報 - admin_account: 管理者アカウント - site_name: - label: サイト名: - msg: サイト名は空にできません. - msg_max_length: サイト名は最大30文字でなければなりません。 - site_url: - label: サイトURL - text: あなたのサイトのアドレス - msg: - empty: サイト URL は空にできません. - incorrect: サイトURLの形式が正しくありません。 - max_length: サイトのURLは最大512文字でなければなりません - contact_email: - label: 連絡先メール アドレス - text: このサイトを担当するキーコンタクトのメールアドレスです。 - msg: - empty: 連絡先メールアドレスを空にすることはできません。 - incorrect: 連絡先メールアドレスの形式が正しくありません。 - login_required: - label: 非公開 - switch: ログインが必要です - text: ログインしているユーザーのみがこのコミュニティにアクセスできます。 - admin_name: - label: 名前 - msg: 名前を空にすることはできません。 - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: パスワード - text: >- - ログインするにはこのパスワードが必要です。安全な場所に保存してください。 - msg: パスワードは空白にできません - msg_min_length: パスワードは8文字以上でなければなりません。 - msg_max_length: パスワードは最大 32 文字でなければなりません。 - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: メールアドレス - text: ログインするにはこのメールアドレスが必要です。 - msg: - empty: メールアドレスは空にできません。 - incorrect: メールアドレスの形式が正しくありません. - ready_title: サイトの準備ができました - ready_desc: >- - もっと設定を変更したいと思ったことがある場合は、<1>管理者セクションをご覧ください。サイトメニューで見つけてください。 - good_luck: "楽しんで、幸運を!" - warn_title: 警告 - warn_desc: >- - ファイル<1>config.yamlは既に存在します。このファイルのいずれかの設定アイテムをリセットする必要がある場合は、最初に削除してください。 - install_now: <1>今すぐインストールを試してみてください。 - installed: 既にインストール済みです - installed_desc: >- - 既にインストールされているようです。再インストールするには、最初に古いデータベーステーブルをクリアしてください。 - db_failed: データベースの接続が失敗しました - db_failed_desc: >- - これは、<1>設定内のデータベース情報を意味します。 amlファイルが正しくないか、データベースサーバーとの連絡先が確立できませんでした。ホストのデータベースサーバーがダウンしている可能性があります。 - counts: - views: ビュー - votes: 投票数 - answers: 回答 - accepted: 承認済み - page_error: - http_error: HTTP Error {{ code }} - desc_403: このページにアクセスする権限がありません。 - desc_404: 残念ながら、このページは存在しません。 - desc_50X: サーバーにエラーが発生し、リクエストを完了できませんでした。 - back_home: ホームページに戻ります - page_maintenance: - desc: "メンテナンス中です。まもなく戻ります。" - nav_menus: - dashboard: ダッシュボード - contents: コンテンツ - questions: 質問 - answers: 回答 - users: ユーザー - badges: バッジ - flags: フラグ - settings: 設定 - general: 一般 - interface: 外観 - smtp: SMTP - branding: ブランディング - legal: 法的事項 - write: 書き - terms: Terms - tos: 利用規約 - privacy: プライバシー - seo: SEO - customize: カスタマイズ - themes: テーマ - login: ログイン - privileges: 特典 - plugins: プラグイン - installed_plugins: 使用中のプラグイン - apperance: Appearance - website_welcome: '{{site_name}} へようこそ' - user_center: - login: ログイン - qrcode_login_tip: QRコードをスキャンしてログインするには {{ agentName }} を使用してください。 - login_failed_email_tip: ログインに失敗しました。もう一度やり直す前に、このアプリがあなたのメール情報にアクセスすることを許可してください。 - badges: - modal: - title: お疲れ様でした! - content: 新しいバッジを獲得しました。 - close: クローズ - confirm: バッジを表示 - title: バッジ - awarded: 受賞済み - earned_×: 獲得×{{ number }} - ×_awarded: "{{ number }} 受賞" - can_earn_multiple: これを複数回獲得できます。 - earned: 獲得済み - admin: - admin_header: - title: 管理者 - dashboard: - title: ダッシュボード - welcome: Adminへようこそ! - site_statistics: サイト統計 - questions: "質問:" - resolved: "解決済み:" - unanswered: "未回答:" - answers: "回答:" - comments: "評論:" - votes: "投票:" - users: "ユーザー数:" - flags: "フラグ:" - reviews: "レビュー:" - site_health: サイトの状態 - version: "バージョン:" - https: "HTTPS:" - upload_folder: "フォルダを上げる" - run_mode: "実行中モード:" - private: 非公開 - public: 公開 - smtp: "SMTP:" - timezone: "Timezone:" - system_info: システム情報 - go_version: "バージョン:" - database: "データベース:" - database_size: "データベースのサイズ:" - storage_used: "使用されているストレージ" - uptime: "稼働時間:" - links: リンク - plugins: プラグイン - github: GitHub - blog: ブログ - contact: 連絡先 - forum: Forum - documents: ドキュメント - feedback: フィードバック - support: サポート - review: レビュー - config: 設定 - update_to: 更新日時 - latest: 最新 - check_failed: チェックに失敗しました - "yes": "はい" - "no": "いいえ" - not_allowed: 許可されていません - allowed: 許可 - enabled: 有効 - disabled: 無効 - writable: 書き込み可 - not_writable: 書き込み不可 - flags: - title: フラグ - pending: 処理待ち - completed: 完了済 - flagged: フラグ付き - flagged_type: フラグを立てた {{ type }} - created: 作成 - action: 動作 - review: レビュー - user_role_modal: - title: ユーザーロールを変更... - btn_cancel: キャンセル - btn_submit: 送信 - new_password_modal: - title: 新しいパスワードを設定 - form: - fields: - password: - label: パスワード - text: ユーザーはログアウトされ、再度ログインする必要があります。 - msg: パスワードの長さは 8 ~ 32 文字である必要があります。 - btn_cancel: キャンセル - btn_submit: 送信 - edit_profile_modal: - title: プロファイルを編集 - form: - fields: - display_name: - label: 表示名 - msg_range: Display name must be 2-30 characters in length. - username: - label: ユーザー名 - msg_range: Username must be 2-30 characters in length. - email: - label: メールアドレス - msg_invalid: 無効なメールアドレス - edit_success: 更新が成功しました - btn_cancel: キャンセル - btn_submit: 送信 - user_modal: - title: 新しいユーザーを追加 - form: - fields: - users: - label: ユーザーを一括追加 - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: '「名前、メールアドレス、パスワード」をカンマで区切ってください。' - msg: "ユーザーのメールアドレスを1行に1つ入力してください。" - display_name: - label: 表示名 - msg: 表示名の長さは 2 ~ 30 文字にする必要があります。 - email: - label: メールアドレス - msg: メールアドレスが無効です。 - password: - label: パスワード - msg: パスワードの長さは 8 ~ 32 文字である必要があります。 - btn_cancel: キャンセル - btn_submit: 送信 - users: - title: ユーザー - name: 名前 - email: メールアドレス - reputation: 評価 - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: ステータス - role: ロール - action: 操作 - change: 変更 - all: すべて - staff: スタッフ - more: もっと見る - inactive: 非アクティブ - suspended: 凍結済み - deleted: 削除済み - normal: 通常 - Moderator: モデレーター - Admin: 管理者 - User: ユーザー - filter: - placeholder: "ユーザー名でフィルタ" - set_new_password: 新しいパスワードを設定します。 - edit_profile: プロファイルを編集 - change_status: ステータスを変更 - change_role: ロールを変更 - show_logs: ログを表示 - add_user: ユーザを追加 - deactivate_user: - title: ユーザーを非アクティブにする - content: アクティブでないユーザーはメールアドレスを再認証する必要があります。 - delete_user: - title: このユーザの削除 - content: このユーザーを削除してもよろしいですか?これは永久的です! - remove: このコンテンツを削除 - label: すべての質問、回答、コメントなどを削除 - text: ユーザーのアカウントのみ削除したい場合は、これを確認しないでください。 - suspend_user: - title: ユーザーをサスペンドにする - content: 一時停止中のユーザーはログインできません。 - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: 質問 - unlisted: 限定公開済み - post: 投稿 - votes: 投票 - answers: 回答 - created: 作成 - status: ステータス - action: 動作 - change: 変更 - pending: 処理待ち - filter: - placeholder: "タイトル、質問:id でフィルター" - answers: - page_title: 回答 - post: 投稿 - votes: 投票 - created: 作成 - status: ステータス - action: 操作 - change: 変更 - filter: - placeholder: "タイトル、質問:id でフィルター" - general: - page_title: 一般 - name: - label: サイト名 - msg: サイト名は空にできません. - text: "タイトルタグで使用されるこのサイトの名前。" - site_url: - label: サイトURL - msg: サイト URL は空にできません. - validate: 正しいURLを入力してください。 - text: あなたのサイトのアドレス - short_desc: - label: 短いサイトの説明 - msg: 短いサイト説明は空にできません. - text: "ホームページのタイトルタグで使用されている簡単な説明。" - desc: - label: サイトの説明 - msg: サイト説明を空にすることはできません。 - text: "メタ説明タグで使用されるように、このサイトを1つの文で説明します。" - contact_email: - label: 連絡先メール アドレス - msg: 連絡先メールアドレスを空にすることはできません。 - validate: 連絡先のメールアドレスが無効です。 - text: このサイトを担当するキーコンタクトのメールアドレスです。 - check_update: - label: ソフトウェアアップデート - text: 自動的に更新を確認 - interface: - page_title: 外観 - language: - label: インタフェース言語 - msg: インターフェース言語は空にできません。 - text: ユーザーインターフェイスの言語。ページを更新すると変更されます。 - time_zone: - label: タイムゾーン - msg: タイムゾーンを空にすることはできません。 - text: あなたのタイムゾーンを選択してください。 - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: 差出人 - msg: 差出人メールアドレスは空にできません。 - text: 送信元のメールアドレス - from_name: - label: 差出人名 - msg: 差出人名は空にできません - text: メールの送信元の名前 - smtp_host: - label: SMTP ホスト - msg: SMTPホストは空にできません。 - text: メールサーバー - encryption: - label: 暗号化 - msg: 暗号化は空にできません。 - text: ほとんどのサーバではSSLが推奨されます。 - ssl: SSL - tls: TLS - none: なし - smtp_port: - label: SMTPポート - msg: SMTPポートは1〜65535でなければなりません。 - text: メールサーバーへのポート番号 - smtp_username: - label: SMTPユーザ名 - msg: SMTP ユーザー名を空にすることはできません。 - smtp_password: - label: SMTPパスワード - msg: SMTP パスワードを入力してください。 - test_email_recipient: - label: テストメールの受信者 - text: テスト送信を受信するメールアドレスを入力してください。 - msg: テストメールの受信者が無効です - smtp_authentication: - label: 認証を有効にする - title: SMTP認証 - msg: SMTP認証は空にできません。 - "yes": "はい" - "no": "いいえ" - branding: - page_title: ブランディング - logo: - label: ロゴ - msg: ロゴは空にできません。 - text: あなたのサイトの左上にあるロゴ画像。 高さが56、アスペクト比が3:1を超える広い矩形画像を使用します。 空白の場合、サイトタイトルテキストが表示されます。 - mobile_logo: - label: モバイルロゴ - text: サイトのモバイル版で使用されるロゴです。高さが56の横長の長方形の画像を使用してください。空白のままにすると、"ロゴ"設定の画像が使用されます。 - square_icon: - label: アイコン画像 - msg: アイコン画像は空にできません。 - text: メタデータアイコンのベースとして使用される画像。理想的には512x512より大きくなければなりません。 - favicon: - label: Favicon - text: あなたのサイトのファビコン。CDN上で正しく動作するにはpngである必要があります。 32x32にリサイズされます。空白の場合は、"正方形のアイコン"が使用されます。 - legal: - page_title: 法的情報 - terms_of_service: - label: 利用規約 - text: "ここで利用規約のサービスコンテンツを追加できます。すでに他の場所でホストされているドキュメントがある場合は、こちらにフルURLを入力してください。" - privacy_policy: - label: プライバシーポリシー - text: "ここにプライバシーポリシーの内容を追加できます。すでに他の場所でホストされているドキュメントを持っている場合は、こちらにフルURLを入力してください。" - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: 編集 - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: 回答を書く - label: 各ユーザーは同じ質問に対して1つの回答しか書けません - text: "ユーザが同じ質問に複数の回答を書き込めるようにするにはオフにします。これにより回答がフォーカスされていない可能性があります。" - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: おすすめタグ - text: "デフォルトでドロップダウンリストに推奨タグが表示されます。" - msg: - contain_reserved: "推奨されるタグは予約済みタグを含めることはできません" - required_tag: - title: 必須タグを設定 - label: 必須タグに「推奨タグ」を設定 - text: "新しい質問には少なくとも1つの推奨タグが必要です。" - reserved_tags: - label: 予約済みタグ - text: "予約済みのタグはモデレータのみ使用できます。" - image_size: - label: 画像ファイルの最大サイズ(MB) - text: "画像ファイルの最大アップロードサイズ。" - attachment_size: - label: 添付ファイルの最大サイズ (MB) - text: "添付ファイルの最大アップロードサイズ。" - image_megapixels: - label: 画像の最大解像度 - text: "画像ファイルに許可する最大メガピクセル数。" - image_extensions: - label: 認可された画像ファイルの拡張子 - text: "イメージ表示に許可されるファイル拡張子のリスト(コンマで区切り)" - attachment_extensions: - label: 認可された添付ファイルの拡張子 - text: "アップロードを許可するファイル拡張子のリスト(カンマ区切り)\n警告: アップロードを許可するとセキュリティ上の問題が発生する可能性があります。" - seo: - page_title: SEO - permalink: - label: 固定リンク - text: カスタム URL 構造は、ユーザビリティとリンクの前方互換性を向上させることができます。 - robots: - label: robots.txt - text: これにより、関連するサイト設定が永久に上書きされます。 - themes: - page_title: テーマ - themes: - label: テーマ - text: 既存のテーマを選択してください - color_scheme: - label: 配色 - navbar_style: - label: Navbar background style - primary_color: - label: メインカラー - text: テーマで使用される色を変更する - css_and_html: - page_title: CSS と HTML - custom_css: - label: カスタム CSS - text: > - - head: - label: ヘッド - text: > - - header: - label: ヘッダー - text: > - - footer: - label: フッター - text: これは </body> の前に挿入されます。 - sidebar: - label: サイドバー - text: サイドバーに挿入されます。 - login: - page_title: ログイン - membership: - title: メンバー - label: 新しい登録を許可する - text: 誰もが新しいアカウントを作成できないようにするには、オフにしてください。 - email_registration: - title: メールアドレスの登録 - label: メールアドレスの登録を許可 - text: オフにすると、メールで新しいアカウントを作成できなくなります。 - allowed_email_domains: - title: 許可されたメールドメイン - text: ユーザーがアカウントを登録する必要があるメールドメインです。1行に1つのドメインがあります。空の場合は無視されます。 - private: - title: 非公開 - label: ログインが必要です - text: ログインしているユーザーのみがこのコミュニティにアクセスできます。 - password_login: - title: パスワードログイン - label: メールアドレスとパスワードのログインを許可する - text: "警告: オフにすると、他のログイン方法を設定していない場合はログインできない可能性があります。" - installed_plugins: - title: インストール済みプラグイン - plugin_link: プラグインは機能を拡張します。<1>プラグインリポジトリにプラグインがあります。 - filter: - all: すべて - active: アクティブ - inactive: 非アクティブ - outdated: 期限切れ - plugins: - label: プラグイン - text: 既存のプラグインを選択します - name: 名前 - version: バージョン - status: ステータス - action: 操作 - deactivate: 非アクティブ化 - activate: アクティベート - settings: 設定 - settings_users: - title: ユーザー - avatar: - label: デフォルトのアバター - text: 自分のカスタムアバターのないユーザー向け。 - gravatar_base_url: - label: Gravatar Base URL - text: GravatarプロバイダーのAPIベースのURL。空の場合は無視されます。 - profile_editable: - title: プロフィール編集可能 - allow_update_display_name: - label: ユーザーが表示名を変更できるようにする - allow_update_username: - label: ユーザー名の変更を許可する - allow_update_avatar: - label: ユーザーのプロフィール画像の変更を許可する - allow_update_bio: - label: ユーザーが自分についての変更を許可する - allow_update_website: - label: ユーザーのウェブサイトの変更を許可する - allow_update_location: - label: ユーザーの位置情報の変更を許可する - privilege: - title: 特権 - level: - label: 評判の必要レベル - text: 特権に必要な評判を選択します - msg: - should_be_number: 入力は数値でなければなりません - number_larger_1: 数値は 1 以上でなければなりません - badges: - action: 操作 - active: アクティブ - activate: アクティベート - all: すべて - awards: 賞 - deactivate: 非アクティブ化 - filter: - placeholder: 名前、バッジ:id でフィルター - group: グループ - inactive: 非アクティブ - name: 名前 - show_logs: ログを表示 - status: ステータス - title: バッジ - form: - optional: (任意) - empty: 空にすることはできません - invalid: 無効です - btn_submit: 保存 - not_found_props: "必須プロパティ {{ key }} が見つかりません。" - select: 選択 - page_review: - review: レビュー - proposed: 提案された - question_edit: 質問の編集 - answer_edit: 回答の編集 - tag_edit: タグの編集 - edit_summary: 概要を編集 - edit_question: 質問を編集 - edit_answer: 回答を編集 - edit_tag: タグを編集 - empty: レビュータスクは残っていません。 - approve_revision_tip: この修正を承認しますか? - approve_flag_tip: このフラグを承認しますか? - approve_post_tip: この投稿を承認しますか? - approve_user_tip: このユーザーを承認しますか? - suggest_edits: 提案された編集 - flag_post: 報告された投稿 - flag_user: 報告されたユーザー - queued_post: キューに入れられた投稿 - queued_user: キューに入れられたユーザー - filter_label: タイプ - reputation: 評価 - flag_post_type: この投稿は {{ type }} として報告されました - flag_user_type: このユーザーは {{ type }} として報告されました - edit_post: 投稿を編集 - list_post: 投稿一覧 - unlist_post: 限定公開投稿 - timeline: - undeleted: 復元する - deleted: 削除済み - downvote: 低評価 - upvote: 高評価 - accept: 承認 - cancelled: キャンセル済み - commented: コメントしました - rollback: rollback - edited: 編集済み - answered: 回答済み - asked: 質問済み - closed: クローズ済み - reopened: 再オープン - created: 作成済み - pin: ピン留め済 - unpin: ピン留め解除 - show: 限定公開解除済み - hide: 限定公開済み - title: "履歴:" - tag_title: "タイムライン:" - show_votes: "投票を表示" - n_or_a: N/A - title_for_question: "タイムライン:" - title_for_answer: "{{ title }} の {{ author }} 回答のタイムライン" - title_for_tag: "タグのタイムライン:" - datetime: 日付時刻 - type: タイプ - by: By - comment: コメント - no_data: "何も見つけられませんでした" - users: - title: ユーザー - users_with_the_most_reputation: 今週最も高い評価スコアを持つユーザ - users_with_the_most_vote: 今週一番多く投票したユーザー - staffs: コミュニティのスタッフ - reputation: 評価 - votes: 投票 - prompt: - leave_page: このページから移動してもよろしいですか? - changes_not_save: 変更が保存されない可能性があります - draft: - discard_confirm: 下書きを破棄してもよろしいですか? - messages: - post_deleted: この投稿は削除されました。 - post_cancel_deleted: この投稿の削除が取り消されました。 - post_pin: この投稿はピン留めされています。 - post_unpin: この投稿のピン留めが解除されました。 - post_hide_list: この投稿は一覧から非表示になっています。 - post_show_list: この投稿は一覧に表示されています。 - post_reopen: この投稿は再オープンされました。 - post_list: この投稿は一覧に表示されています。 - post_unlist: この投稿は一覧に登録されていません。 - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: この投稿はクローズされました。 - answer_deleted: この回答は削除されました。 - answer_cancel_deleted: この回答の削除が取り消されました。 - change_user_role: このユーザーのロールが変更されました。 - user_inactive: このユーザーは既に無効です。 - user_normal: このユーザーは既に有効です。 - user_suspended: このユーザーは凍結されています。 - user_deleted: このユーザーは削除されました。 - badge_activated: このバッジは有効化されました。 - badge_inactivated: このバッジは無効化されています。 - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/ko_KR.yaml b/data/i18n/ko_KR.yaml deleted file mode 100644 index abea1556c..000000000 --- a/data/i18n/ko_KR.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: 성공. - unknown: - other: 알 수 없는 오류. - request_format_error: - other: 요청 형식이 잘못되었습니다. - unauthorized_error: - other: 권한이 없습니다. - database_error: - other: 데이터 서버 오류. - forbidden_error: - other: 접근 금지. - duplicate_request_error: - other: 중복된 제출입니다. - action: - report: - other: 신고하기 - edit: - other: 편집 - delete: - other: 삭제 - close: - other: 닫기 - reopen: - other: 다시 열기 - forbidden_error: - other: 접근 금지. - pin: - other: 고정 - hide: - other: 리스트 제거 - unpin: - other: 고정 해제 - show: - other: 리스트 - invite_someone_to_answer: - other: 편집 - undelete: - other: 삭제 취소 - merge: - other: 병합 - role: - name: - user: - other: 유저 - admin: - other: 관리자 - moderator: - other: 중재자 - description: - user: - other: 특별한 접근 권한이 없는 기본 사용자입니다. - admin: - other: 사이트에 대한 모든 권한을 가집니다. - moderator: - other: 관리자 설정을 제외한 모든 게시물에 접근할 수 있습니다. - privilege: - level_1: - description: - other: 레벨 1 (비공개 팀, 그룹에 적은 평판 필요) - level_2: - description: - other: 레벨 2 (스타트업 커뮤니티에 낮은 평판 필요) - level_3: - description: - other: 레벨 3 (성숙한 커뮤니티에 높은 평판 필요) - level_custom: - description: - other: 커스텀 레벨 - rank_question_add_label: - other: 질문하기 - rank_answer_add_label: - other: 답변하기 - rank_comment_add_label: - other: 댓글 작성하기 - rank_report_add_label: - other: 신고하기 - rank_comment_vote_up_label: - other: 댓글 추천 - rank_link_url_limit_label: - other: 한번에 2개 이상의 링크를 게시하세요 - rank_question_vote_up_label: - other: 질문 추천 - rank_answer_vote_up_label: - other: 답변 추천 - rank_question_vote_down_label: - other: 질문 비추천 - rank_answer_vote_down_label: - other: 답변 비추천 - rank_invite_someone_to_answer_label: - other: 답변할 사람 초대 - rank_tag_add_label: - other: 새 태그 만들기 - rank_tag_edit_label: - other: 태그 설명 편집 (검토 필요) - rank_question_edit_label: - other: 다른 사람의 질문 편집 (검토 필요) - rank_answer_edit_label: - other: 다른 사람의 답변 편집 (검토 필요) - rank_question_edit_without_review_label: - other: 검토 없이 다른 사람의 질문 편집 - rank_answer_edit_without_review_label: - other: 검토 없이 다른 사람의 답변 편집 - rank_question_audit_label: - other: 질문 편집 검토하기 - rank_answer_audit_label: - other: 답변 편집 검토하기 - rank_tag_audit_label: - other: 태그 편집 검토하기 - rank_tag_edit_without_review_label: - other: 검토 없이 태그 설명 편집 - rank_tag_synonym_label: - other: 태그 동의어 관리 - email: - other: 이메일 - e_mail: - other: 이메일 - password: - other: 비밀번호 - pass: - other: 비밀번호 - old_pass: - other: 현재 비밀번호 - original_text: - other: 이 게시물 - email_or_password_wrong_error: - other: 이메일과 비밀번호가 일치하지 않습니다. - error: - common: - invalid_url: - other: 잘못된 URL 입니다. - status_invalid: - other: 유효하지 않은 상태. - password: - space_invalid: - other: 암호에는 공백을 포함할 수 없습니다. - admin: - cannot_update_their_password: - other: 암호를 변경할 수 없습니다. - cannot_edit_their_profile: - other: 수정할 수 없습니다. - cannot_modify_self_status: - other: 상태를 변경할 수 없습니다. - email_or_password_wrong: - other: 이메일과 비밀번호가 일치하지 않습니다. - answer: - not_found: - other: 답변을 찾을 수 없습니다. - cannot_deleted: - other: 삭제 권한이 없습니다. - cannot_update: - other: 편집 권한이 없습니다. - question_closed_cannot_add: - other: 질문이 닫혔으며, 추가할 수 없습니다. - content_cannot_empty: - other: 답변 내용은 비워둘 수 없습니다. - comment: - edit_without_permission: - other: 편집이 가능하지 않은 댓글입니다. - not_found: - other: 댓글을 찾을 수 없습니다. - cannot_edit_after_deadline: - other: 수정 허용 시간을 초과했습니다. - content_cannot_empty: - other: 댓글 내용은 비워둘 수 없습니다. - email: - duplicate: - other: 이미 존재하는 이메일입니다. - need_to_be_verified: - other: 이메일을 확인해주세요. - verify_url_expired: - other: URL이 만료되었습니다. 이메일을 다시 보내주세요. - illegal_email_domain_error: - other: 해당 도메인을 사용할 수 없습니다. 다른 전자 메일을 사용하십시오. - lang: - not_found: - other: 언어 파일을 찾을 수 없습니다. - object: - captcha_verification_failed: - other: 잘못된 Captcha입니다. - disallow_follow: - other: 팔로우할 수 없습니다. - disallow_vote: - other: 추천할 수 없습니다. - disallow_vote_your_self: - other: 자신의 게시물에는 추천할 수 없습니다. - not_found: - other: 오브젝트를 찾을 수 없습니다. - verification_failed: - other: 확인 실패. - email_or_password_incorrect: - other: 이메일과 비밀번호가 일치하지 않습니다. - old_password_verification_failed: - other: 이전 암호 확인에 실패했습니다 - new_password_same_as_previous_setting: - other: 새 비밀번호는 이전 비밀번호와 다르게 입력해주세요. - already_deleted: - other: 이 게시물은 삭제되었습니다. - meta: - object_not_found: - other: 메타 객체를 찾을 수 없습니다 - question: - already_deleted: - other: 삭제된 게시물입니다. - under_review: - other: 검토를 기다리고 있습니다. 승인된 후에 볼 수 있습니다. - not_found: - other: 질문을 찾을 수 없습니다. - cannot_deleted: - other: 삭제 권한이 없습니다. - cannot_close: - other: 닫을 권한이 없습니다. - cannot_update: - other: 업데이트 권한이 없습니다. - content_cannot_empty: - other: 내용은 비워둘 수 없습니다. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: 등급이 조건을 충족하지 못합니다. - vote_fail_to_meet_the_condition: - other: 피드백 감사합니다. 투표를 하려면 최소 {{.Rank}} 평판이 필요합니다. - no_enough_rank_to_operate: - other: 이 작업을 하려면 최소 {{.Rank}} 평판이 필요합니다. - report: - handle_failed: - other: 신고 처리에 실패했습니다. - not_found: - other: 신고를 찾을 수 없습니다. - tag: - already_exist: - other: 이미 존재하는 태그입니다. - not_found: - other: 태그를 찾을 수 없습니다. - recommend_tag_not_found: - other: 추천 태그가 존재하지 않습니다. - recommend_tag_enter: - other: 하나 이상의 태그를 입력해주세요. - not_contain_synonym_tags: - other: 동일한 태그를 포함하지 않아야 합니다. - cannot_update: - other: 편집 권한이 없습니다. - is_used_cannot_delete: - other: 사용 중인 태그는 삭제할 수 없습니다. - cannot_set_synonym_as_itself: - other: 현재 태그의 동의어로 자기 자신을 설정할 수 없습니다. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: 발신자 이름은 이메일 주소가 될 수 없습니다. - theme: - not_found: - other: 테마를 찾을 수 없습니다. - revision: - review_underway: - other: 검토 대기열에 있기 때문에 현재 편집할 수 없습니다. - no_permission: - other: 수정권한이 없습니다. - user: - external_login_missing_user_id: - other: 서드파티 플랫폼에서 고유 사용자 ID를 제공하지 않아 로그인할 수 없습니다. 웹사이트 관리자에게 문의하세요. - external_login_unbinding_forbidden: - other: 이 로그인을 제거하기 전에 계정에 로그인 비밀번호를 설정하세요. - email_or_password_wrong: - other: - other: 이메일 또는 비밀번호가 일치하지 않습니다. - not_found: - other: 사용자를 찾을 수 없습니다. - suspended: - other: 사용자가 정지되었습니다. - username_invalid: - other: 유효하지 않은 이름입니다. - username_duplicate: - other: 이미 사용중인 이름입니다. - set_avatar: - other: 아바타 설정에 실패했습니다. - cannot_update_your_role: - other: 수정할 수 없습니다. - not_allowed_registration: - other: 현재 사이트는 등록할 수 없습니다. - not_allowed_login_via_password: - other: 현재 사이트는 비밀번호를 통해 로그인할 수 없습니다. - access_denied: - other: 접근이 거부당했습니다. - page_access_denied: - other: 이 페이지에 대한 접근 권한이 없습니다. - add_bulk_users_format_error: - other: "줄 {{.Line}}의 '{{.Content}}' 근처 {{.Field}} 형식 오류입니다. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "한 번에 추가할 수 있는 사용자 수는 1-{{.MaxAmount}} 범위 내에 있어야 합니다." - status_suspended_forever: - other: "이 사용자는 무기한 접근이 금지 되었습니다. 이 사용자는 커뮤니티의 지침을 충족시키지 않았습니다." - status_suspended_until: - other: "이 사용자는 {{.SuspendedUntil}} 까지 접근이 금지 되었습니다. 이 사용자는 커뮤니티의 지침을 충족시키지 않았습니다." - status_deleted: - other: "삭제된 사용자입니다." - status_inactive: - other: "비활성 사용자입니다." - config: - read_config_failed: - other: 컨피그파일 읽기를 실패했습니다 - database: - connection_failed: - other: 데이터베이스 연결을 실패했습니다 - create_table_failed: - other: 테이블 생성을 실패했습니다 - install: - create_config_failed: - other: config.yaml 파일을 생성할 수 없습니다. - upload: - unsupported_file_format: - other: 지원하지 않는 파일 형식입니다. - site_info: - config_not_found: - other: 사이트 설정을 찾을 수 없습니다. - badge: - object_not_found: - other: 배지 객체를 찾을 수 없습니다 - reason: - spam: - name: - other: 스팸 - desc: - other: 이 게시물은 광고로 인식되었습니다. 현재 주제와 관련이 없습니다. - rude_or_abusive: - name: - other: 폭언 또는 무례한 언행입니다. - desc: - other: "대화에 부적절한 내용입니다." - a_duplicate: - name: - other: 중복 - desc: - other: 이 질문은 이전에 질문한 적이 있으며 이미 답변이 있습니다. - placeholder: - other: 이미 존재하는 질문입니다 - not_a_answer: - name: - other: 답변이 아닙니다 - desc: - other: "이 내용은 답변으로 게시 되었지만, 질문에 대한 답변 시도가 아닙니다. 이는 수정, 댓글, 다른 질문으로 올리는 것이 적절하거나, 삭제하는 것이 적절할 수도 있습니다." - no_longer_needed: - name: - other: 더 이상 필요하지 않습니다. - desc: - other: 이 의견은 구식이거나 대화 중이거나 이 게시물과 관련이 없습니다. - something: - name: - other: 다른 항목 - desc: - other: 이 게시물은 위에 나열되지 않은 다른 이유로 직원의 주의가 필요합니다. - placeholder: - other: 귀하가 우려하는 사항을 구체적으로 알려주세요. - community_specific: - name: - other: 커뮤니티별 특정 이유 - desc: - other: 이 질문은 커뮤니티 가이드라인에 부합하지 않습니다. - not_clarity: - name: - other: 세부사항 또는 명확성이 필요합니다. - desc: - other: 이 질문은 현재 하나에 여러 개의 질문이 포함되어 있습니다. 하나의 문제에만 초점을 맞추어야 합니다. - looks_ok: - name: - other: 괜찮아 보입니다. - desc: - other: 이 게시물은 괜찮으며 품질이 낮지 않습니다. - needs_edit: - name: - other: 편집이 필요하고, 제가 했습니다. - desc: - other: 이 게시물에 대한 문제를 직접 개선하고 수정합니다. - needs_close: - name: - other: 닫혀야 함 - desc: - other: 닫힌 질문은 대답할 수 없지만 편집, 투표 및 댓글 작성을 할 수 있습니다. - needs_delete: - name: - other: 삭제해야 함 - desc: - other: 이 게시물은 삭제되었습니다. - question: - close: - duplicate: - name: - other: 스팸 - desc: - other: 이 질문은 이전에 질문한 적이 있으며 이미 답변이 있습니다. - guideline: - name: - other: 커뮤니티 특정 이유 - desc: - other: 이 질문은 커뮤니티 가이드라인에 부합하지 않습니다. - multiple: - name: - other: 세부사항 또는 명확성이 필요합니다. - desc: - other: 이 질문은 현재 하나에 여러 개의 질문이 포함되어 있습니다. 하나의 문제에만 초점을 맞추어야 합니다. - other: - name: - other: 다른 이유 - desc: - other: 이 게시물에는 위에 나열되지 않은 다른 이유가 필요합니다. - operation_type: - asked: - other: 질문됨 - answered: - other: 답변됨 - modified: - other: 수정됨 - deleted_title: - other: 이미 삭제된 게시물입니다. - questions_title: - other: 질문들 - tag: - tags_title: - other: 태그 - no_description: - other: 이 태그에는 설명이 없습니다. - notification: - action: - update_question: - other: 수정된 질문 - answer_the_question: - other: 대답한 질문 - update_answer: - other: 수정된 대답 - accept_answer: - other: 채택된 답변 - comment_question: - other: 질문에 댓글 달림 - comment_answer: - other: 답변에 댓글 달림 - reply_to_you: - other: 당신에게 답변함 - mention_you: - other: 당신을 언급함 - your_question_is_closed: - other: 당신의 질문이 닫혔습니다 - your_question_was_deleted: - other: 당신의 질문이 삭제되었습니다 - your_answer_was_deleted: - other: 당신의 답변이 삭제되었습니다 - your_comment_was_deleted: - other: 당신의 댓글이 삭제되었습니다 - up_voted_question: - other: 질문에 추천함 - down_voted_question: - other: 질문에 비추천함 - up_voted_answer: - other: 답변에 추천함 - down_voted_answer: - other: 답변에 비추천함 - up_voted_comment: - other: 댓글에 추천함 - invited_you_to_answer: - other: 답변에 초대함 - earned_badge: - other: '"{{.BadgeName}}" 배지를 획득했습니다' - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] 새 이메일 주소 확인" - body: - other: "다음 링크를 클릭하여 {{.SiteName}} 의 새 이메일 주소를 확인하세요:
        \n{{.ChangeEmailUrl}}

        \n\n이 변경을 요청하지 않았다면 이 이메일을 무시하세요.

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} 님이 답변을 작성했습니다" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \n{{.SiteName}} 에서 보기

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요.

        \n\n구독 취소" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} 님이 답변을 요청했습니다" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        답변을 아실 것 같습니다.

        \n{{.SiteName}} 에서 보기

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요.

        \n\n구독 취소" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} 님이 당신의 게시물에 댓글을 남겼습니다" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \n{{.SiteName}} 에서 보기

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요.

        \n\n구독 취소" - new_question: - title: - other: "[{{.SiteName}}] 새 질문: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요.

        \n\n구독 취소" - pass_reset: - title: - other: "[{{.SiteName }}] 비밀번호 재설정" - body: - other: "누군가가 {{.SiteName}} 에서 당신의 비밀번호 재설정을 요청했습니다.

        \n\n당신이 요청하지 않았다면 이 이메일을 무시해도 됩니다.

        \n\n새 비밀번호를 선택하려면 다음 링크를 클릭하세요:
        \n{{.PassResetUrl}}\n

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요." - register: - title: - other: "[{{.SiteName}}] 새 계정 확인" - body: - other: "{{.SiteName}} 에 오신 것을 환영합니다!

        \n\n새 계정을 확인하고 활성화하려면 다음 링크를 클릭하세요:
        \n{{.RegisterUrl}}

        \n\n위 링크가 동작하지 않으면 복사하여 브라우저의 주소 입력에 직접 붙여넣으세요.\n

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요." - test: - title: - other: "[{{.SiteName}}] 테스트 이메일" - body: - other: "이것은 테스트 이메일입니다.\n

        \n\n--
        \n참고: 이것은 자동 시스템 이메일입니다. 응답해도 확인되지 않으므로 이 메시지에 회신하지 마세요." - action_activity_type: - upvote: - other: 추천 - upvoted: - other: 추천함 - downvote: - other: 비추천 - downvoted: - other: 비추천함 - accept: - other: 채택 - accepted: - other: 채택됨 - edit: - other: 수정 - review: - queued_post: - other: 대기 중인 게시물 - flagged_post: - other: 신고된 게시물 - suggested_post_edit: - other: 건의된 수정 - reaction: - tooltip: - other: "{{ .Names }} 외 {{ .Count }} 명..." - badge: - default_badges: - autobiographer: - name: - other: 자서전 작가 - desc: - other: 프로필 정보를 작성했습니다. - certified: - name: - other: 인증됨 - desc: - other: 신규 사용자 튜토리얼을 완료했습니다. - editor: - name: - other: 에디터 - desc: - other: 첫 게시물 편집. - first_flag: - name: - other: 첫 번째 플래그 - desc: - other: 첫 번째로 게시물에 플래그를 설정했습니다. - first_upvote: - name: - other: 첫 번째 추천 - desc: - other: 첫 번째로 게시물을 추천했습니다. - first_link: - name: - other: 첫 번째 링크 - desc: - other: 첫 번째로 다른 게시물에 링크를 추가했습니다. - first_reaction: - name: - other: 첫 번째 반응 - desc: - other: 첫 번째로 게시물에 반응했습니다. - first_share: - name: - other: 첫 번째 공유 - desc: - other: 첫 번째로 게시물을 공유했습니다. - scholar: - name: - other: 학자 - desc: - other: 질문을 하고 답변을 채택했습니다. - commentator: - name: - other: 해설자 - desc: - other: 댓글 5 개 남기기. - new_user_of_the_month: - name: - other: 이달의 신규 사용자 - desc: - other: 첫 달의 뛰어난 기여. - read_guidelines: - name: - other: 가이드라인 읽음 - desc: - other: '[커뮤니티 가이드라인] 을 읽어보세요.' - reader: - name: - other: 리더 - desc: - other: 10 개 이상의 답변이 있는 주제의 모든 답변을 읽어보세요. - welcome: - name: - other: 환영합니다 - desc: - other: 추천을 받았습니다. - nice_share: - name: - other: 좋은 공유 - desc: - other: 25 명의 고유 방문자와 게시물을 공유했습니다. - good_share: - name: - other: 더 좋은 공유 - desc: - other: 300 명의 고유 방문자와 게시물을 공유했습니다. - great_share: - name: - other: 훌륭한 공유 - desc: - other: 1000 명의 고유 방문자와 게시물을 공유했습니다. - out_of_love: - name: - other: 사랑이 식어서 - desc: - other: 하루에 50 개의 추천을 사용했습니다. - higher_love: - name: - other: 더 큰 사랑 - desc: - other: 하루에 50 개의 추천을 5 번 사용했습니다. - crazy_in_love: - name: - other: 사랑에 미치다 - desc: - other: 하루에 50 개의 추천을 20 번 사용했습니다. - promoter: - name: - other: 홍보자 - desc: - other: 사용자를 초대했습니다. - campaigner: - name: - other: 캠페인 담당자 - desc: - other: 3 명의 기본 사용자를 초대했습니다. - champion: - name: - other: 챔피언 - desc: - other: 5 명의 멤버를 초대했습니다. - thank_you: - name: - other: 감사합니다 - desc: - other: 20 개의 추천받은 게시물을 보유하고 10 개의 추천을 주었습니다. - gives_back: - name: - other: 보답 - desc: - other: 100 개의 추천받은 게시물을 보유하고 100 개의 추천을 주었습니다. - empathetic: - name: - other: 공감적 - desc: - other: 500 개의 추천받은 게시물을 보유하고 1000 개의 추천을 주었습니다. - enthusiast: - name: - other: 열성팬 - desc: - other: 10 일 연속으로 방문했습니다. - aficionado: - name: - other: 애호가 - desc: - other: 100 일 연속으로 방문했습니다. - devotee: - name: - other: 열성 지지자 - desc: - other: 365 일 연속으로 방문했습니다. - anniversary: - name: - other: 기념일 - desc: - other: 1 년 동안 활발한 멤버로 활동하며 최소 한 번 이상 게시했습니다. - appreciated: - name: - other: 감사합니다 - desc: - other: 20 개의 게시물에서 1 번의 추천을 받았습니다. - respected: - name: - other: 존경받는 - desc: - other: 100 개의 게시물에서 2 번의 추천을 받았습니다. - admired: - name: - other: 존경받는 - desc: - other: 300 개의 게시물에서 5 번의 추천을 받았습니다. - solved: - name: - other: 해결됨 - desc: - other: 답변이 채택되었습니다. - guidance_counsellor: - name: - other: 지도 상담사 - desc: - other: 10 개의 답변이 채택되었습니다. - know_it_all: - name: - other: 만물박사 - desc: - other: 50 개의 답변이 채택되었습니다. - solution_institution: - name: - other: 솔루션 기관 - desc: - other: 150 개의 답변이 채택되었습니다. - nice_answer: - name: - other: 좋은 답변 - desc: - other: 답변 점수가 10 점 이상입니다. - good_answer: - name: - other: 더 좋은 답변 - desc: - other: 답변 점수가 25 점 이상입니다. - great_answer: - name: - other: 훌륭한 답변 - desc: - other: 답변 점수가 50 점 이상입니다. - nice_question: - name: - other: 좋은 질문 - desc: - other: 질문 점수가 10 점 이상입니다. - good_question: - name: - other: 좋은 질문 - desc: - other: 질문 점수가 25 점 이상입니다. - great_question: - name: - other: 훌륭한 질문 - desc: - other: 질문 점수가 50 점 이상입니다. - popular_question: - name: - other: 인기 질문 - desc: - other: 500 회 조회된 질문입니다. - notable_question: - name: - other: 중요 질문 - desc: - other: 1,000 회 조회된 질문입니다. - famous_question: - name: - other: 유명 질문 - desc: - other: 5,000 회 조회된 질문입니다. - popular_link: - name: - other: 인기 링크 - desc: - other: 50 번 클릭된 외부 링크를 게시했습니다. - hot_link: - name: - other: 핫 링크 - desc: - other: 300 번 클릭된 외부 링크를 게시했습니다. - famous_link: - name: - other: 유명한 링크 - desc: - other: 100 번 클릭된 외부 링크를 게시했습니다. - default_badge_groups: - getting_started: - name: - other: 시작하기 - community: - name: - other: 커뮤니티 - posting: - name: - other: 포스팅 -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: 포맷 방법 - desc: >- -
        • 게시물 언급: #post_id

        • 링크 만들기

          <https://url.com>

          [제목](https://url.com)
        • 단락 사이에 줄바꿈 넣기

        • _기울임체_ 또는 **굵게**

        • 코드는 4 칸 들여쓰기

        • 줄 시작에 > 를 넣어 인용

        • 백틱으로 이스케이프 `_이렇게_`

        • 백틱 ` 으로 코드 펜스 생성

          ```
          여기에 코드
          ```
        - pagination: - prev: 이전 - next: 다음 - page_title: - question: 질문 - questions: 질문들 - tag: 태그 - tags: 태그들 - tag_wiki: 태그 위키 - create_tag: 태그 생성 - edit_tag: 태그 수정 - ask_a_question: 질문 생성 - edit_question: 질문 수정 - edit_answer: 답변 수정 - search: 검색 - posts_containing: 포함된 게시물 - settings: 설정 - notifications: 알림 - login: 로그인 - sign_up: 회원 가입 - account_recovery: 계정 복구 - account_activation: 계정 활성화 - confirm_email: 이메일 확인 - account_suspended: 계정 정지 - admin: 관리자 - change_email: 이메일 수정 - install: 답변 설치 - upgrade: 답변 업그레이드 - maintenance: 웹사이트 유지보수 - users: 사용자 - oauth_callback: 처리 중 - http_404: HTTP 오류 404 - http_50X: HTTP 오류 500 - http_403: HTTP 오류 403 - logout: 로그아웃 - posts: Posts - notifications: - title: 알림 - inbox: 받은 편지함 - achievement: 업적 - new_alerts: 새로운 알림 - all_read: 모두 읽음 처리 - show_more: 더 보기 - someone: 누군가 - inbox_type: - all: 전체 - posts: 게시물 - invites: 초대 - votes: 투표 - answer: 답변 - question: 질문 - badge_award: 뱃지 - suspended: - title: 계정이 정지되었습니다 - until_time: "당신의 계정은 {{ time }}까지 정지되었습니다." - forever: 이 사용자는 영구 정지되었습니다. - end: 커뮤니티 가이드라인을 준수하지 않았습니다. - contact_us: 문의하기 - editor: - blockquote: - text: 인용구 - bold: - text: 강조 - chart: - text: 차트 - flow_chart: 플로우 차트 - sequence_diagram: 시퀀스 다이어그램 - class_diagram: 클래스 다이어그램 - state_diagram: 상태 다이어그램 - entity_relationship_diagram: 엔터티 관계 다이어그램 - user_defined_diagram: 사용자 정의 다이어그램 - gantt_chart: 간트 차트 - pie_chart: 파이 차트 - code: - text: 코드 예시 - add_code: 코드 예시 추가 - form: - fields: - code: - label: 코드 - msg: - empty: 코드를 입력하세요. - language: - label: 언어 - placeholder: 자동 감지 - btn_cancel: 취소 - btn_confirm: 추가 - formula: - text: 수식 - options: - inline: 인라인 수식 - block: 블록 수식 - heading: - text: 제목 - options: - h1: 제목 1 - h2: 제목 2 - h3: 제목 3 - h4: 제목 4 - h5: 제목 5 - h6: 제목 6 - help: - text: 도움말 - hr: - text: 가로규칙 - image: - text: 이미지 - add_image: 이미지 추가 - tab_image: 이미지 업로드 - form_image: - fields: - file: - label: 이미지 파일 - btn: 이미지 선택 - msg: - empty: 파일을 선택하세요. - only_image: 이미지 파일만 허용됩니다. - max_size: 파일 크기는 {{size}} MB 를 초과할 수 없습니다. - desc: - label: 설명 - tab_url: 이미지 URL - form_url: - fields: - url: - label: 이미지 URL - msg: - empty: 이미지 URL을 입력하세요. - name: - label: 설명 - btn_cancel: 취소 - btn_confirm: 추가 - uploading: 업로드 중 - indent: - text: 들여쓰기 - outdent: - text: 내어쓰기 - italic: - text: 이탤릭체 - link: - text: 링크 - add_link: 링크 추가 - form: - fields: - url: - label: URL - msg: - empty: URL을 입력하세요. - name: - label: 설명 - btn_cancel: 취소 - btn_confirm: 추가 - ordered_list: - text: 번호 매긴 목록 - unordered_list: - text: 글머리 기호 목록 - table: - text: 표 - heading: 제목 - cell: 셀 - file: - text: 파일 첨부 - not_supported: "해당 파일 형식을 지원하지 않습니다. {{file_type}} 로 다시 시도해 주세요." - max_size: "첨부 파일 크기는 {{size}} MB 를 초과할 수 없습니다." - close_modal: - title: 이 게시물을 다음과 같은 이유로 닫습니다... - btn_cancel: 취소 - btn_submit: 제출 - remark: - empty: 비어 있을 수 없습니다. - msg: - empty: 이유를 선택해 주세요. - report_modal: - flag_title: 이 게시물을 신고합니다... - close_title: 이 게시물을 다음과 같은 이유로 닫습니다... - review_question_title: 질문 검토 - review_answer_title: 답변 검토 - review_comment_title: 댓글 검토 - btn_cancel: 취소 - btn_submit: 제출 - remark: - empty: 비어 있을 수 없습니다. - msg: - empty: 이유를 선택해 주세요. - not_a_url: URL 형식이 올바르지 않습니다. - url_not_match: URL 원본이 현재 웹사이트와 일치하지 않습니다. - tag_modal: - title: 새로운 태그 생성 - form: - fields: - display_name: - label: 표시 이름 - msg: - empty: 표시 이름을 입력하세요. - range: 표시 이름은 최대 35자까지 입력 가능합니다. - slug_name: - label: URL 슬러그 - desc: '"a-z", "0-9", "+ # - ." 문자 집합을 사용해야 합니다.' - msg: - empty: URL 슬러그를 입력하세요. - range: URL 슬러그는 최대 35자까지 입력 가능합니다. - character: 허용되지 않은 문자 집합이 포함되어 있습니다.' - desc: - label: 설명 - revision: - label: 개정 - edit_summary: - label: 편집 요약 - placeholder: >- - 수정 사항을 간략히 설명하세요 (철자 수정, 문법 수정, 서식 개선 등) - btn_cancel: 취소 - btn_submit: 제출 - btn_post: 새 태그 게시 - tag_info: - created_at: 생성됨 - edited_at: 편집됨 - history: 히스토리 - synonyms: - title: 동의어 - text: 다음 태그가 다음으로 다시 매핑됩니다 - empty: 동의어가 없습니다. - btn_add: 동의어 추가 - btn_edit: 편집 - btn_save: 저장 - synonyms_text: 다음 태그가 다음으로 다시 매핑됩니다 - delete: - title: 이 태그 삭제 - tip_with_posts: >- -

        게시물이 있는 태그 삭제는 허용되지 않습니다.

        먼저 게시물에서 이 태그를 제거해 주세요.

        - tip_with_synonyms: >- -

        동의어가 있는 태그 삭제는 허용되지 않습니다.

        먼저 이 태그에서 동의어를 제거해 주세요.

        - tip: 정말로 삭제하시겠습니까? - close: 닫기 - merge: - title: 태그 병합 - source_tag_title: 원본 태그 - source_tag_description: 원본 태그와 관련 데이터가 대상 태그로 재매핑됩니다. - target_tag_title: 대상 태그 - target_tag_description: 병합 후 이 두 태그 간 동의어가 생성됩니다. - no_results: 일치하는 태그가 없습니다 - btn_submit: 제출 - btn_close: 닫기 - edit_tag: - title: 태그 수정 - default_reason: 태그 수정 - default_first_reason: 태그 추가 - btn_save_edits: 수정 저장 - btn_cancel: 취소 - dates: - long_date: MMM D - long_date_with_year: "YYYY년 M월 D일" - long_date_with_time: "YYYY년 MMM D일 HH:mm" - now: 방금 전 - x_seconds_ago: "{{count}}초 전" - x_minutes_ago: "{{count}}분 전" - x_hours_ago: "{{count}}시간 전" - hour: 시간 - day: 일 - hours: 시간 - days: 일 - month: 월 - months: 개월 - year: 년 - reaction: - heart: 하트 - smile: 스마일 - frown: 찡그린 표정 - btn_label: 반응 추가 또는 제거 - undo_emoji: '{{ emoji }} 반응 취소' - react_emoji: '{{ emoji }} 로 반응' - unreact_emoji: '{{ emoji }} 반응 취소' - comment: - btn_add_comment: 댓글 추가 - reply_to: 답글 달기 - btn_reply: 답글 - btn_edit: 수정 - btn_delete: 삭제 - btn_flag: 신고 - btn_save_edits: 수정 저장 - btn_cancel: 취소 - show_more: "{{count}}개의 댓글 더 보기" - tip_question: >- - 더 많은 정보를 요청하거나 개선을 제안하기 위해 댓글을 사용하세요. 댓글에서 질문에 답변하지는 마세요. - tip_answer: >- - 다른 사용자에게 답변하거나 변경 사항을 알릴 때 댓글을 사용하세요. 새로운 정보를 추가하는 경우에는 게시물을 수정하세요. - tip_vote: 게시물에 유용한 정보를 추가합니다. - edit_answer: - title: 답변 수정 - default_reason: 답변 수정 - default_first_reason: 답변 추가 - form: - fields: - revision: - label: 개정 - answer: - label: 답변 - feedback: - characters: 내용은 최소 6자 이상이어야 합니다. - edit_summary: - label: 편집 요약 - placeholder: >- - 수정 사항을 간략히 설명하세요 (철자 수정, 문법 수정, 서식 개선 등) - btn_save_edits: 수정 저장 - btn_cancel: 취소 - tags: - title: 태그들 - sort_buttons: - popular: 인기순 - name: 이름 - newest: 최신순 - button_follow: 팔로우 - button_following: 팔로잉 중 - tag_label: 질문들 - search_placeholder: 태그 이름으로 필터링 - no_desc: 이 태그에는 설명이 없습니다. - more: 더 보기 - wiki: 위키 - ask: - title: 질문 생성 - edit_title: 질문 수정 - default_reason: 질문 수정 - default_first_reason: 질문 생성 - similar_questions: 유사한 질문 - form: - fields: - revision: - label: 개정 - title: - label: 제목 - placeholder: 주제는 무엇인가요? 상세하게 작성해주세요. - msg: - empty: 제목을 입력하세요. - range: 제목은 최대 150자까지 입력 가능합니다. - body: - label: 본문 - msg: - empty: 본문을 입력하세요. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: 태그 - msg: - empty: 태그를 입력하세요. - answer: - label: 답변 - msg: - empty: 답변을 입력하세요. - edit_summary: - label: 편집 요약 - placeholder: >- - 수정 사항을 간략히 설명하세요 (철자 수정, 문법 수정, 서식 개선 등) - btn_post_question: 질문 게시하기 - btn_save_edits: 수정사항 저장 - answer_question: 질문에 대한 답변 작성 - post_question&answer: 질문과 답변 게시하기 - tag_selector: - add_btn: 태그 추가 - create_btn: 새 태그 생성 - search_tag: 태그 검색 - hint: 질문의 주제를 설명하세요. 적어도 하나의 태그가 필요합니다. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: 일치하는 태그가 없습니다. - tag_required_text: 필수 태그 (적어도 하나) - header: - nav: - question: 질문 - tag: 태그 - user: 사용자 - badges: 뱃지 - profile: 프로필 - setting: 설정 - logout: 로그아웃 - admin: 관리자 - review: 리뷰 - bookmark: 즐겨찾기 - moderation: 운영 - search: - placeholder: 검색 - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: 변경 - loading: 로딩 중... - pic_auth_code: - title: 캡차 - placeholder: 위의 텍스트를 입력하세요 - msg: - empty: 캡차를 입력하세요. - inactive: - first: >- - 거의 다 되었습니다! {{mail}}로 활성화 메일을 보냈습니다. 계정을 활성화하려면 메일 안의 지침을 따르세요. - info: "메일이 도착하지 않았다면, 스팸 메일함도 확인해 주세요." - another: >- - {{mail}}로 또 다른 활성화 이메일을 보냈습니다. 메일이 도착하는 데 몇 분 정도 걸릴 수 있으니 스팸 메일함도 확인해 주세요. - btn_name: 활성화 이메일 재전송 - change_btn_name: 이메일 변경 - msg: - empty: 비어 있을 수 없습니다. - resend_email: - url_label: 활성화 이메일을 재전송하시겠습니까? - url_text: 위의 활성화 링크를 사용자에게 제공할 수도 있습니다. - login: - login_to_continue: 계속하려면 로그인하세요 - info_sign: 계정이 없으신가요? <1>가입하기 - info_login: 이미 계정이 있으신가요? <1>로그인하기 - agreements: 가입하면 <1>개인정보 보호 정책과 <3>이용 약관에 동의하게 됩니다. - forgot_pass: 비밀번호를 잊으셨나요? - name: - label: 이름 - msg: - empty: 이름을 입력하세요. - range: 이름은 2 자에서 30 자 사이여야 합니다. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: 이메일 - msg: - empty: 이메일을 입력하세요. - password: - label: 비밀번호 - msg: - empty: 비밀번호를 입력하세요. - different: 입력된 비밀번호가 일치하지 않습니다. - account_forgot: - page_title: 비밀번호를 잊으셨나요? - btn_name: 비밀번호 재설정 이메일 보내기 - send_success: >- - {{mail}}에 해당하는 계정이 있다면 곧 비밀번호 재설정 방법을 안내하는 이메일을 받으실 수 있습니다. - email: - label: 이메일 - msg: - empty: 이메일을 입력하세요. - change_email: - btn_cancel: 취소 - btn_update: 이메일 주소 업데이트 - send_success: >- - {{mail}}에 해당하는 계정이 있다면 곧 이메일 주소 변경 방법을 안내하는 이메일을 받으실 수 있습니다. - email: - label: 새 이메일 - msg: - empty: 이메일을 입력하세요. - oauth: - connect: '{{ auth_name }}로 연결' - remove: '{{ auth_name }} 연결 해제' - oauth_bind_email: - subtitle: 계정에 복구 이메일 추가 - btn_update: 이메일 주소 업데이트 - email: - label: 이메일 - msg: - empty: 이메일을 입력하세요. - modal_title: 이미 등록된 이메일 - modal_content: 이 이메일 주소는 이미 등록되어 있습니다. 기존 계정에 연결하시겠습니까? - modal_cancel: 이메일 변경 - modal_confirm: 기존 계정에 연결하기 - password_reset: - page_title: 비밀번호 재설정 - btn_name: 비밀번호 재설정 - reset_success: >- - 비밀번호가 성공적으로 변경되었습니다. 로그인 페이지로 이동합니다. - link_invalid: >- - 죄송합니다. 이 비밀번호 재설정 링크는 더 이상 유효하지 않습니다. 이미 비밀번호를 재설정하셨을 수 있습니다. - to_login: 로그인 페이지로 이동 - password: - label: 비밀번호 - msg: - empty: 비밀번호를 입력하세요. - length: 비밀번호는 8자에서 32자 사이여야 합니다. - different: 입력한 비밀번호가 일치하지 않습니다. - password_confirm: - label: 새 비밀번호 확인 - settings: - page_title: 설정 - goto_modify: 수정으로 이동 - nav: - profile: 프로필 - notification: 알림 - account: 계정 - interface: 인터페이스 - profile: - heading: 프로필 - btn_name: 저장 - display_name: - label: 표시 이름 - msg: 표시 이름을 입력하세요. - msg_range: 표시 이름은 2-30 자 길이여야 합니다. - username: - label: 사용자 이름 - caption: 다른 사용자가 "@사용자이름"으로 멘션할 수 있습니다. - msg: 사용자 이름을 입력하세요. - msg_range: 유저 이름은 2-30 자 길이여야 합니다. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: 프로필 이미지 - gravatar: Gravatar - gravatar_text: Gravatar에서 이미지를 변경할 수 있습니다. - custom: 사용자 정의 - custom_text: 사용자 이미지를 업로드할 수 있습니다. - default: 시스템 기본 이미지 - msg: 프로필 이미지를 업로드하세요. - bio: - label: 자기 소개 - website: - label: 웹사이트 - placeholder: "https://example.com" - msg: 웹사이트 형식이 올바르지 않습니다. - location: - label: 위치 - placeholder: "도시, 국가" - notification: - heading: 이메일 알림 - turn_on: 켜기 - inbox: - label: 받은 편지함 알림 - description: 질문에 대한 답변, 댓글, 초대 등을 받습니다. - all_new_question: - label: 모든 새 질문 - description: 모든 새 질문에 대해 알림을 받습니다. 주당 최대 50개의 질문까지. - all_new_question_for_following_tags: - label: 팔로우 태그의 모든 새 질문 - description: 팔로우하는 태그의 새로운 질문에 대해 알림을 받습니다. - account: - heading: 계정 - change_email_btn: 이메일 변경 - change_pass_btn: 비밀번호 변경 - change_email_info: >- - 해당 주소로 이메일을 보냈습니다. 확인 지침을 따라주세요. - email: - label: 이메일 - new_email: - label: 새 이메일 - msg: 새 이메일을 입력하세요. - pass: - label: 현재 비밀번호 - msg: 비밀번호를 입력하세요. - password_title: 비밀번호 - current_pass: - label: 현재 비밀번호 - msg: - empty: 현재 비밀번호를 입력하세요. - length: 비밀번호는 8자에서 32자 사이여야 합니다. - different: 입력한 두 비밀번호가 일치하지 않습니다. - new_pass: - label: 새 비밀번호 - pass_confirm: - label: 새 비밀번호 확인 - interface: - heading: 인터페이스 - lang: - label: 인터페이스 언어 - text: 사용자 인터페이스 언어입니다. 페이지를 새로고침하면 변경됩니다. - my_logins: - title: 내 로그인 정보 - label: 이 사이트에서 이 계정으로 로그인하거나 가입하세요. - modal_title: 로그인 제거 - modal_content: 이 계정에서 이 로그인을 제거하시겠습니까? - modal_confirm_btn: 제거 - remove_success: 제거되었습니다. - toast: - update: 업데이트 성공 - update_password: 비밀번호가 성공적으로 변경되었습니다. - flag_success: 신고 감사합니다. - forbidden_operate_self: 자신에 대한 작업은 금지되어 있습니다. - review: 검토 후에 귀하의 수정 사항이 표시됩니다. - sent_success: 전송 성공 - related_question: - title: 관련된 질문 - answers: 답변 - linked_question: - title: 링크된 질문 - description: 이 질문을 링크한 질문 - no_linked_question: 이 질문에 연결된 질문 없음. - invite_to_answer: - title: 질문자 초대 - desc: 답변을 알고 있을 것으로 생각되는 사람을 선택하세요. - invite: 답변 초대 - add: 사람 추가 - search: 사람 검색 - question_detail: - action: 동작 - created: Created - Asked: 질문함 - asked: 질문 작성 - update: 수정됨 - Edited: Edited - edit: 편집됨 - commented: 댓글 작성 - Views: 조회수 - Follow: 팔로우 - Following: 팔로잉 중 - follow_tip: 이 질문을 팔로우하여 알림을 받으세요. - answered: 답변 작성 - closed_in: 답변 종료 - show_exist: 기존 질문 표시 - useful: 유용함 - question_useful: 유용하고 명확함 - question_un_useful: 불명확하거나 유용하지 않음 - question_bookmark: 이 질문 즐겨찾기 - answer_useful: 유용함 - answer_un_useful: 유용하지 않음 - answers: - title: 답변 - score: 점수 - newest: 최신순 - oldest: 오래된 순 - btn_accept: 채택 - btn_accepted: 채택됨 - write_answer: - title: 당신의 답변 - edit_answer: 내 답변 편집하기 - btn_name: 답변 게시하기 - add_another_answer: 다른 답변 추가 - confirm_title: 답변 계속하기 - continue: 계속 - confirm_info: >- -

        다른 답변을 추가하시겠습니까?

        대신 기존 답변을 향상시키고 개선할 수 있는 수정 링크를 사용할 수 있습니다.

        - empty: 답변을 입력해주세요. - characters: 내용은 최소 6자 이상이어야 합니다. - tips: - header_1: 답변해 주셔서 감사합니다 - li1_1: 질문에 답변을 제공하세요. 세부 사항을 설명하고 연구 결과를 공유하세요. - li1_2: 발언을 뒷받침하는 자료나 개인적인 경험을 통해 주장을 뒷받침하세요. - header_2: 하지만 피해야 할 것들 ... - li2_1: 도움을 요청하거나 해명을 구하거나 다른 답변에 응답하는 것. - reopen: - confirm_btn: 다시 열기 - title: 이 게시물 다시 열기 - content: 정말 다시 열기를 원하시나요? - list: - confirm_btn: 목록 - title: 이 게시물 목록에 추가하기 - content: 정말 목록에 추가하시겠습니까? - unlist: - confirm_btn: 목록 해제 - title: 이 게시물 목록에서 제외하기 - content: 정말 목록에서 제외하시겠습니까? - pin: - title: 이 게시물 고정하기 - content: 글로벌로 고정하시겠습니까? 이 게시물은 모든 게시물 목록 상단에 표시됩니다. - confirm_btn: 고정하기 - delete: - title: 이 게시물 삭제하기 - question: >- -

        답변이 있는 질문을 삭제하는 것은 권장하지 않습니다 이는 이 지식을 필요로 하는 사용자에게 정보를 제공하지 못하게 될 수 있습니다.

        답변이 있는 질문을 반복적으로 삭제하는 경우 질문 권한이 차단될 수 있습니다. 정말 삭제하시겠습니까? - answer_accepted: >- -

        채택된 답변을 삭제하는 것은 권장하지 않습니다 이는 이 지식을 필요로 하는 사용자에게 정보를 제공하지 못하게 될 수 있습니다.

        채택된 답변을 반복적으로 삭제하는 경우 답변 권한이 차단될 수 있습니다. 정말 삭제하시겠습니까? - other: 정말 삭제하시겠습니까? - tip_answer_deleted: 이 답변은 삭제되었습니다. - undelete_title: 이 게시물 복구하기 - undelete_desc: 정말 복구하시겠습니까? - btns: - confirm: 확인 - cancel: 취소 - edit: 편집 - save: 저장 - delete: 삭제 - undelete: 복구 - list: 목록 - unlist: 목록 해제 - unlisted: 목록에서 해제됨 - login: 로그인 - signup: 가입하기 - logout: 로그아웃 - verify: 확인 - create: 생성 - approve: 승인 - reject: 거부 - skip: 건너뛰기 - discard_draft: 임시 저장 삭제 - pinned: 고정됨 - all: 모두 - question: 질문 - answer: 답변 - comment: 댓글 - refresh: 새로 고침 - resend: 재전송 - deactivate: 비활성화 - active: 활성화 - suspend: 정지 - unsuspend: 정지 해제 - close: 닫기 - reopen: 다시 열기 - ok: 확인 - light: 밝게 - dark: 어둡게 - system_setting: 시스템 설정 - default: 기본 - reset: 재설정 - tag: 태그 - post_lowercase: 게시물 - filter: 필터 - ignore: 무시 - submit: 제출 - normal: 일반 - closed: 닫힘 - deleted: 삭제됨 - deleted_permanently: 영구 삭제 - pending: 보류 중 - more: 더 보기 - view: 보기 - card: 카드 - compact: 간단히 - display_below: 아래에 표시 - always_display: 항상 표시 - or: 또는 - back_sites: 사이트로 돌아가기 - search: - title: 검색 결과 - keywords: 키워드 - options: 옵션 - follow: 팔로우 - following: 팔로잉 중 - counts: "{{count}} 개의 결과" - counts_loading: "... 개의 결과" - more: 더 보기 - sort_btns: - relevance: 관련성 - newest: 최신순 - active: 활성순 - score: 평점순 - more: 더 보기 - tips: - title: 고급 검색 팁 - tag: "<1>[태그] 태그로 검색" - user: "<1>user:사용자명 작성자로 검색" - answer: "<1>answers:0 답변이 없는 질문" - score: "<1>score:3 평점이 3 이상인 글" - question: "<1>is:question 질문만 검색" - is_answer: "<1>is:answer 답변만 검색" - empty: 아무것도 찾지 못했습니다.
        다른 키워드를 사용하거나 덜 구체적인 검색을 시도하세요. - share: - name: 공유 - copy: 링크 복사 - via: 포스트 공유하기... - copied: 복사됨 - facebook: Facebook에 공유 - twitter: X에 공유하기 - cannot_vote_for_self: 자신의 글에 투표할 수 없습니다. - modal_confirm: - title: 오류... - delete_permanently: - title: 영구 삭제 - content: 영구적으로 삭제하시겠습니까? - account_result: - success: 새 계정이 확인되었습니다. 홈페이지로 이동합니다. - link: 홈페이지로 이동 - oops: 이런! - invalid: 사용하신 링크가 더 이상 작동하지 않습니다. - confirm_new_email: 이메일이 업데이트되었습니다. - confirm_new_email_invalid: >- - 죄송합니다, 이 확인 링크는 더 이상 유효하지 않습니다. 이미 이메일이 변경된 상태일 수 있습니다. - unsubscribe: - page_title: 구독 해지 - success_title: 구독 해지 완료 - success_desc: 이 구독자 목록에서 성공적으로 제거되었으며, 더 이상 우리로부터 어떠한 이메일도 받지 않게 됩니다. - link: 설정 변경하기 - question: - following_tags: 팔로우 태그 - edit: 수정 - save: 저장 - follow_tag_tip: 질문 목록을 관리하기 위해 태그를 팔로우하세요. - hot_questions: 인기 질문 - all_questions: 모든 질문 - x_questions: "{{ count }} 개의 질문" - x_answers: "{{ count }} 개의 답변" - x_posts: "{{ count }} 개의 글" - questions: 질문 - answers: 답변 - newest: 최신순 - active: 활성순 - hot: 인기 - frequent: 빈도 - recommend: 추천 - score: 평점순 - unanswered: 답변이 없는 질문 - modified: 수정됨 - answered: 답변됨 - asked: 질문됨 - closed: 닫힘 - follow_a_tag: 태그 팔로우하기 - more: 더 보기 - personal: - overview: 개요 - answers: 답변 - answer: 답변 - questions: 질문 - question: 질문 - bookmarks: 즐겨찾기 - reputation: 평판 - comments: 댓글 - votes: 투표 - badges: 뱃지 - newest: 최신순 - score: 평점순 - edit_profile: 프로필 수정 - visited_x_days: "{{ count }} 일 방문함" - viewed: 조회됨 - joined: 가입일 - comma: "," - last_login: 최근 접속 - about_me: 자기 소개 - about_me_empty: "// 안녕하세요, 세상아 !" - top_answers: 최고 답변 - top_questions: 최고 질문 - stats: 통계 - list_empty: 게시물을 찾을 수 없습니다.
        다른 탭을 선택하실 수 있습니다. - content_empty: 게시물을 찾을 수 없습니다. - accepted: 채택됨 - answered: 답변됨 - asked: 질문됨 - downvoted: 다운투표됨 - mod_short: MOD - mod_long: 관리자 - x_reputation: 평판 - x_votes: 받은 투표 - x_answers: 답변 - x_questions: 질문 - recent_badges: 최근 배지 - install: - title: 설치 - next: 다음 - done: 완료 - config_yaml_error: config.yaml 파일을 생성할 수 없습니다. - lang: - label: 언어 선택 - db_type: - label: 데이터베이스 엔진 - db_username: - label: 사용자 이름 - placeholder: root - msg: 사용자 이름은 비워둘 수 없습니다. - db_password: - label: 비밀번호 - placeholder: root - msg: 비밀번호는 비워둘 수 없습니다. - db_host: - label: 데이터베이스 호스트 - placeholder: "db:3306" - msg: 데이터베이스 호스트는 비워둘 수 없습니다. - db_name: - label: 데이터베이스 이름 - placeholder: 답변 - msg: 데이터베이스 이름은 비워둘 수 없습니다. - db_file: - label: 데이터베이스 파일 - placeholder: /data/answer.db - msg: 데이터베이스 파일은 비워둘 수 없습니다. - ssl_enabled: - label: SSL 활성화 - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL 모드 - ssl_root_cert: - placeholder: sslrootcert 파일 경로 - msg: sslrootcert 파일 경로는 비워둘 수 없습니다 - ssl_cert: - placeholder: sslcert 파일 경로 - msg: sslcert 파일 경로는 비워둘 수 없습니다 - ssl_key: - placeholder: sslkey 파일 경로 - msg: sslkey 파일 경로는 비워둘 수 없습니다 - config_yaml: - title: config.yaml 파일 생성 - label: config.yaml 파일이 생성되었습니다. - desc: >- - config.yaml 파일을 <1>/var/wwww/xxx/ 디렉터리에 수동으로 생성하고 아래 텍스트를 붙여넣을 수 있습니다. - info: 위 작업을 완료한 후 "다음" 버튼을 클릭하세요. - site_information: 사이트 정보 - admin_account: 관리자 계정 - site_name: - label: 사이트 이름 - msg: 사이트 이름을 입력하세요. - msg_max_length: 사이트 이름은 최대 30자여야 합니다. - site_url: - label: 사이트 URL - text: 사이트의 주소입니다. - msg: - empty: 사이트 URL을 입력하세요. - incorrect: 올바른 형식의 사이트 URL을 입력하세요. - max_length: 사이트 URL은 최대 512자여야 합니다. - contact_email: - label: 연락처 이메일 - text: 이 사이트에 책임을 지는 주요 연락 이메일 주소입니다. - msg: - empty: 연락처 이메일을 입력하세요. - incorrect: 올바른 형식의 연락처 이메일을 입력하세요. - login_required: - label: 비공개 - switch: 로그인 필요 - text: 로그인한 사용자만 이 커뮤니티에 접근할 수 있습니다. - admin_name: - label: 이름 - msg: 이름을 입력하세요. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: 이름은 2 자 이상 30 자 이하여야 합니다. - admin_password: - label: 비밀번호 - text: >- - 로그인에 필요한 비밀번호입니다. 안전한 위치에 보관하세요. - msg: 비밀번호를 입력하세요. - msg_min_length: 비밀번호는 최소 8자여야 합니다. - msg_max_length: 비밀번호는 최대 32자여야 합니다. - admin_confirm_password: - label: "비밀번호 확인" - text: "확인을 위해 비밀번호를 다시 입력해주세요." - msg: "비밀번호 확인이 일치하지 않습니다." - admin_email: - label: 이메일 - text: 로그인에 필요한 이메일입니다. - msg: - empty: 이메일을 입력하세요. - incorrect: 올바른 형식의 이메일을 입력하세요. - ready_title: 귀하의 사이트가 준비되었습니다 - ready_desc: >- - 추가 설정을 원하시면 <1>관리자 섹션에서 찾아보세요; 사이트 메뉴에서 확인할 수 있습니다. - good_luck: "재미있고 행운을 빕니다!" - warn_title: 경고 - warn_desc: >- - 파일 <1>config.yaml이 이미 존재합니다. 이 파일의 구성 항목 중 재설정이 필요하면 먼저 삭제하세요. - install_now: <1>지금 설치해보세요. - installed: 이미 설치됨 - installed_desc: >- - 이미 설치된 것으로 보입니다. 재설치하려면 먼저 이전 데이터베이스 테이블을 삭제하세요. - db_failed: 데이터베이스 연결 실패 - db_failed_desc: >- - <1>config.yaml 파일에 있는 데이터베이스 정보가 올바르지 않거나 데이터베이스 서버와 연결할 수 없습니다. 호스트의 데이터베이스 서버가 다운된 경우입니다. - counts: - views: 조회수 - votes: 투표 - answers: 답변 - accepted: 채택됨 - page_error: - http_error: HTTP 오류 {{ code }} - desc_403: 이 페이지에 접근할 권한이 없습니다. - desc_404: 죄송합니다. 이 페이지는 존재하지 않습니다. - desc_50X: 서버에서 오류가 발생하여 요청을 완료할 수 없습니다. - back_home: 홈페이지로 돌아가기 - page_maintenance: - desc: "저희는 현재 유지보수 중입니다. 곧 돌아오겠습니다." - nav_menus: - dashboard: 대시보드 - contents: 콘텐츠 - questions: 질문 - answers: 답변 - users: 사용자 - badges: 뱃지 - flags: 신고하기 - settings: 설정 - general: 일반 - interface: 인터페이스 - smtp: SMTP - branding: 브랜딩 - legal: 법적 사항 - write: 글 작성 - terms: Terms - tos: 이용 약관 - privacy: 개인정보 보호 - seo: 검색 엔진 최적화 - customize: 사용자 정의 - themes: 테마 - login: 로그인 - privileges: 권한 - plugins: 플러그인 - installed_plugins: 설치된 플러그인 - apperance: 모양 - website_welcome: '{{site_name}}에 오신 것을 환영합니다' - user_center: - login: 로그인 - qrcode_login_tip: '{{ agentName }}을(를) 사용하여 QR 코드를 스캔하고 로그인하세요.' - login_failed_email_tip: 로그인 실패, 다시 시도하기 전에 이 앱이 이메일 정보에 접근할 수 있도록 허용하세요. - badges: - modal: - title: 축하합니다 - content: 새로운 뱃지를 획득했습니다. - close: 닫기 - confirm: 뱃지 보기 - title: 뱃지 - awarded: 수여됨 - earned_×: '{{ number }} 개 획득' - ×_awarded: "{{ number }} 개 수여됨" - can_earn_multiple: 이 뱃지는 여러 번 획득할 수 있습니다. - earned: 획득함 - admin: - admin_header: - title: 관리자 - dashboard: - title: 대시보드 - welcome: 관리자에 오신 것을 환영합니다! - site_statistics: 사이트 통계 - questions: "질문:" - resolved: "해결됨:" - unanswered: "답변이 없는 질문:" - answers: "답변:" - comments: "댓글:" - votes: "투표:" - users: "사용자:" - flags: "신고:" - reviews: "리뷰:" - site_health: 사이트 상태 - version: "버전:" - https: "HTTPS:" - upload_folder: "업로드 폴더:" - run_mode: "실행 모드:" - private: 비공개 - public: 공개 - smtp: "SMTP:" - timezone: "시간대:" - system_info: 시스템 정보 - go_version: "Go 버전:" - database: "데이터베이스:" - database_size: "데이터베이스 크기:" - storage_used: "사용 중인 저장 공간:" - uptime: "가동 시간:" - links: 링크 - plugins: 플러그인 - github: GitHub - blog: 블로그 - contact: 연락처 - forum: 포럼 - documents: 문서 - feedback: 피드백 - support: 지원 - review: 검토 - config: 설정 - update_to: 업데이트 - latest: 최신 버전 - check_failed: 확인 실패 - "yes": "예" - "no": "아니요" - not_allowed: 허용되지 않음 - allowed: 허용됨 - enabled: 활성화됨 - disabled: 비활성화됨 - writable: 쓰기 가능 - not_writable: 쓰기 불가능 - flags: - title: 신고 - pending: 처리 대기 중 - completed: 완료됨 - flagged: 신고됨 - flagged_type: '{{ type }}로 신고됨' - created: 생성됨 - action: 동작 - review: 검토 - user_role_modal: - title: 사용자 역할 변경 - btn_cancel: 취소 - btn_submit: 제출 - new_password_modal: - title: 새 비밀번호 설정 - form: - fields: - password: - label: 비밀번호 - text: 사용자가 로그아웃되고 다시 로그인해야 합니다. - msg: 비밀번호는 8-32자여야 합니다. - btn_cancel: 취소 - btn_submit: 제출 - edit_profile_modal: - title: 프로필 수정 - form: - fields: - display_name: - label: 표시 이름 - msg_range: 표시 이름은 2-30 자 길이여야 합니다. - username: - label: 사용자 이름 - msg_range: 유저 이름은 2-30 자 길이여야 합니다. - email: - label: 이메일 - msg_invalid: 유효하지 않은 이메일 주소. - edit_success: 성공적으로 수정되었습니다 - btn_cancel: 취소 - btn_submit: 제출 - user_modal: - title: 새 사용자 추가 - form: - fields: - users: - label: 대량 사용자 추가 - placeholder: "홍길동, hong@example.com, BUSYopr2\n김철수, kim@example.com, fpDntV8q" - text: 쉼표로 구분하여 “이름, 이메일, 비밀번호”를 입력하세요. 한 줄에 한 명의 사용자. - msg: "사용자의 이메일을 입력하세요. 한 줄에 한 명씩 입력하세요." - display_name: - label: 표시 이름 - msg: 표시 이름은 2-30 자 길이여야 합니다. - email: - label: 이메일 - msg: 이메일이 유효하지 않습니다. - password: - label: 비밀번호 - msg: 비밀번호는 8-32자여야 합니다. - btn_cancel: 취소 - btn_submit: 제출 - users: - title: 사용자 - name: 이름 - email: 이메일 - reputation: 평판 - created_at: 생성 시간 - delete_at: 삭제된 시간 - suspend_at: 정지된 시간 - suspend_until: 정지 기한 - status: 상태 - role: 역할 - action: 동작 - change: 변경 - all: 전체 - staff: 스탭 - more: 더 보기 - inactive: 비활성화됨 - suspended: 정지됨 - deleted: 삭제됨 - normal: 일반 - Moderator: 관리자 - Admin: 관리자 - User: 사용자 - filter: - placeholder: "이름 또는 사용자 ID로 필터링" - set_new_password: 새 비밀번호 설정 - edit_profile: 프로필 수정 - change_status: 상태 변경 - change_role: 역할 변경 - show_logs: 로그 표시 - add_user: 사용자 추가 - deactivate_user: - title: 사용자 비활성화 - content: 비활성화된 사용자는 이메일을 다시 확인해야 합니다. - delete_user: - title: 이 사용자 삭제 - content: 정말로 이 사용자를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다! - remove: 사용자의 모든 질문, 답변, 댓글 등을 삭제합니다. - label: 사용자의 계정만 삭제하려면 이 옵션을 선택하지 마세요. - text: 사용자의 계정만 삭제하려면 이 항목을 선택하지 마십시오. - suspend_user: - title: 이 사용자 정지 - content: 정지된 사용자는 로그인할 수 없습니다. - label: 사용자를 며칠 접근 금지 하시겠습니까? - forever: 무기한 - questions: - page_title: 질문 - unlisted: 비공개 - post: 게시물 - votes: 투표 - answers: 답변 - created: 생성됨 - status: 상태 - action: 동작 - change: 변경 - pending: 대기 중 - filter: - placeholder: "제목 또는 질문 ID로 필터링" - answers: - page_title: 답변 - post: 게시물 - votes: 투표 - created: 생성됨 - status: 상태 - action: 동작 - change: 변경 - filter: - placeholder: "제목 또는 답변 ID로 필터링" - general: - page_title: 일반 - name: - label: 사이트 이름 - msg: 사이트 이름을 입력하세요. - text: "사이트 이름, 타이틀 태그에 사용됩니다." - site_url: - label: 사이트 URL - msg: 사이트 URL을 입력하세요. - validate: 유효한 URL을 입력하세요. - text: 사이트 주소입니다. - short_desc: - label: 짧은 사이트 설명 - msg: 짧은 사이트 설명을 입력하세요. - text: "홈페이지에서 사용되는 짧은 설명입니다." - desc: - label: 사이트 설명 - msg: 사이트 설명을 입력하세요. - text: "메타 설명 태그에 사용되는 한 문장 설명입니다." - contact_email: - label: 연락처 이메일 - msg: 연락처 이메일을 입력하세요. - validate: 유효한 이메일 주소를 입력하세요. - text: 사이트를 책임지는 주요 연락처 이메일 주소입니다. - check_update: - label: 소프트웨어 업데이트 - text: 소프트웨어 업데이트 자동 확인 - interface: - page_title: 인터페이스 - language: - label: 인터페이스 언어 - msg: 인터페이스 언어를 선택하세요. - text: 페이지를 새로고침하면 언어가 변경됩니다. - time_zone: - label: 시간대 - msg: 시간대를 선택하세요. - text: 본인과 같은 시간대의 도시를 선택하세요. - avatar: - label: 기본 아바타 - text: 사용자 정의 아바타가 없는 사용자에게 표시됩니다. - gravatar_base_url: - label: Gravatar 기본 URL - text: Gravatar 공급자의 API 기본 URL입니다. 비어 있으면 무시됩니다. - smtp: - page_title: SMTP - from_email: - label: 발신 이메일 - msg: 발신 이메일을 입력하세요. - text: 이메일 발신 주소입니다. - from_name: - label: 발신자 이름 - msg: 발신자 이름을 입력하세요. - text: 이메일 발신 시 사용될 이름입니다. - smtp_host: - label: SMTP 호스트 - msg: SMTP 호스트를 입력하세요. - text: 메일 서버 주소입니다. - encryption: - label: 암호화 - msg: 암호화 방식을 선택하세요. - text: 대부분의 서버에서 SSL을 권장합니다. - ssl: SSL - tls: TLS - none: 없음 - smtp_port: - label: SMTP 포트 - msg: SMTP 포트는 1에서 65535 사이의 숫자여야 합니다. - text: 메일 서버의 포트 번호입니다. - smtp_username: - label: SMTP 사용자 이름 - msg: SMTP 사용자 이름을 입력하세요. - smtp_password: - label: SMTP 비밀번호 - msg: SMTP 비밀번호를 입력하세요. - test_email_recipient: - label: 테스트 이메일 수신자 - text: 테스트 이메일을 받을 이메일 주소를 입력하세요. - msg: 테스트 이메일 수신자가 유효하지 않습니다. - smtp_authentication: - label: 인증 사용 - title: SMTP 인증 - msg: SMTP 인증을 선택하세요. - "yes": "예" - "no": "아니오" - branding: - page_title: 브랜딩 - logo: - label: 로고 - msg: 로고를 입력하세요. - text: 사이트 좌측 상단에 표시될 로고 이미지입니다. 넓은 직사각형 이미지로, 높이는 56 이상이어야 하며 가로 세로 비율은 3:1 이상이어야 합니다. 비워 둘 경우 사이트 제목 텍스트가 표시됩니다. - mobile_logo: - label: 모바일 로고 - text: 사이트의 모바일 버전에서 사용할 로고 이미지입니다. 넓은 직사각형 이미지로, 높이는 56 이상이어야 합니다. 비워 둘 경우 "로고" 설정에서 이미지가 사용됩니다. - square_icon: - label: 정사각형 아이콘 - msg: 정사각형 아이콘을 입력하세요. - text: 메타데이터 아이콘의 기본 이미지로 사용됩니다. 이상적으로는 512x512보다 큰 이미지여야 합니다. - favicon: - label: 파비콘 - text: 사이트의 파비콘 이미지입니다. CDN에서 정상적으로 작동하려면 png 형식이어야 하며, 크기는 32x32로 조정됩니다. 비워 둘 경우 "정사각형 아이콘"이 사용됩니다. - legal: - page_title: 법적 고지 - terms_of_service: - label: 서비스 이용 약관 - text: "여기에 서비스 이용 약관 내용을 추가할 수 있습니다. 이미 다른 곳에 문서가 호스팅되어 있다면 전체 URL을 여기에 제공하세요." - privacy_policy: - label: 개인정보 보호 정책 - text: "여기에 개인정보 보호 정책 내용을 추가할 수 있습니다. 이미 다른 곳에 문서가 호스팅되어 있다면 전체 URL을 여기에 제공하세요." - external_content_display: - label: 외부 콘텐츠 - text: "콘텐츠에는 외부 웹사이트에서 삽입된 이미지, 비디오 및 미디어가 포함됩니다." - always_display: 항상 외부 콘텐츠 표시 - ask_before_display: 외부 콘텐츠 표시 전 확인 - write: - page_title: 작성 - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: 답변 작성 - label: 각 사용자는 각 질문에 대해 단 하나의 답변만 작성할 수 있습니다. - text: "기존 답변을 개선하고 향상시키기 위해 편집 링크를 사용할 수 있습니다." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: 추천 태그 - text: "추천 태그가 기본적으로 드롭다운 목록에 표시됩니다." - msg: - contain_reserved: "추천 태그에는 예약된 태그가 포함될 수 없습니다" - required_tag: - title: 필수 태그 설정 - label: '"추천 태그" 를 필수 태그로 설정' - text: "모든 새로운 질문은 최소한 하나의 추천 태그가 있어야 합니다." - reserved_tags: - label: 예약된 태그 - text: "예약된 태그는 관리자만 사용할 수 있습니다." - image_size: - label: 최대 이미지 크기 (MB) - text: "최대 이미지 업로드 크기입니다." - attachment_size: - label: 최대 첨부 파일 크기 (MB) - text: "최대 첨부 파일 업로드 크기입니다." - image_megapixels: - label: 최대 이미지 메가픽셀 - text: "이미지에 허용되는 최대 메가픽셀 수입니다." - image_extensions: - label: 허용된 이미지 확장자 - text: "이미지 표시가 허용된 파일 확장자 목록입니다. 쉼표로 구분하세요." - attachment_extensions: - label: 인증된 첨부 파일 확장자 - text: "업로드가 허용된 파일 확장자 목록입니다. 쉼표로 구분하세요. 경고: 업로드를 허용하면 보안 문제가 발생할 수 있습니다." - seo: - page_title: 검색 엔진 최적화 - permalink: - label: 영구 링크 - text: 사용자 정의 URL 구조는 링크의 사용성과 미래 호환성을 향상시킬 수 있습니다. - robots: - label: robots.txt - text: 이 설정은 사이트 설정과 관련된 내용을 영구적으로 덮어씁니다. - themes: - page_title: 테마 - themes: - label: 테마 - text: 기존 테마를 선택하세요. - color_scheme: - label: 색상 스키마 - navbar_style: - label: 네비바 배경 스타일 - primary_color: - label: 주요 색상 - text: 테마에서 사용할 색상을 수정합니다. - css_and_html: - page_title: CSS 및 HTML - custom_css: - label: 사용자 정의 CSS - text: > - - head: - label: 헤드 - text: > - - header: - label: 헤더 - text: > - - footer: - label: 푸터 - text: 본문의 바로 앞에 삽입됩니다. - sidebar: - label: 사이드바 - text: 사이드바에 삽입됩니다. - login: - page_title: 로그인 - membership: - title: 멤버십 - label: 신규 등록 허용 - text: 계정을 생성할 수 있는 사람을 제한하려면 끄세요. - email_registration: - title: 이메일 등록 - label: 이메일 등록 허용 - text: 이메일을 통한 새 계정 생성을 막으려면 끄세요. - allowed_email_domains: - title: 허용된 이메일 도메인 - text: 사용자가 계정을 등록할 때 필수적으로 사용해야 하는 이메일 도메인입니다. 한 줄에 하나의 도메인을 입력하세요. 비어 있으면 무시됩니다. - private: - title: 비공개 - label: 로그인 필수 - text: 로그인한 사용자만이 이 커뮤니티에 접근할 수 있습니다. - password_login: - title: 비밀번호 로그인 - label: 이메일과 비밀번호 로그인 허용 - text: "경고: 끄면 다른 로그인 방법을 설정하지 않았다면 로그인할 수 없을 수 있습니다." - installed_plugins: - title: 설치된 플러그인 - plugin_link: 플러그인은 기능을 확장하고 확장합니다. <1> 플러그인 저장소에서 플러그인을 찾을 수 있습니다. - filter: - all: 전체 - active: 활성화됨 - inactive: 비활성화됨 - outdated: 오래된 상태 - plugins: - label: 플러그인 - text: 기존 플러그인을 선택하세요. - name: 이름 - version: 버전 - status: 상태 - action: 작업 - deactivate: 비활성화 - activate: 활성화 - settings: 설정 - settings_users: - title: 사용자 - avatar: - label: 기본 아바타 - text: 사용자가 자신의 사용자 정의 아바타를 가지지 않았을 때 표시됩니다. - gravatar_base_url: - label: Gravatar 기본 URL - text: Gravatar 공급자의 API 기본 URL입니다. 비어 있으면 무시됩니다. - profile_editable: - title: 프로필 편집 가능 - allow_update_display_name: - label: 사용자가 표시 이름을 변경할 수 있도록 허용 - allow_update_username: - label: 사용자가 사용자 이름을 변경할 수 있도록 허용 - allow_update_avatar: - label: 사용자가 프로필 이미지를 변경할 수 있도록 허용 - allow_update_bio: - label: 사용자가 자기 소개를 변경할 수 있도록 허용 - allow_update_website: - label: 사용자가 웹사이트를 변경할 수 있도록 허용 - allow_update_location: - label: 사용자가 위치 정보를 변경할 수 있도록 허용 - privilege: - title: 권한 - level: - label: 권한에 필요한 평판 레벨 - text: 권한에 필요한 평판 레벨을 선택하세요. - msg: - should_be_number: 입력값은 숫자여야 합니다. - number_larger_1: 숫자는 1 이상이어야 합니다. - badges: - action: 동작 - active: 활성 - activate: 활성화 - all: 모두 - awards: 수상 - deactivate: 비활성화 - filter: - placeholder: 이름, 배지:id 로 필터링 - group: 그룹 - inactive: 비활성 - name: 이름 - show_logs: 로그 표시 - status: 상태 - title: 뱃지 - form: - optional: (선택 사항) - empty: 비어 있을 수 없습니다 - invalid: 유효하지 않습니다 - btn_submit: 저장 - not_found_props: "필수 속성 {{ key }}을(를) 찾을 수 없습니다." - select: 선택 - page_review: - review: 리뷰 - proposed: 제안된 - question_edit: 질문 편집 - answer_edit: 답변 편집 - tag_edit: 태그 편집 - edit_summary: 편집 요약 - edit_question: 질문 편집 - edit_answer: 답변 편집 - edit_tag: 태그 편집 - empty: 남은 리뷰 작업이 없습니다. - approve_revision_tip: 이 리비전을 승인하시겠습니까? - approve_flag_tip: 이 신고를 승인하시겠습니까? - approve_post_tip: 이 게시물을 승인하시겠습니까? - approve_user_tip: 이 사용자를 승인하시겠습니까? - suggest_edits: 제안된 편집 - flag_post: 게시물 신고 - flag_user: 사용자 신고 - queued_post: 대기 중인 게시물 - queued_user: 대기 중인 사용자 - filter_label: 유형 - reputation: 평판 - flag_post_type: 이 게시물을 {{ type }}로 신고 처리했습니다. - flag_user_type: 이 사용자를 {{ type }}로 신고 처리했습니다. - edit_post: 게시물 편집 - list_post: 게시물 목록 - unlist_post: 게시물 비공개 - timeline: - undeleted: 복구됨 - deleted: 삭제됨 - downvote: 다운보트 - upvote: 업보트 - accept: 채택됨 - cancelled: 취소됨 - commented: 댓글 작성됨 - rollback: 롤백 - edited: 편집됨 - answered: 답변됨 - asked: 질문됨 - closed: 닫힘 - reopened: 다시 열림 - created: 생성됨 - pin: 고정됨 - unpin: 고정 해제됨 - show: 공개됨 - hide: 비공개됨 - title: "다음을 위한 히스토리" - tag_title: "태그에 대한 타임라인" - show_votes: "투표 보기" - n_or_a: 없음 - title_for_question: "질문에 대한 타임라인" - title_for_answer: "{{ author }}가 {{ title }}에 대한 답변에 대한 타임라인" - title_for_tag: "태그에 대한 타임라인" - datetime: 날짜 및 시간 - type: 유형 - by: 작성자 - comment: 코멘트 - no_data: "아무 데이터도 찾을 수 없습니다." - users: - title: 사용자 - users_with_the_most_reputation: 이번 주 평판이 가장 높은 사용자들 - users_with_the_most_vote: 이번 주 투표를 가장 많이 한 사용자들 - staffs: 우리 커뮤니티 스태프 - reputation: 평판 - votes: 투표 - prompt: - leave_page: 페이지를 떠나시겠습니까? - changes_not_save: 변경 사항이 저장되지 않을 수 있습니다. - draft: - discard_confirm: 초안을 삭제하시겠습니까? - messages: - post_deleted: 이 게시물은 삭제되었습니다. - post_cancel_deleted: 이 게시물이 삭제 취소되었습니다. - post_pin: 이 게시물이 고정되었습니다. - post_unpin: 이 게시물의 고정이 해제되었습니다. - post_hide_list: 이 게시물이 목록에서 숨겨졌습니다. - post_show_list: 이 게시물이 목록에 표시되었습니다. - post_reopen: 이 게시물이 다시 열렸습니다. - post_list: 이 게시물이 목록에 등록되었습니다. - post_unlist: 이 게시물이 목록에서 등록 해제되었습니다. - post_pending: 회원님의 게시물이 검토를 기다리고 있습니다. 미리보기입니다. 승인 후에 공개됩니다. - post_closed: 이 게시물이 닫혔습니다. - answer_deleted: 이 답변이 삭제되었습니다. - answer_cancel_deleted: 이 답변이 삭제 취소되었습니다. - change_user_role: 이 사용자의 역할이 변경되었습니다. - user_inactive: 이 사용자는 이미 비활성 상태입니다. - user_normal: 이 사용자는 이미 일반 사용자입니다. - user_suspended: 이 사용자가 정지되었습니다. - user_deleted: 이 사용자가 삭제되었습니다. - badge_activated: 이 배지가 활성화되었습니다. - badge_inactivated: 이 배지가 비활성화되었습니다. - users_deleted: 이 사용자들이 삭제되었습니다. - posts_deleted: 이 질문들이 삭제되었습니다. - answers_deleted: 이 답변들이 삭제되었습니다. - copy: 클립보드에 복사 - copied: 복사됨 - external_content_warning: 외부 이미지/미디어가 표시되지 않습니다. - - diff --git a/data/i18n/ml_IN.yaml b/data/i18n/ml_IN.yaml deleted file mode 100644 index 07c47bd8d..000000000 --- a/data/i18n/ml_IN.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Success. - unknown: - other: Unknown error. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - forbidden_error: - other: Forbidden. - duplicate_request_error: - other: Duplicate submission. - action: - report: - other: Flag - edit: - other: Edit - delete: - other: Delete - close: - other: Close - reopen: - other: Reopen - forbidden_error: - other: Forbidden. - pin: - other: Pin - hide: - other: Unlist - unpin: - other: Unpin - show: - other: List - invite_someone_to_answer: - other: Edit - undelete: - other: Undelete - merge: - other: Merge - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - privilege: - level_1: - description: - other: Level 1 (less reputation required for private team, group) - level_2: - description: - other: Level 2 (low reputation required for startup community) - level_3: - description: - other: Level 3 (high reputation required for mature community) - level_custom: - description: - other: Custom Level - rank_question_add_label: - other: Ask question - rank_answer_add_label: - other: Write answer - rank_comment_add_label: - other: Write comment - rank_report_add_label: - other: Flag - rank_comment_vote_up_label: - other: Upvote comment - rank_link_url_limit_label: - other: Post more than 2 links at a time - rank_question_vote_up_label: - other: Upvote question - rank_answer_vote_up_label: - other: Upvote answer - rank_question_vote_down_label: - other: Downvote question - rank_answer_vote_down_label: - other: Downvote answer - rank_invite_someone_to_answer_label: - other: Invite someone to answer - rank_tag_add_label: - other: Create new tag - rank_tag_edit_label: - other: Edit tag description (need to review) - rank_question_edit_label: - other: Edit other's question (need to review) - rank_answer_edit_label: - other: Edit other's answer (need to review) - rank_question_edit_without_review_label: - other: Edit other's question without review - rank_answer_edit_without_review_label: - other: Edit other's answer without review - rank_question_audit_label: - other: Review question edits - rank_answer_audit_label: - other: Review answer edits - rank_tag_audit_label: - other: Review tag edits - rank_tag_edit_without_review_label: - other: Edit tag description without review - rank_tag_synonym_label: - other: Manage tag synonyms - email: - other: Email - e_mail: - other: Email - password: - other: Password - pass: - other: Password - old_pass: - other: Current password - original_text: - other: This post - email_or_password_wrong_error: - other: Email and password do not match. - error: - common: - invalid_url: - other: Invalid URL. - status_invalid: - other: Invalid status. - password: - space_invalid: - other: Password cannot contain spaces. - admin: - cannot_update_their_password: - other: You cannot modify your password. - cannot_edit_their_profile: - other: You cannot modify your profile. - cannot_modify_self_status: - other: You cannot modify your status. - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - question_closed_cannot_add: - other: Questions are closed and cannot be added. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - illegal_email_domain_error: - other: Email is not allowed from that email domain. Please use another one. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - already_deleted: - other: This post has been deleted. - meta: - object_not_found: - other: Meta object not found - question: - already_deleted: - other: This post has been deleted. - under_review: - other: Your post is awaiting review. It will be visible after it has been approved. - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Reputation rank fail to meet the condition. - vote_fail_to_meet_the_condition: - other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. - no_enough_rank_to_operate: - other: You need at least {{.Rank}} reputation to do this. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - already_exist: - other: Tag already exists. - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - is_used_cannot_delete: - other: You cannot delete a tag that is in use. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: The from name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to revise. - user: - external_login_missing_user_id: - other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. - external_login_unbinding_forbidden: - other: Please set a login password for your account before you remove this login. - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration. - not_allowed_login_via_password: - other: Currently the site is not allowed to login via password. - access_denied: - other: Access denied - page_access_denied: - other: You do not have access to this page. - add_bulk_users_format_error: - other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - site_info: - config_not_found: - other: Site config not found. - badge: - object_not_found: - other: Badge object not found - reason: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude_or_abusive: - name: - other: rude or abusive - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - a_duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - placeholder: - other: Enter the existing question link - not_a_answer: - name: - other: not an answer - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." - no_longer_needed: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - something: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - placeholder: - other: Let us know specifically what you are concerned about - community_specific: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - not_clarity: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - looks_ok: - name: - other: looks OK - desc: - other: This post is good as-is and not low quality. - needs_edit: - name: - other: needs edit, and I did it - desc: - other: Improve and correct problems with this post yourself. - needs_close: - name: - other: needs close - desc: - other: A closed question can't answer, but still can edit, vote and comment. - needs_delete: - name: - other: needs delete - desc: - other: This post will be deleted. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - deleted_title: - other: Deleted question - questions_title: - other: Questions - tag: - tags_title: - other: Tags - no_description: - other: The tag has no description. - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted - up_voted_question: - other: upvoted question - down_voted_question: - other: downvoted question - up_voted_answer: - other: upvoted answer - down_voted_answer: - other: downvoted answer - up_voted_comment: - other: upvoted comment - invited_you_to_answer: - other: invited you to answer - earned_badge: - other: You've earned the "{{.BadgeName}}" badge - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Confirm your new email address" - body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} answered your question" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n

        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_question: - title: - other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Password reset" - body: - other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - register: - title: - other: "[{{.SiteName}}] Confirm your new account" - body: - other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - test: - title: - other: "[{{.SiteName}}] Test Email" - body: - other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: - upvote: - other: upvote - upvoted: - other: upvoted - downvote: - other: downvote - downvoted: - other: downvoted - accept: - other: accept - accepted: - other: accepted - edit: - other: edit - review: - queued_post: - other: Queued post - flagged_post: - other: Flagged post - suggested_post_edit: - other: Suggested edits - reaction: - tooltip: - other: "{{ .Names }} and {{ .Count }} more..." - badge: - default_badges: - autobiographer: - name: - other: Autobiographer - desc: - other: Filled out profile information. - certified: - name: - other: Certified - desc: - other: Completed our new user tutorial. - editor: - name: - other: Editor - desc: - other: First post edit. - first_flag: - name: - other: First Flag - desc: - other: First flagged a post. - first_upvote: - name: - other: First Upvote - desc: - other: First up voted a post. - first_link: - name: - other: First Link - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: First Share - desc: - other: First shared a post. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Leave 5 comments. - new_user_of_the_month: - name: - other: New User of the Month - desc: - other: Outstanding contributions in their first month. - read_guidelines: - name: - other: Read Guidelines - desc: - other: Read the [community guidelines]. - reader: - name: - other: Reader - desc: - other: Read every answers in a topic with more than 10 answers. - welcome: - name: - other: Welcome - desc: - other: Received a up vote. - nice_share: - name: - other: Nice Share - desc: - other: Shared a post with 25 unique visitors. - good_share: - name: - other: Good Share - desc: - other: Shared a post with 300 unique visitors. - great_share: - name: - other: Great Share - desc: - other: Shared a post with 1000 unique visitors. - out_of_love: - name: - other: Out of Love - desc: - other: Used 50 up votes in a day. - higher_love: - name: - other: Higher Love - desc: - other: Used 50 up votes in a day 5 times. - crazy_in_love: - name: - other: Crazy in Love - desc: - other: Used 50 up votes in a day 20 times. - promoter: - name: - other: Promoter - desc: - other: Invited a user. - campaigner: - name: - other: Campaigner - desc: - other: Invited 3 basic users. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: Thank You - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Active member for a year, posted at least once. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - create_tag: Create Tag - edit_tag: Edit Tag - ask_a_question: Create Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - oauth_callback: Processing - http_404: HTTP Error 404 - http_50X: HTTP Error 500 - http_403: HTTP Error 403 - logout: Log Out - posts: Posts - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - new_alerts: New alerts - all_read: Mark all as read - show_more: Show more - someone: Someone - inbox_type: - all: All - posts: Posts - invites: Invites - votes: Votes - answer: Answer - question: Question - badge_award: Badge - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - contact_us: Contact us - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image file - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed {{size}} MB. - desc: - label: Description - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered list - unordered_list: - text: Bulleted list - table: - text: Table - heading: Heading - cell: Cell - file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - not_a_url: URL format is incorrect. - url_not_match: URL origin does not match the current website. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description - revision: - label: Revision - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_cancel: Cancel - btn_submit: Submit - btn_post: Post new tag - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - tip_with_posts: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - tip_with_synonyms: >- -

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        - tip: Are you sure you wish to delete? - close: Close - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - default_first_reason: Add tag - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - hours: hours - days: days - month: month - months: months - year: year - reaction: - heart: heart - smile: smile - frown: frown - btn_label: add or remove reactions - undo_emoji: undo {{ emoji }} reaction - react_emoji: react with {{ emoji }} - unreact_emoji: unreact with {{ emoji }} - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: "{{count}} more comments" - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - tip_vote: It adds something useful to the post - edit_answer: - title: Edit Answer - default_reason: Edit answer - default_first_reason: Add answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: Newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - wiki: Wiki - ask: - title: Create Question - edit_title: Edit Question - default_reason: Edit question - default_first_reason: Create question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: What's your topic? Be specific. - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - badges: Badges - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - bookmark: Bookmarks - moderation: Moderation - search: - placeholder: Search - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - resend_email: - url_label: Are you sure you want to resend the activation email? - url_text: You can also give the activation link above to the user. - login: - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New email - msg: - empty: Email cannot be empty. - oauth: - connect: Connect with {{ auth_name }} - remove: Remove {{ auth_name }} - oauth_bind_email: - subtitle: Add a recovery email to your account. - btn_update: Update email address - email: - label: Email - msg: - empty: Email cannot be empty. - modal_title: Email already existes. - modal_content: This email address already registered. Are you sure you want to connect to the existing account? - modal_cancel: Change email - modal_confirm: Connect to the existing account - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm new password - settings: - page_title: Settings - goto_modify: Go to modify - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile image - gravatar: Gravatar - gravatar_text: You can change image on - custom: Custom - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About me - website: - label: Website - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location - placeholder: "City, Country" - notification: - heading: Email Notifications - turn_on: Turn on - inbox: - label: Inbox notifications - description: Answers to your questions, comments, invites, and more. - all_new_question: - label: All new questions - description: Get notified of all new questions. Up to 50 questions per week. - all_new_question_for_following_tags: - label: All new questions for following tags - description: Get notified of new questions for following tags. - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - pass: - label: Current password - msg: Password cannot be empty. - password_title: Password - current_pass: - label: Current password - msg: - empty: Current password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New password - pass_confirm: - label: Confirm new password - interface: - heading: Interface - lang: - label: Interface language - text: User interface language. It will change when you refresh the page. - my_logins: - title: My logins - label: Log in or sign up on this site using these accounts. - modal_title: Remove login - modal_content: Are you sure you want to remove this login from your account? - modal_confirm_btn: Remove - remove_success: Removed successfully - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - sent_success: Sent successfully - related_question: - title: Related - answers: answers - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Invite People - desc: Invite people you think can answer. - invite: Invite to answer - add: Add people - search: Search people - question_detail: - action: Action - created: Created - Asked: Asked - asked: asked - update: Modified - Edited: Edited - edit: edited - commented: commented - Views: Viewed - Follow: Follow - Following: Following - follow_tip: Follow this question to receive notifications - answered: answered - closed_in: Closed in - show_exist: Show existing question. - useful: Useful - question_useful: It is useful and clear - question_un_useful: It is unclear or not useful - question_bookmark: Bookmark this question - answer_useful: It is useful - answer_un_useful: It is not useful - answers: - title: Answers - score: Score - newest: Newest - oldest: Oldest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - edit_answer: Edit my existing answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - tips: - header_1: Thanks for your answer - li1_1: Please be sure to answer the question. Provide details and share your research. - li1_2: Back up any statements you make with references or personal experience. - header_2: But avoid ... - li2_1: Asking for help, seeking clarification, or responding to other answers. - reopen: - confirm_btn: Reopen - title: Reopen this post - content: Are you sure you want to reopen? - list: - confirm_btn: List - title: List this post - content: Are you sure you want to list? - unlist: - confirm_btn: Unlist - title: Unlist this post - content: Are you sure you want to unlist? - pin: - title: Pin this post - content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. - confirm_btn: Pin - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_answer_deleted: This answer has been deleted - undelete_title: Undelete this post - undelete_desc: Are you sure you wish to undelete? - btns: - confirm: Confirm - cancel: Cancel - edit: Edit - save: Save - delete: Delete - undelete: Undelete - list: List - unlist: Unlist - unlisted: Unlisted - login: Log in - signup: Sign up - logout: Log out - verify: Verify - create: Create - approve: Approve - reject: Reject - skip: Skip - discard_draft: Discard draft - pinned: Pinned - all: All - question: Question - answer: Answer - comment: Comment - refresh: Refresh - resend: Resend - deactivate: Deactivate - active: Active - suspend: Suspend - unsuspend: Unsuspend - close: Close - reopen: Reopen - ok: OK - light: Light - dark: Dark - system_setting: System setting - default: Default - reset: Reset - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignore - submit: Submit - normal: Normal - closed: Closed - deleted: Deleted - deleted_permanently: Deleted permanently - pending: Pending - more: More - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - counts_loading: "... Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post. - modal_confirm: - title: Error... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - x_posts: "{{ count }} Posts" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - frequent: Frequent - recommend: Recommend - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - badges: Badges - newest: Newest - score: Score - edit_profile: Edit profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - comma: "," - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - content_empty: No posts found. - accepted: Accepted - answered: answered - asked: asked - downvoted: downvoted - mod_short: MOD - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - recent_badges: Recent Badges - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please choose a language - db_type: - label: Database engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database host - placeholder: "db:3306" - msg: Database host cannot be empty. - db_name: - label: Database name - placeholder: answer - msg: Database name cannot be empty. - db_file: - label: Database file - placeholder: /data/answer.db - msg: Database file cannot be empty. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site name - msg: Site name cannot be empty. - msg_max_length: Site name must be at maximum 30 characters in length. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - max_length: Site URL must be at maximum 512 characters in length. - contact_email: - label: Contact email - text: Email address of key contact responsible for this site. - msg: - empty: Contact email cannot be empty. - incorrect: Contact email incorrect format. - login_required: - label: Private - switch: Login required - text: Only logged in users can access this community. - admin_name: - label: Name - msg: Name cannot be empty. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - msg_min_length: Password must be at least 8 characters in length. - msg_max_length: Password must be at maximum 32 characters in length. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_error: - http_error: HTTP Error {{ code }} - desc_403: You don't have permission to access this page. - desc_404: Unfortunately, this page doesn't exist. - desc_50X: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - badges: Badges - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - terms: Terms - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - login: Login - privileges: Privileges - plugins: Plugins - installed_plugins: Installed Plugins - apperance: Appearance - website_welcome: Welcome to {{site_name}} - user_center: - login: Login - qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. - login_failed_email_tip: Login failed, please allow this app to access your email information before try again. - badges: - modal: - title: Congratulations - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site statistics - questions: "Questions:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - users: "Users:" - flags: "Flags:" - reviews: "Reviews:" - site_health: Site health - version: "Version:" - https: "HTTPS:" - upload_folder: "Upload folder:" - run_mode: "Running mode:" - private: Private - public: Public - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System info - go_version: "Go version:" - database: "Database:" - database_size: "Database size:" - storage_used: "Storage used:" - uptime: "Uptime:" - links: Links - plugins: Plugins - github: GitHub - blog: Blog - contact: Contact - forum: Forum - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - writable: Writable - not_writable: Not writable - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - flagged_type: Flagged {{ type }} - created: Created - action: Action - review: Review - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - edit_profile_modal: - title: Edit profile - form: - fields: - display_name: - label: Display name - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Invalid Email Address. - edit_success: Edited successfully - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - users: - label: Bulk add user - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separate “name, email, password” with commas. One user per line. - msg: "Please enter the user's email, one per line." - display_name: - label: Display name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - more: More - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - edit_profile: Edit profile - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - deactivate_user: - title: Deactivate user - content: An inactive user must re-validate their email. - delete_user: - title: Delete this user - content: Are you sure you want to delete this user? This is permanent! - remove: Remove their content - label: Remove all questions, answers, comments, etc. - text: Don’t check this if you wish to only delete the user’s account. - suspend_user: - title: Suspend this user - content: A suspended user can't log in. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Questions - unlisted: Unlisted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - pending: Pending - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short site description - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site description - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - check_update: - label: Software updates - text: Automatically check for updates - interface: - page_title: Interface - language: - label: Interface language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: From email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - tls: TLS - none: None - smtp_port: - label: SMTP port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test email recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile logo - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square icon - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Write - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Each user can only write one answer for the same question - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Recommend tags - text: "Recommend tags will show in the dropdown list by default." - msg: - contain_reserved: "recommended tags cannot contain reserved tags" - required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved tags - text: "Reserved tags can only be used by moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - color_scheme: - label: Color scheme - navbar_style: - label: Navbar background style - primary_color: - label: Primary color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: > - - head: - label: Head - text: > - - header: - label: Header - text: > - - footer: - label: Footer - text: This will insert before </body>. - sidebar: - label: Sidebar - text: This will insert in sidebar. - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - email_registration: - title: Email registration - label: Allow email registration - text: Turn off to prevent anyone creating new account through email. - allowed_email_domains: - title: Allowed email domains - text: Email domains that users must register accounts with. One domain per line. Ignored when empty. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - password_login: - title: Password login - label: Allow email and password login - text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." - installed_plugins: - title: Installed Plugins - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. - filter: - all: All - active: Active - inactive: Inactive - outdated: Outdated - plugins: - label: Plugins - text: Select an existing plugin. - name: Name - version: Version - status: Status - action: Action - deactivate: Deactivate - activate: Activate - settings: Settings - settings_users: - title: Users - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - profile_editable: - title: Profile editable - allow_update_display_name: - label: Allow users to change their display name - allow_update_username: - label: Allow users to change their username - allow_update_avatar: - label: Allow users to change their profile image - allow_update_bio: - label: Allow users to change their about me - allow_update_website: - label: Allow users to change their website - allow_update_location: - label: Allow users to change their location - privilege: - title: Privileges - level: - label: Reputation required level - text: Choose the reputation required for the privileges - msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 - badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate - filter: - placeholder: Filter by name, badge:id - group: Group - inactive: Inactive - name: Name - show_logs: Show logs - status: Status - title: Badges - form: - optional: (optional) - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - select: Select - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - approve_revision_tip: Do you approve this revision? - approve_flag_tip: Do you approve this flag? - approve_post_tip: Do you approve this post? - approve_user_tip: Do you approve this user? - suggest_edits: Suggested edits - flag_post: Flag post - flag_user: Flag user - queued_post: Queued post - queued_user: Queued user - filter_label: Type - reputation: reputation - flag_post_type: Flagged this post as {{ type }}. - flag_user_type: Flagged this user as {{ type }}. - edit_post: Edit post - list_post: List post - unlist_post: Unlist post - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - pin: pinned - unpin: unpinned - show: listed - hide: unlisted - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores this week - users_with_the_most_vote: Users who voted the most this week - staffs: Our community staff - reputation: reputation - votes: votes - prompt: - leave_page: Are you sure you want to leave the page? - changes_not_save: Your changes may not be saved. - draft: - discard_confirm: Are you sure you want to discard your draft? - messages: - post_deleted: This post has been deleted. - post_cancel_deleted: This post has been undeleted. - post_pin: This post has been pinned. - post_unpin: This post has been unpinned. - post_hide_list: This post has been hidden from list. - post_show_list: This post has been shown to list. - post_reopen: This post has been reopened. - post_list: This post has been listed. - post_unlist: This post has been unlisted. - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/nl_NL.yaml b/data/i18n/nl_NL.yaml deleted file mode 100644 index 25c086f11..000000000 --- a/data/i18n/nl_NL.yaml +++ /dev/null @@ -1,1384 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: Success. - unknown: - other: Unknown error. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - email: - other: Email - password: - other: Password - email_or_password_wrong_error: - other: Email and password do not match. - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - question: - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - rank: - fail_to_meet_the_condition: - other: Rank fail to meet the condition. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend Tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - smtp: - config_from_name_cannot_be_email: - other: The From Name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to Revision. - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - report: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude: - name: - other: rude or abusive - desc: - other: A reasonable person would find this content inappropriate for respectful discourse. - duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - not_answer: - name: - other: not an answer - desc: - other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. - not_need: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - other: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comments - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to {{site_name}} - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to {{site_name}} - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/no_NO.yaml b/data/i18n/no_NO.yaml deleted file mode 100644 index abe12baf4..000000000 --- a/data/i18n/no_NO.yaml +++ /dev/null @@ -1,1385 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: Success. - unknown: - other: Unknown error. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - email: - other: Email - password: - other: Password - email_or_password_wrong_error: - other: Email and password do not match. - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - question: - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - rank: - fail_to_meet_the_condition: - other: Rank fail to meet the condition. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend Tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - smtp: - config_from_name_cannot_be_email: - other: The From Name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to Revision. - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - report: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude: - name: - other: rude or abusive - desc: - other: A reasonable person would find this content inappropriate for respectful discourse. - duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - not_answer: - name: - other: not an answer - desc: - other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. - not_need: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - other: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comments - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to {{site_name}} - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to {{site_name}} - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - recommend: Recommend - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/pl_PL.yaml b/data/i18n/pl_PL.yaml deleted file mode 100644 index 7cf88431b..000000000 --- a/data/i18n/pl_PL.yaml +++ /dev/null @@ -1,2414 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Sukces. - unknown: - other: Nieznany błąd. - request_format_error: - other: Format żądania jest nieprawidłowy. - unauthorized_error: - other: Niezautoryzowany. - database_error: - other: Błąd serwera danych. - forbidden_error: - other: Zakazane. - duplicate_request_error: - other: Duplikat zgłoszenia. - action: - report: - other: Zgłoś - edit: - other: Edytuj - delete: - other: Usuń - close: - other: Zamknij - reopen: - other: Otwórz ponownie - forbidden_error: - other: Zakazane. - pin: - other: Przypnij - hide: - other: Usuń z listy - unpin: - other: Odepnij - show: - other: Lista - invite_someone_to_answer: - other: Edytuj - undelete: - other: Przywróć - merge: - other: Merge - role: - name: - user: - other: Użytkownik - admin: - other: Administrator - moderator: - other: Moderator - description: - user: - other: Domyślnie bez specjalnego dostępu. - admin: - other: Posiadać pełne uprawnienia dostępu do strony. - moderator: - other: Ma dostęp do wszystkich postów z wyjątkiem ustawień administratora. - privilege: - level_1: - description: - other: Poziom 1 (mniejsza reputacja wymagana dla prywatnego zespołu, grupy) - level_2: - description: - other: Poziom 2 (niska reputacja wymagana dla społeczności startującej) - level_3: - description: - other: Poziom 3 (wysoka reputacja wymagana dla dojrzałej społeczności) - level_custom: - description: - other: Poziom niestandardowy - rank_question_add_label: - other: Zadaj pytanie - rank_answer_add_label: - other: Napisz odpowiedź - rank_comment_add_label: - other: Napisz komentarz - rank_report_add_label: - other: Zgłoś - rank_comment_vote_up_label: - other: Wyróżnij komentarz - rank_link_url_limit_label: - other: Opublikuj więcej niż 2 linki na raz - rank_question_vote_up_label: - other: Wyróżnij pytanie - rank_answer_vote_up_label: - other: Wyróżnij odpowiedź - rank_question_vote_down_label: - other: Oceń pytanie negatywnie - rank_answer_vote_down_label: - other: Oceń odpowiedź negatywnie - rank_invite_someone_to_answer_label: - other: Zaproś kogoś do odpowiedzi - rank_tag_add_label: - other: Utwórz nowy tag - rank_tag_edit_label: - other: Edytuj opis tagu (wymaga akceptacji) - rank_question_edit_label: - other: Edytuj pytanie innych (wymaga akceptacji) - rank_answer_edit_label: - other: Edytuj odpowiedź innych (wymaga akceptacji) - rank_question_edit_without_review_label: - other: Edytuj pytanie innych bez akceptacji - rank_answer_edit_without_review_label: - other: Edytuj odpowiedź innych bez akceptacji - rank_question_audit_label: - other: Przejrzyj edycje pytania - rank_answer_audit_label: - other: Przejrzyj edycje odpowiedzi - rank_tag_audit_label: - other: Przejrzyj edycje tagu - rank_tag_edit_without_review_label: - other: Edytuj opis tagu bez akceptacji - rank_tag_synonym_label: - other: Zarządzaj synonimami tagów - email: - other: E-mail - e_mail: - other: Email - password: - other: Hasło - pass: - other: Hasło - old_pass: - other: Current password - original_text: - other: Ten wpis - email_or_password_wrong_error: - other: Email lub hasło nie są poprawne. - error: - common: - invalid_url: - other: Nieprawidłowy URL. - status_invalid: - other: Nieprawidłowy status. - password: - space_invalid: - other: Hasło nie może zawierać spacji. - admin: - cannot_update_their_password: - other: Nie możesz zmieniać swojego hasła. - cannot_edit_their_profile: - other: Nie możesz modyfikować swojego profilu. - cannot_modify_self_status: - other: Nie możesz modyfikować swojego statusu. - email_or_password_wrong: - other: Emil lub hasło nie są zgodne. - answer: - not_found: - other: Odpowiedź nie została odnaleziona. - cannot_deleted: - other: Brak uprawnień do usunięcia. - cannot_update: - other: Brak uprawnień do aktualizacji. - question_closed_cannot_add: - other: Pytania są zamknięte i nie można ich dodawać. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Komentarz nie może edytować. - not_found: - other: Komentarz nie został odnaleziony. - cannot_edit_after_deadline: - other: Czas komentowania był zbyt długi, aby go zmodyfikować. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: E-mail już istnieje. - need_to_be_verified: - other: E-mail powinien zostać zweryfikowany. - verify_url_expired: - other: Adres URL zweryfikowanej wiadomości e-mail wygasł, prosimy o ponowne wysłanie wiadomości e-mail. - illegal_email_domain_error: - other: Wysyłanie wiadomości e-mail z tej domeny jest niedozwolone. Użyj innej domeny. - lang: - not_found: - other: Nie znaleziono pliku językowego. - object: - captcha_verification_failed: - other: Nieprawidłowa captcha. - disallow_follow: - other: Nie wolno ci podążać za nimi. - disallow_vote: - other: Nie masz uprawnień do głosowania. - disallow_vote_your_self: - other: Nie możesz głosować na własne posty. - not_found: - other: Obiekt nie został odnaleziony. - verification_failed: - other: Weryfikacja nie powiodła się. - email_or_password_incorrect: - other: Email lub hasło są nieprawidłowe. - old_password_verification_failed: - other: Stara weryfikacja hasła nie powiodła się - new_password_same_as_previous_setting: - other: Nowe hasło jest takie samo jak poprzednie. - already_deleted: - other: Ten wpis został usunięty. - meta: - object_not_found: - other: Meta obiekt nie został odnaleziony - question: - already_deleted: - other: Ten post został usunięty. - under_review: - other: Twój post oczekuje na recenzje. Będzie widoczny po jej akceptacji. - not_found: - other: Pytanie nie zostało odnalezione. - cannot_deleted: - other: Brak uprawnień do usunięcia. - cannot_close: - other: Brak uprawnień do zamknięcia. - cannot_update: - other: Brak uprawnień do edycji. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Ranga nie spełnia warunku. - vote_fail_to_meet_the_condition: - other: Dziękujemy za opinię. Potrzebujesz co najmniej {{.Rank}} reputacji, aby oddać głos. - no_enough_rank_to_operate: - other: Potrzebujesz co najmniej {{.Rank}} reputacji, aby to zrobić. - report: - handle_failed: - other: Nie udało się obsłużyć raportu. - not_found: - other: Raport nie został znaleziony. - tag: - already_exist: - other: Tag już istnieje. - not_found: - other: Tag nie został znaleziony. - recommend_tag_not_found: - other: Zalecany tag nie istnieje. - recommend_tag_enter: - other: Proszę wprowadzić przynajmniej jeden wymagany tag. - not_contain_synonym_tags: - other: Nie powinno zawierać tagów synonimów. - cannot_update: - other: Brak uprawnień do aktualizacji. - is_used_cannot_delete: - other: Nie możesz usunąć tagu, który jest w użyciu. - cannot_set_synonym_as_itself: - other: Nie można ustawić synonimu aktualnego tagu jako takiego. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: Nazwą nadawcy nie może być adresem e-mail. - theme: - not_found: - other: Nie znaleziono motywu. - revision: - review_underway: - other: Nie można teraz edytować, istnieje wersja w kolejce sprawdzeń. - no_permission: - other: Brak uprawnień do wersji. - user: - external_login_missing_user_id: - other: Platforma zewnętrzna nie dostarcza unikalnego identyfikatora użytkownika (UserID), dlatego nie możesz się zalogować. Skontaktuj się z administratorem witryny. - external_login_unbinding_forbidden: - other: Proszę ustawić hasło logowania dla swojego konta przed usunięciem tego logowania. - email_or_password_wrong: - other: - other: Adres email i hasło nie są zgodne. - not_found: - other: Użytkownik nie został znaleziony. - suspended: - other: Użytkownik został zawieszony. - username_invalid: - other: Nazwa użytkownika jest nieprawidłowa. - username_duplicate: - other: Nazwa użytkownika jest już zajęta. - set_avatar: - other: Nie udało się ustawić awatara. - cannot_update_your_role: - other: Nie możesz zmienić swojej roli. - not_allowed_registration: - other: Obecnie strona nie zezwala na rejestracje. - not_allowed_login_via_password: - other: Obecnie strona nie zezwala na logowanie się za pomocą hasła. - access_denied: - other: Odmowa dostępu. - page_access_denied: - other: Nie masz dostępu do tej strony. - add_bulk_users_format_error: - other: "Błąd {{.Field}} w pobliżu '{{.Content}}' w linii {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "Liczba użytkowników, których dodasz na raz, powinna mieścić się w przedziale 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Nie udało się odczytać pliku konfiguracyjnego. - database: - connection_failed: - other: Nie udało się połączyć z bazą danych. - create_table_failed: - other: Nie udało się utworzyć tabeli. - install: - create_config_failed: - other: Nie można utworzyć pliku config.yaml. - upload: - unsupported_file_format: - other: Nieobsługiwany format pliku. - site_info: - config_not_found: - other: Nie znaleziono konfiguracji strony. - badge: - object_not_found: - other: Nie znaleziono obiektu odznaki - reason: - spam: - name: - other: spam - desc: - other: Ten post jest reklamą lub wandalizmem. Nie jest przydatny ani istotny dla bieżącego tematu. - rude_or_abusive: - name: - other: niegrzeczny lub obraźliwy - desc: - other: "Rozsądna osoba uznałaby tę treść za nieodpowiednią do dyskusji opartej na szacunku." - a_duplicate: - name: - other: duplikat - desc: - other: To pytanie zostało już wcześniej zadane i ma już odpowiedź. - placeholder: - other: Wprowadź link do istniejącego pytania - not_a_answer: - name: - other: nie jest odpowiedzią - desc: - other: "Ta wiadomość została zamieszczona jako odpowiedź, ale nie próbuje odpowiedzieć na pytanie. Powinna być prawdopodobnie edycją, komentarzem, kolejnym pytaniem lub całkowicie usunięta." - no_longer_needed: - name: - other: nie jest już potrzebne - desc: - other: Ten komentarz jest przestarzały, prowadzi do rozmowy lub nie jest związany z tą wiadomością. - something: - name: - other: coś innego - desc: - other: Ta wiadomość wymaga uwagi personelu z innego powodu, który nie jest wymieniony powyżej. - placeholder: - other: Poinformuj nas dokładnie, o co Ci chodzi - community_specific: - name: - other: powód specyficzny dla społeczności - desc: - other: To pytanie nie spełnia wytycznych społeczności. - not_clarity: - name: - other: wymaga szczegółów lub wyjaśnienia - desc: - other: To pytanie obecnie zawiera wiele pytań w jednym. Powinno skupić się tylko na jednym problemie. - looks_ok: - name: - other: Wygląda poprawnie - desc: - other: Ta wiadomość jest dobra w obecnej formie i nie jest niskiej jakości. - needs_edit: - name: - other: wymaga edycji, a ja to zrobiłem/am - desc: - other: Popraw i skoryguj problemy w tej wiadomości samodzielnie. - needs_close: - name: - other: wymaga zamknięcia - desc: - other: Na zamknięte pytanie nie można odpowiadać, ale wciąż można edytować, głosować i komentować. - needs_delete: - name: - other: wymaga usunięcia - desc: - other: Ta wiadomość zostanie usunięta. - question: - close: - duplicate: - name: - other: spam - desc: - other: To pytanie zostało już wcześniej zadane i ma już odpowiedź. - guideline: - name: - other: powód specyficzny dla społeczności - desc: - other: To pytanie nie spełnia wytycznych społeczności. - multiple: - name: - other: wymaga szczegółów lub wyjaśnienia - desc: - other: To pytanie obecnie zawiera wiele pytań w jednym. Powinno się skupić tylko na jednym problemie. - other: - name: - other: coś innego - desc: - other: Ten post wymaga jeszcze jednego powodu, który nie został wymieniony powyżej. - operation_type: - asked: - other: zapytano - answered: - other: odpowiedziano - modified: - other: zmodyfikowane - deleted_title: - other: Usunięte pytanie - questions_title: - other: Pytania - tag: - tags_title: - other: Tagi - no_description: - other: Tag nie posiada opisu. - notification: - action: - update_question: - other: zaktualizował/a pytanie - answer_the_question: - other: odpowiedz na pytanie - update_answer: - other: aktualizuj odpowiedź - accept_answer: - other: zaakceptował/a odpowiedź - comment_question: - other: skomentował/a pytanie - comment_answer: - other: skomentował/a odpowiedź - reply_to_you: - other: odpowiedział/a tobie - mention_you: - other: wspomniał/a o tobie - your_question_is_closed: - other: Twoje pytanie zostało zamknięte - your_question_was_deleted: - other: Twoje pytanie zostało usunięte - your_answer_was_deleted: - other: Twoja odpowiedź została usunięta - your_comment_was_deleted: - other: Twój komentarz został usunięty - up_voted_question: - other: pytanie przegłosowane - down_voted_question: - other: pytanie odrzucone - up_voted_answer: - other: odpowiedź przegłosowana - down_voted_answer: - other: odrzucona odpowiedź - up_voted_comment: - other: komentarz upvote - invited_you_to_answer: - other: zaproszono Cię do odpowiedzi - earned_badge: - other: Zdobyłeś odznakę "{{.BadgeName}}" - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Potwierdź swój nowy adres e-mail" - body: - other: "Potwierdź swój nowy adres e-mail dla {{.SiteName}}, klikając poniższy link:
        \n{{.ChangeEmailUrl}}

        \n\nJeśli nie prosiłeś(-aś) o zmianę adresu e-mail, zignoruj tę wiadomość.

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} odpowiedział(-a) na pytanie" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}} napisał(-a):
        \n
        {{.AnswerSummary}}

        \nZobacz na {{.SiteName}}

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana.

        \n\nZrezygnuj z subskrypcji" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} zaprosił(-a) Cię do odpowiedzi" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}} napisał(-a):
        \n
        Myślę, że możesz znać odpowiedź.

        \nZobacz na {{.SiteName}}

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana.

        \n\nZrezygnuj z subskrypcji" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} skomentował(-a) Twój wpis" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}} napisał(-a):
        \n
        {{.CommentSummary}}

        \nZobacz na {{.SiteName}}

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana.

        \n\nZrezygnuj z subskrypcji" - new_question: - title: - other: "[{{.SiteName}}] Nowe pytanie: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana.

        \n\nZrezygnuj z subskrypcji" - pass_reset: - title: - other: "[{{.SiteName}}] Reset hasła" - body: - other: "Otrzymaliśmy prośbę o zresetowanie Twojego hasła w serwisie {{.SiteName}}.

        \n\nJeśli to nie Ty wysłałeś(-aś) tę prośbę, możesz bezpiecznie zignorować tę wiadomość.

        \n\nKliknij poniższy link, aby ustawić nowe hasło:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana." - register: - title: - other: "[{{.SiteName}}] Potwierdź swoje nowe konto" - body: - other: "Witamy w {{.SiteName}}!

        \n\nKliknij poniższy link, aby potwierdzić i aktywować swoje nowe konto:
        \n{{.RegisterUrl}}

        \n\nJeśli powyższy link nie jest klikalny, spróbuj skopiować go i wkleić do paska adresu przeglądarki.\n

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana." - test: - title: - other: "[{{.SiteName}}] Wiadomość testowa" - body: - other: "To jest testowa wiadomość e-mail.\n

        \n\n--
        \nUwaga: to jest automatyczna wiadomość systemowa, nie odpowiadaj na nią, ponieważ odpowiedź nie będzie odczytana." - upvote: - other: oceń pozytywnie - upvoted: - other: polubione - downvote: - other: oceń negatywnie - downvoted: - other: oceniono negatywnie - accept: - other: akceptuj - accepted: - other: zaakceptowane - edit: - other: edytuj - review: - queued_post: - other: Post w kolejce - flagged_post: - other: Post oznaczony - suggested_post_edit: - other: Sugerowane zmiany - reaction: - tooltip: - other: "{{ .Names }} już {{ .Count }} razy ..." - badge: - default_badges: - autobiographer: - name: - other: Autobiografista - desc: - other: Wypełniono informacje profil. - certified: - name: - other: Certyfikowany - desc: - other: Ukończono nasz nowy samouczek. - editor: - name: - other: Edytor - desc: - other: Pierwsza edycja posta. - first_flag: - name: - other: Pierwsza flaga - desc: - other: Po raz pierwszy oznaczono post. - first_upvote: - name: - other: Pierwszy pozytywny głos - desc: - other: Po raz pierwszy oddano pozytywny głos na post. - first_link: - name: - other: Pierwszy odnośnik - desc: - other: Po raz pierwszy dodano link do innego wpisu. - - first_reaction: - name: - other: Pierwsza reakcja - desc: - other: Po raz pierwszy zareagowano na wpis. - - first_share: - name: - other: Pierwsze udostępnienie - desc: - other: Po raz pierwszy udostępniono wpis. - - scholar: - name: - other: Scholar - desc: - other: Zadano pytanie i zaakceptowano odpowiedź. - - commentator: - name: - other: Komentator - desc: - other: Pozostawiono 5 komentarzy. - - new_user_of_the_month: - name: - other: Nowy użytkownik miesiąca - desc: - other: Wyjątkowy wkład w pierwszym miesiącu aktywności. - - read_guidelines: - name: - other: Przeczytano zasady - desc: - other: Przeczytano [zasady społeczności]. - - reader: - name: - other: Czytelnik - desc: - other: Przeczytano wszystkie odpowiedzi w wątku mającym ponad 10 odpowiedzi. - - welcome: - name: - other: Witamy - desc: - other: Otrzymano pozytywny głos. - - nice_share: - name: - other: Udane udostępnienie - desc: - other: Udostępniono wpis, który odwiedziło 25 unikalnych użytkowników. - - good_share: - name: - other: Dobre udostępnienie - desc: - other: Udostępniono wpis, który odwiedziło 300 unikalnych użytkowników. - - great_share: - name: - other: Świetne udostępnienie - desc: - other: Udostępniono wpis, który odwiedziło 1000 unikalnych użytkowników. - - out_of_love: - name: - other: Z miłości - desc: - other: Wykorzystano 50 pozytywnych głosów w ciągu dnia. - - higher_love: - name: - other: Więcej miłości - desc: - other: Wykorzystano 50 pozytywnych głosów w ciągu dnia - 5 razy. - - crazy_in_love: - name: - other: Szaleństwo miłości - desc: - other: Wykorzystano 50 pozytywnych głosów w ciągu dnia - 20 razy. - - promoter: - name: - other: Promotor - desc: - other: Zaproszono użytkownika. - - campaigner: - name: - other: Kampanier - desc: - other: Zaproszono 3 podstawowych użytkowników. - - champion: - name: - other: Mistrz - desc: - other: Zaproszono 5 użytkowników. - - thank_you: - name: - other: Dziękuję - desc: - other: Otrzymano 20 pozytywnych głosów i oddano 10. - - gives_back: - name: - other: Oddający dalej - desc: - other: Otrzymano 100 pozytywnych głosów i oddano 100. - - empathetic: - name: - other: Empatyczny - desc: - other: Otrzymano 500 pozytywnych głosów i oddano 1000. - - enthusiast: - name: - other: Entuzjasta - desc: - other: Odwiedzono serwis 10 dni z rzędu. - - aficionado: - name: - other: Koneser - desc: - other: Odwiedzono serwis 100 dni z rzędu. - - devotee: - name: - other: Wytrwały - desc: - other: Odwiedzono serwis 365 dni z rzędu. - - anniversary: - name: - other: Rocznica - desc: - other: Aktywny użytkownik od roku, co najmniej jeden wpis. - - appreciated: - name: - other: Doceniony - desc: - other: Otrzymano 1 pozytywny głos na 20 wpisach. - - respected: - name: - other: Szanujący - desc: - other: Otrzymano 2 pozytywne głosy na 100 wpisach. - - admired: - name: - other: Podziwiany - desc: - other: Otrzymano 5 pozytywnych głosów na 300 wpisach. - - solved: - name: - other: Rozwiązane - desc: - other: Udzielono odpowiedzi, która została zaakceptowana. - - guidance_counsellor: - name: - other: Doradca - desc: - other: 10 udzielonych odpowiedzi zostało zaakceptowanych. - - know_it_all: - name: - other: Wszystkowiedzący - desc: - other: 50 udzielonych odpowiedzi zostało zaakceptowanych. - - solution_institution: - name: - other: Instytucja rozwiązań - desc: - other: 150 udzielonych odpowiedzi zostało zaakceptowanych. - - nice_answer: - name: - other: Dobra odpowiedź - desc: - other: Odpowiedź z wynikiem co najmniej 10. - - good_answer: - name: - other: Bardzo dobra odpowiedź - desc: - other: Odpowiedź z wynikiem co najmniej 25. - - great_answer: - name: - other: Świetna odpowiedź - desc: - other: Odpowiedź z wynikiem co najmniej 50. - - nice_question: - name: - other: Dobre pytanie - desc: - other: Pytanie z wynikiem co najmniej 10. - - good_question: - name: - other: Bardzo dobre pytanie - desc: - other: Pytanie z wynikiem co najmniej 25. - - great_question: - name: - other: Świetne pytanie - desc: - other: Pytanie z wynikiem co najmniej 50. - - popular_question: - name: - other: Popularne pytanie - desc: - other: Pytanie z 500 wyświetleniami. - - notable_question: - name: - other: Zauważalne pytanie - desc: - other: Pytanie z 1000 wyświetleniami. - - famous_question: - name: - other: Słynne pytanie - desc: - other: Pytanie z 5000 wyświetleniami. - - popular_link: - name: - other: Popularny link - desc: - other: Opublikowano zewnętrzny link z 50 kliknięciami. - - hot_link: - name: - other: Gorący link - desc: - other: Opublikowano zewnętrzny link z 300 kliknięciami. - - famous_link: - name: - other: Słynny link - desc: - other: Opublikowano zewnętrzny link z 1000 kliknięciami. - default_badge_groups: - getting_started: - name: - other: Pierwsze kroki - community: - name: - other: Społeczność - posting: - name: - other: Publikowanie -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Jak formatować - desc: >- -
          -
        • wspomnij wpis: #post_id

        • -
        • tworzenie linków

          -
          <https://url.com>

          [Tytuł](https://url.com)
          -
        • -
        • oddziel akapity pustą linią

        • -
        • _kursywa_ lub **pogrubienie**

        • -
        • zagnieźdź kod, dodając 4 spacje na początku wiersza

        • -
        • cytuj, dodając > na początku wiersza

        • -
        • użyj odwrotnego apostrofu (backtick) do zagnieżdżonego kodu `tak _to_ działa`

        • -
        • twórz bloki kodu przy pomocy potrójnych odwrotnych apostrofów `

          -
          ```
          kod tutaj
          ```
          -
        • -
        - prev: Poprzedni - next: Następny - page_title: - question: Pytanie - questions: Pytania - tag: Tag - tags: Tagi - tag_wiki: wiki tagu - create_tag: Utwórz tag - edit_tag: Edytuj tag - ask_a_question: Create Question - edit_question: Edytuj pytanie - edit_answer: Edytuj odpowiedź - search: Szukaj - posts_containing: Posty zawierające - settings: Ustawienia - notifications: Powiadomienia - login: Zaloguj się - sign_up: Zarejestruj się - account_recovery: Odzyskiwanie konta - account_activation: Aktywacja konta - confirm_email: Potwierdź adres e-mail - account_suspended: Konto zawieszone - admin: Administrator - change_email: Zmień e-mail - install: Instalacja Answer - upgrade: Aktualizacja Answer - maintenance: Przerwa techniczna - users: Użytkownicy - oauth_callback: Przetwarzanie - http_404: Błąd HTTP 404 - http_50X: Błąd HTTP 500 - http_403: Błąd HTTP 403 - logout: Wyloguj się - posts: Posts - notifications: - title: Powiadomienia - inbox: Skrzynka odbiorcza - achievement: Osiągnięcia - new_alerts: Nowe powiadomienia - all_read: Oznacz wszystkie jako przeczytane - show_more: Pokaż więcej - someone: Ktoś - inbox_type: - all: Wszystko - posts: Posty - invites: Zaproszenia - votes: Głosy - answer: Answer - question: Question - badge_award: Badge - suspended: - title: Twoje konto zostało zawieszone - until_time: "Twoje konto zostało zawieszone do {{ time }}." - forever: Ten użytkownik został na zawsze zawieszony. - end: Nie spełniasz wytycznych społeczności. - contact_us: Skontaktuj się z nami - editor: - blockquote: - text: Cytat - bold: - text: Pogrubienie - chart: - text: Wykres - flow_chart: Wykres przepływu - sequence_diagram: Diagram sekwencji - class_diagram: Diagram klas - state_diagram: Diagram stanów - entity_relationship_diagram: Diagram związków encji - user_defined_diagram: Diagram zdefiniowany przez użytkownika - gantt_chart: Wykres Gantta - pie_chart: Wykres kołowy - code: - text: Przykład kodu - add_code: Dodaj przykład kodu - form: - fields: - code: - label: Kod - msg: - empty: Kod nie może być pusty. - language: - label: Język - placeholder: Wykrywanie automatyczne - btn_cancel: Anuluj - btn_confirm: Dodaj - formula: - text: Formuła - options: - inline: Formuła w linii - block: Formuła blokowa - heading: - text: Nagłówek - options: - h1: Nagłówek 1 - h2: Nagłówek 2 - h3: Nagłówek 3 - h4: Nagłówek 4 - h5: Nagłówek 5 - h6: Nagłówek 6 - help: - text: Pomoc - hr: - text: Linia pozioma - image: - text: Obrazek - add_image: Dodaj obrazek - tab_image: Prześlij obrazek - form_image: - fields: - file: - label: Plik graficzny - btn: Wybierz obrazek - msg: - empty: Plik nie może być pusty. - only_image: Dozwolone są tylko pliki obrazków. - max_size: File size cannot exceed {{size}} MB. - desc: - label: Opis - tab_url: Adres URL obrazka - form_url: - fields: - url: - label: Adres URL obrazka - msg: - empty: Adres URL obrazka nie może być pusty. - name: - label: Opis - btn_cancel: Anuluj - btn_confirm: Dodaj - uploading: Przesyłanie - indent: - text: Wcięcie - outdent: - text: Wcięcie zewnętrzne - italic: - text: Podkreślenie - link: - text: Hiperłącze - add_link: Dodaj hiperłącze - form: - fields: - url: - label: Adres URL - msg: - empty: Adres URL nie może być pusty. - name: - label: Opis - btn_cancel: Anuluj - btn_confirm: Dodaj - ordered_list: - text: Lista numerowana - unordered_list: - text: Lista wypunktowana - table: - text: Tabela - heading: Nagłówek - cell: Komórka - file: - text: Dołącz pliki - not_supported: "Ten typ pliku nie jest obsługiwany. Spróbuj ponownie z {{file_type}}." - max_size: "Rozmiar dołączanych plików nie może przekraczać {{size}} MB." - close_modal: - title: Zamykam ten post jako... - btn_cancel: Anuluj - btn_submit: Prześlij - remark: - empty: Nie może być puste. - msg: - empty: Proszę wybrać powód. - report_modal: - flag_title: Oznaczam ten post jako... - close_title: Zamykam ten post jako... - review_question_title: Przegląd pytania - review_answer_title: Przegląd odpowiedzi - review_comment_title: Przegląd komentarza - btn_cancel: Anuluj - btn_submit: Prześlij - remark: - empty: Nie może być puste. - msg: - empty: Proszę wybrać powód. - not_a_url: Format adresu URL jest nieprawidłowy. - url_not_match: Wskazany URL nie pasuje do bieżącej witryny. - tag_modal: - title: Utwórz nowy tag - form: - fields: - display_name: - label: Nazwa wyświetlana - msg: - empty: Nazwa wyświetlana nie może być pusta. - range: Nazwa wyświetlana może zawierać maksymalnie 35 znaków. - slug_name: - label: Adres URL slug - desc: Odnośnik URL może zawierać maksymalnie 35 znaków. - msg: - empty: Odnośnik URL nie może być pusty. - range: Odnośnik URL może zawierać maksymalnie 35 znaków. - character: Slug adresu URL zawiera niedozwolony zestaw znaków. - desc: - label: Opis - revision: - label: Wersja - edit_summary: - label: Podsumowanie edycji - placeholder: >- - Krótkie wyjaśnienie zmian (poprawa pisowni, naprawa gramatyki, poprawa formatowania) - btn_cancel: Anuluj - btn_submit: Prześlij - btn_post: Opublikuj nowy tag - tag_info: - created_at: Utworzony - edited_at: Edytowany - history: Historia - synonyms: - title: Synonimy - text: Następujące tagi zostaną przekierowane na - empty: Nie znaleziono synonimów. - btn_add: Dodaj synonim - btn_edit: Edytuj - btn_save: Zapisz - synonyms_text: Następujące tagi zostaną przekierowane na - delete: - title: Usuń ten tag - tip_with_posts: >- -

        Nie można usunąć tagu, który jest używany w postach.

        -

        Najpierw usuń ten tag z powiązanych postów.

        - tip_with_synonyms: >- -

        Nie można usunąć tagu, który ma synonimy.

        -

        Najpierw usuń synonimy przypisane do tego tagu.

        - tip: Czy na pewno chcesz usunąć? - close: Zamknij - merge: - title: Scal tag - source_tag_title: Źródłowy tag - source_tag_description: Źródłowy tag i wszystkie powiązane dane zostaną przemapowane na tag docelowy. - target_tag_title: Docelowy tag - target_tag_description: Po scaleniu zostanie utworzony synonim między tymi dwoma tagami. - no_results: Brak pasujących tagów - btn_submit: Zatwierdź - btn_close: Zamknij - edit_tag: - title: Edytuj tag - default_reason: Edytuj tag - default_first_reason: Dodaj tag - btn_save_edits: Zapisz edycje - btn_cancel: Anuluj - dates: - long_date: D MMM - long_date_with_year: "YYYY MMM D" - long_date_with_time: "YYYY MMM D [o] HH:mm" - now: teraz - x_seconds_ago: "{{count}} sek. temu" - x_minutes_ago: "{{count}} min. temu" - x_hours_ago: "{{count}} godz. temu" - hour: godzina - day: dzień - hours: godziny - days: dni - month: month - months: months - year: rok - reaction: - heart: serce - smile: uśmiech - frown: niezadowolenie - btn_label: dodaj lub usuń reakcje - undo_emoji: cofnij reakcje {{ emoji }} - react_emoji: zareaguj {{ emoji }} - unreact_emoji: usuń reakcje {{ emoji }} - comment: - btn_add_comment: Dodaj komentarz - reply_to: Odpowiedź na - btn_reply: Odpowiedz - btn_edit: Edytuj - btn_delete: Usuń - btn_flag: Zgłoś - btn_save_edits: Zapisz edycje - btn_cancel: Anuluj - show_more: "Jest {{count}} komentarzy, pokaż więcej" - tip_question: >- - Użyj komentarzy, aby poprosić o dodatkowe informacje lub sugerować poprawki. Unikaj udzielania odpowiedzi na pytania w komentarzach. - tip_answer: >- - Użyj komentarzy, aby odpowiedzieć innym użytkownikom lub powiadomić ich o zmianach. Jeśli dodajesz nowe informacje, edytuj swój post zamiast komentować. - tip_vote: Dodaje coś wartościowego do posta - edit_answer: - title: Edytuj odpowiedź - default_reason: Edytuj odpowiedź - default_first_reason: Dodaj odpowiedź - form: - fields: - revision: - label: Rewizja - answer: - label: Odpowiedź - feedback: - characters: Treść musi mieć co najmniej 6 znaków. - edit_summary: - label: Podsumowanie edycji - placeholder: >- - Pokrótce opisz swoje zmiany (poprawa pisowni, naprawa gramatyki, poprawa formatowania) - btn_save_edits: Zapisz edycje - btn_cancel: Anuluj - tags: - title: Tagi - sort_buttons: - popular: Popularne - name: Nazwa - newest: Najnowsze - button_follow: Obserwuj - button_following: Obserwowane - tag_label: pytania - search_placeholder: Filtruj według nazwy tagu - no_desc: Tag nie posiada opisu. - more: Więcej - wiki: Wiki - ask: - title: Utwórz pytanie - edit_title: Edytuj pytanie - default_reason: Edytuj pytanie - default_first_reason: Create question - similar_questions: Podobne pytania - form: - fields: - revision: - label: Rewizja - title: - label: Tytuł - placeholder: Jaki jest temat? Bądź konkretny. - msg: - empty: Tytuł nie może być pusty. - range: Tytuł do 150 znaków - body: - label: Treść - msg: - empty: Treść nie może być pusta. - hint: - optional_body: Opisz, czego dotyczy pytanie. - minimum_characters: "Opisz, czego dotyczy pytanie — wymagane jest co najmniej {{min_content_length}} znaków." - tags: - label: Tagi - msg: - empty: Tagi nie mogą być puste. - answer: - label: Odpowiedź - msg: - empty: Odpowiedź nie może być pusta. - edit_summary: - label: Podsumowanie edycji - placeholder: >- - Pokrótce opisz swoje zmiany (poprawa pisowni, naprawa gramatyki, poprawa formatowania) - btn_post_question: Opublikuj swoje pytanie - btn_save_edits: Zapisz edycje - answer_question: Odpowiedz na swoje pytanie - post_question&answer: Opublikuj swoje pytanie i odpowiedź - tag_selector: - add_btn: Dodaj tag - create_btn: Utwórz nowy tag - search_tag: Wyszukaj tag - hint: Opisz, czego dotyczy Twoja treść — wymagany jest co najmniej jeden tag. - hint_zero_tags: Opisz, czego dotyczy Twoja treść. - hint_more_than_one_tag: "Opisz, czego dotyczy Twoja treść — wymagane są co najmniej {{min_tags_number}} tagi." - no_result: Nie znaleziono pasujących tagów - tag_required_text: Wymagany tag (co najmniej jeden) - header: - nav: - question: Pytania - tag: Tagi - user: Użytkownicy - badges: Odznaki - profile: Profil - setting: Ustawienia - logout: Wyloguj - admin: Administrator - review: Recenzja - bookmark: Zakładki - moderation: Moderacja - search: - placeholder: Szukaj - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Zmień - loading: Wczytywanie... - pic_auth_code: - title: Captcha - placeholder: Wpisz tekst z obrazka powyżej - msg: - empty: Captcha nie może być pusty. - inactive: - first: >- - Czas na ostatni krok! Wysłaliśmy wiadomość aktywacyjną na adres {{mail}}. Prosimy postępować zgodnie z instrukcjami zawartymi w wiadomości w celu aktywacji Twojego konta. - info: "Jeśli nie dotarła, sprawdź folder ze spamem." - another: >- - Wysłaliśmy kolejną wiadomość aktywacyjną na adres {{mail}}. Może to potrwać kilka minut, zanim dotrze; upewnij się, że sprawdzasz folder ze spamem. - btn_name: Ponownie wyślij wiadomość aktywacyjną - change_btn_name: Zmień adres e-mail - msg: - empty: Nie może być puste. - resend_email: - url_label: Czy na pewno chcesz ponownie wysłać e-mail aktywacyjny? - url_text: Możesz również podać powyższy link aktywacyjny użytkownikowi. - login: - login_to_continue: Zaloguj się, aby kontynuować - info_sign: Nie masz jeszcze konta? <1>Zarejestruj się - info_login: Masz już konto? <1>Zaloguj się - agreements: Rejestrując się, wyrażasz zgodę na <1>politykę prywatności i <3>warunki korzystania z usługi. - forgot_pass: Zapomniałeś hasła? - name: - label: Imię - msg: - empty: Imię nie może być puste. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: Adres e-mail - msg: - empty: Adres e-mail nie może być pusty. - password: - label: Hasło - msg: - empty: Hasło nie może być puste. - different: Wprowadzone hasła są niezgodne - account_forgot: - page_title: Zapomniałeś hasła - btn_name: Wyślij mi e-mail odzyskiwania - send_success: >- - Jeśli istnieje konto powiązane z adresem {{mail}}, wkrótce otrzymasz wiadomość e-mail z instrukcjami dotyczącymi resetowania hasła. - email: - label: Adres e-mail - msg: - empty: Adres e-mail nie może być pusty. - change_email: - btn_cancel: Anuluj - btn_update: Zaktualizuj adres e-mail - send_success: >- - Jeśli istnieje konto powiązane z adresem {{mail}}, wkrótce otrzymasz wiadomość e-mail z instrukcjami dotyczącymi zmiany adresu e-mail. - email: - label: Nowy email - msg: - empty: Adres e-mail nie może być pusty. - oauth: - connect: Połącz z {{ auth_name }} - remove: Usuń {{ auth_name }} - oauth_bind_email: - subtitle: Dodaj e-mail odzyskiwania do swojego konta. - btn_update: Zaktualizuj adres e-mail - email: - label: Adres e-mail - msg: - empty: Adres e-mail nie może być pusty. - modal_title: Adres e-mail już istnieje. - modal_content: Ten adres e-mail jest już zarejestrowany. Czy na pewno chcesz połączyć się z istniejącym kontem? - modal_cancel: Zmień adres e-mail - modal_confirm: Połącz z istniejącym kontem - password_reset: - page_title: Resetowanie hasła - btn_name: Zresetuj moje hasło - reset_success: >- - Pomyślnie zmieniono hasło; zostaniesz przekierowany na stronę logowania. - link_invalid: >- - Przepraszamy, ten link do resetowania hasła jest już nieaktualny. Być może Twoje hasło jest już zresetowane? - to_login: Przejdź do strony logowania - password: - label: Hasło - msg: - empty: Hasło nie może być puste. - length: Długość musi wynosić od 8 do 32 znaków. - different: Wprowadzone hasła są niezgodne. - password_confirm: - label: Potwierdź nowe hasło - settings: - page_title: Ustawienia - goto_modify: Przejdź do modyfikacji - nav: - profile: Profil - notification: Powiadomienia - account: Konto - interface: Interfejs - profile: - heading: Profil - btn_name: Zapisz - display_name: - label: Nazwa wyświetlana - msg: Wyświetlana nazwa nie może być pusta. - msg_range: Wyświetlana nazwa musi mieć od 2 do 30 znaków długości. - username: - label: Nazwa użytkownika - caption: Ludzie mogą oznaczać Cię jako "@nazwa_użytkownika". - msg: Nazwa użytkownika nie może być pusta. - msg_range: Nazwa użytkownika musi mieć od 2 do 30 znaków długości. - character: 'Muszą być znaki ze zbioru "a-z", "0-9", "- . _"' - avatar: - label: Zdjęcie profilowe - gravatar: Gravatar - gravatar_text: Możesz zmienić obraz na stronie - custom: Własne - custom_text: Możesz przesłać własne zdjęcie. - default: Systemowe - msg: Prosimy o przesłanie awatara - bio: - label: O mnie - website: - label: Strona internetowa - placeholder: "https://przyklad.com" - msg: Nieprawidłowy format strony internetowej - location: - label: Lokalizacja - placeholder: "Miasto, Kraj" - notification: - heading: Powiadomienia email - turn_on: Włącz - inbox: - label: Powiadomienia skrzynki odbiorczej - description: Odpowiedzi na Twoje pytania, komentarze, zaproszenia i inne. - all_new_question: - label: Wszystkie nowe pytania - description: Otrzymuj powiadomienia o wszystkich nowych pytaniach. Do 50 pytań tygodniowo. - all_new_question_for_following_tags: - label: Wszystkie nowe pytania dla obserwowanych tagów - description: Otrzymuj powiadomienia o nowych pytaniach do obserwowanych tagów. - account: - heading: Konto - change_email_btn: Zmień adres e-mail - change_pass_btn: Zmień hasło - change_email_info: >- - Wysłaliśmy e-mail na ten adres. Prosimy postępować zgodnie z instrukcjami potwierdzającymi. - email: - label: Email - new_email: - label: Nowy Email - msg: Nowy Email nie może być pusty. - pass: - label: Aktualne hasło - msg: Hasło nie może być puste. - password_title: Hasło - current_pass: - label: Aktualne hasło - msg: - empty: Obecne hasło nie może być puste. - length: Długość musi wynosić od 8 do 32 znaków. - different: Dwa wprowadzone hasła nie są zgodne. - new_pass: - label: Nowe hasło - pass_confirm: - label: Potwierdź nowe hasło - interface: - heading: Interfejs - lang: - label: Język Interfejsu - text: Język interfejsu użytkownika. Zmieni się po odświeżeniu strony. - my_logins: - title: Moje logowania - label: Zaloguj się lub zarejestruj na tej stronie za pomocą tych kont. - modal_title: Usuń logowanie - modal_content: Czy na pewno chcesz usunąć to logowanie z Twojego konta? - modal_confirm_btn: Usuń - remove_success: Pomyślnie usunięto - toast: - update: pomyślnie zaktualizowane - update_password: Hasło zostało pomyślnie zmienione. - flag_success: Dzięki za zgłoszenie. - forbidden_operate_self: Zakazane działanie na sobie - review: Twoja poprawka zostanie wyświetlona po zatwierdzeniu. - sent_success: Wysyłanie zakończone powodzeniem - related_question: - title: Related - answers: odpowiedzi - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Ludzie pytali - desc: Wybierz osoby, które mogą znać odpowiedź. - invite: Zaproś do odpowiedzi - add: Dodaj osoby - search: Wyszukaj osoby - question_detail: - action: Akcja - created: Utworzono - Asked: Zadane - asked: zadał(a) - update: Zmodyfikowane - Edited: Wyedytowane - edit: edytowany - commented: skomentowano - Views: Wyświetlone - Follow: Obserwuj - Following: Obserwuje - follow_tip: Obserwuj to pytanie, aby otrzymywać powiadomienia - answered: odpowiedziano - closed_in: Zamknięte za - show_exist: Pokaż istniejące pytanie. - useful: Przydatne - question_useful: Jest przydatne i jasne - question_un_useful: Jest niejasne lub nieprzydatne - question_bookmark: Dodaj do zakładek to pytanie - answer_useful: Jest przydatna - answer_un_useful: To nie jest użyteczne - answers: - title: Odpowiedzi - score: Ocena - newest: Najnowsze - oldest: Najstarsze - btn_accept: Akceptuj - btn_accepted: Zaakceptowane - write_answer: - title: Twoja odpowiedź - edit_answer: Edytuj moją obecną odpowiedź - btn_name: Wyślij swoją odpowiedź - add_another_answer: Dodaj kolejną odpowiedź - confirm_title: Kontynuuj odpowiedź - continue: Kontynuuj - confirm_info: >- -

        Czy na pewno chcesz dodać kolejną odpowiedź?

        Możesz zamiast tego użyć linku edycji, aby udoskonalić i poprawić istniejącą odpowiedź.

        - empty: Odpowiedź nie może być pusta. - characters: Treść musi mieć co najmniej 6 znaków. - tips: - header_1: Dziękujemy za Twoją odpowiedź - li1_1: Prosimy, upewnij się, że odpowiadasz na pytanie. Podaj szczegóły i podziel się swoimi badaniami. - li1_2: Popieraj swoje stwierdzenia referencjami lub osobistym doświadczeniem. - header_2: Ale unikaj ... - li2_1: Prośby o pomoc, pytania o wyjaśnienie lub odpowiadanie na inne odpowiedzi. - reopen: - confirm_btn: Ponowne otwarcie - title: Otwórz ponownie ten post - content: Czy na pewno chcesz go ponownie otworzyć? - list: - confirm_btn: Lista - title: Pokaż ten post - content: Czy na pewno chcesz wyświetlić tę listę? - unlist: - confirm_btn: Usuń z listy - title: Usuń ten post z listy - content: Czy na pewno chcesz usunąć z listy? - pin: - title: Przypnij ten post - content: Czy na pewno chcesz przypiąć go globalnie? Ten post będzie wyświetlany na górze wszystkich list postów. - confirm_btn: Przypnij - delete: - title: Usuń ten post - question: >- - Nie zalecamy usuwanie pytań wraz z udzielonymi, ponieważ pozbawia to przyszłych czytelników tej wiedzy.

        Powtarzające się usuwanie pytań z odpowiedziami może skutkować zablokowaniem Twojego konta w zakresie zadawania pytań. Czy na pewno chcesz usunąć? - answer_accepted: >- -

        Nie zalecamy usuwania zaakceptowanych już odpowiedzi, ponieważ pozbawia to przyszłych czytelników tej wiedzy.

        Powtarzające się usuwanie zaakceptowanych odpowiedzi może skutkować zablokowaniem Twojego konta w zakresie udzielania odpowiedzi. Czy na pewno chcesz usunąć? - other: Czy na pewno chcesz usunąć? - tip_answer_deleted: Ta odpowiedź została usunięta - undelete_title: Cofnij usunięcie tego posta - undelete_desc: Czy na pewno chcesz cofnąć usunięcie? - btns: - confirm: Potwierdź - cancel: Anuluj - edit: Edytuj - save: Zapisz - delete: Usuń - undelete: Przywróć - list: Lista - unlist: Usuń z listy - unlisted: Usunięte z listy - login: Zaloguj się - signup: Zarejestruj się - logout: Wyloguj się - verify: Zweryfikuj - create: Create - approve: Zatwierdź - reject: Odrzuć - skip: Pominięcie - discard_draft: Odrzuć szkic - pinned: Przypięte - all: Wszystkie - question: Pytanie - answer: Odpowiedź - comment: Komentarz - refresh: Odśwież - resend: Wyślij ponownie - deactivate: Deaktywuj - active: Aktywne - suspend: Zawieś - unsuspend: Cofnij zawieszenie - close: Zamknij - reopen: Otwórz ponownie - ok: Ok - light: Jasny - dark: Ciemny - system_setting: Ustawienia systemowe - default: Domyślne - reset: Reset - tag: Tag - post_lowercase: wpis - filter: Filtry - ignore: Ignoruj - submit: Prześlij - normal: Normalny - closed: Zamknięty - deleted: Usunięty - deleted_permanently: Usunięto trwale - pending: Oczekujący - more: Więcej - view: Podgląd - card: Karta - compact: Kompakt - display_below: Wyświetl poniżej - always_display: Wyświetlaj zawsze - or: lub - back_sites: Powrót do stron - search: - title: Wyniki wyszukiwania - keywords: Słowa kluczowe - options: Opcje - follow: Obserwuj - following: Obserwuje - counts: "Liczba wyników: {{count}}" - counts_loading: "... Wyniki" - more: Więcej - sort_btns: - relevance: Relewantność - newest: Najnowsze - active: Aktywne - score: Ocena - more: Więcej - tips: - title: Porady dotyczące wyszukiwania zaawansowanego - tag: "<1>[tag] search with a tag" - user: "<1>user:username wyszukiwanie według autora" - answer: "<1> answers:0 pytania bez odpowiedzi" - score: "<1>score:3 posty z oceną 3+" - question: "<1>is:question wyszukiwanie pytań" - is_answer: "<1>is:answer wyszukiwanie odpowiedzi" - empty: Nie mogliśmy niczego znaleźć.
        Wypróbuj inne lub mniej konkretne słowa kluczowe. - share: - name: Udostępnij - copy: Skopiuj link - via: Udostępnij post za pośrednictwem... - copied: Skopiowano - facebook: Udostępnij na Facebooku - twitter: Udostępnij na X - cannot_vote_for_self: Nie możesz głosować na własne posty. - modal_confirm: - title: Błąd... - delete_permanently: - title: Usuń trwale - content: Czy na pewno chcesz usunąć to trwale? - account_result: - success: Twoje nowe konto zostało potwierdzone; zostaniesz przekierowany na stronę główną. - link: Kontynuuj do strony głównej - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: Twój adres e-mail został zaktualizowany. - confirm_new_email_invalid: >- - Przepraszamy, ten link potwierdzający jest już nieaktualny. Być może twój adres e-mail został już zmieniony? - unsubscribe: - page_title: Wypisz się - success_title: Pomyślne anulowanie subskrypcji - success_desc: Zostałeś pomyślnie usunięty z listy subskrybentów i nie będziesz otrzymywać dalszych wiadomości e-mail od nas. - link: Zmień ustawienia - question: - following_tags: Obserwowane tagi - edit: Edytuj - save: Zapisz - follow_tag_tip: Obserwuj tagi, aby dostosować listę pytań. - hot_questions: Gorące pytania - all_questions: Wszystkie pytania - x_questions: "{{ count }} pytań" - x_answers: "{{ count }} odpowiedzi" - x_posts: "{{ count }} Posts" - questions: Pytania - answers: Odpowiedzi - newest: Najnowsze - active: Aktywne - hot: Gorące - frequent: Częste - recommend: Polecane - score: Ocena - unanswered: Bez odpowiedzi - modified: zmodyfikowane - answered: udzielone odpowiedzi - asked: zadane - closed: zamknięte - follow_a_tag: Podążaj za tagiem - more: Więcej - personal: - overview: Przegląd - answers: Odpowiedzi - answer: odpowiedź - questions: Pytania - question: pytanie - bookmarks: Zakładki - reputation: Reputacja - comments: Komentarze - votes: Głosy - badges: Odznaczenia - newest: Najnowsze - score: Ocena - edit_profile: Edytuj Profil - visited_x_days: "Odwiedzone przez {{ count }} dni" - viewed: Wyświetlone - joined: Dołączył - comma: "," - last_login: Widziano - about_me: O mnie - about_me_empty: "// Hello, World !" - top_answers: Najlepsze odpowiedzi - top_questions: Najlepsze pytania - stats: Statystyki - list_empty: Nie znaleziono wpisów.
        Być może chcesz wybrać inną kartę? - content_empty: No posts found. - accepted: Zaakceptowane - answered: Udzielone odpowiedzi - asked: zapytano - downvoted: oceniono negatywnie - mod_short: MOD - mod_long: Moderatorzy - x_reputation: reputacja - x_votes: otrzymane głosy - x_answers: odpowiedzi - x_questions: pytania - recent_badges: Ostatnie odznaki - install: - title: Instalacja - next: Dalej - done: Zakończono - config_yaml_error: Nie można utworzyć pliku config.yaml. - lang: - label: Wybierz język - db_type: - label: Silnik bazy danych - db_username: - label: Nazwa użytkownika - placeholder: root - msg: Nazwa użytkownika nie może być pusta. - db_password: - label: Hasło - placeholder: turbo-tajne-hasło - msg: Hasło nie może być puste. - db_host: - label: Host bazy danych (ewentualnie dodatkowo port) - placeholder: "db.domena:3306" - msg: Host bazy danych nie może być pusty. - db_name: - label: Nazwa bazy danych - placeholder: odpowiedź - msg: Nazwa bazy danych nie może być pusta. - db_file: - label: Plik bazy danych - placeholder: /data/answer.db - msg: Plik bazy danych nie może być pusty. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: Ścieżka do pliku sslrootcert - msg: Ścieżka do pliku sslrootcert nie może być pusta - ssl_cert: - placeholder: Ścieżka do pliku sslcert - msg: Ścieżka do pliku sslcert nie może być pusta - ssl_key: - placeholder: Ścieżka do pliku sslkey - msg: Ścieżka do pliku sslkey nie może być pusta - config_yaml: - title: Utwórz plik config.yaml - label: Plik config.yaml utworzony. - desc: >- - Możesz ręcznie utworzyć plik <1>config.yaml w katalogu <1>/var/wwww/xxx/ i wkleić do niego poniższy tekst. - info: Gdy już to zrobisz, kliknij przycisk "Dalej". - site_information: Informacje o witrynie - admin_account: Konto administratora - site_name: - label: Nazwa witryny - msg: Nazwa witryny nie może być pusta. - msg_max_length: Nazwa witryny musi mieć maksymalnie 30 znaków. - site_url: - label: Adres URL - text: Adres twojej strony. - msg: - empty: Adres URL nie może być pusty. - incorrect: Niepoprawny format adresu URL. - max_length: Adres URL witryny musi mieć maksymalnie 512 znaków. - contact_email: - label: Email kontaktowy - text: Email do osób odpowiedzialnych za tą witrynę. - msg: - empty: Email kontaktowy nie może być pusty. - incorrect: Email do kontaktu ma niepoprawny format. - login_required: - label: Prywatne - switch: Wymagane logowanie - text: Dostęp do tej społeczności mają tylko zalogowani użytkownicy. - admin_name: - label: Imię - msg: Imię nie może być puste. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Hasło - text: >- - Będziesz potrzebować tego hasła do logowania. Przechowuj je w bezpiecznym miejscu. - msg: Hasło nie może być puste. - msg_min_length: Hasło musi mieć co najmniej 8 znaków. - msg_max_length: Hasło musi mieć maksymalnie 32 znaki. - admin_confirm_password: - label: "Potwierdź hasło" - text: "Wprowadź ponownie swoje hasło, aby potwierdzić." - msg: "Potwierdzenie hasła nie jest zgodne." - admin_email: - label: Email - text: Będziesz potrzebować tego adresu e-mail do logowania. - msg: - empty: Adres e-mail nie może być pusty. - incorrect: Niepoprawny format adresu e-mail. - ready_title: Twoja strona jest gotowa - ready_desc: >- - Jeśli kiedykolwiek zechcesz zmienić więcej ustawień, odwiedź <1>sekcję administratora; znajdziesz ją w menu strony. - good_luck: "Baw się dobrze i powodzenia!" - warn_title: Ostrzeżenie - warn_desc: >- - Plik <1>config.yaml już istnieje. Jeśli chcesz zresetować którekolwiek z elementów konfiguracji w tym pliku, proszę go najpierw usunąć. - install_now: Możesz teraz <1>rozpocząć instalację. - installed: Już zainstalowane - installed_desc: >- - Wygląda na to, że masz już zainstalowaną instancję Answer. Aby zainstalować ponownie, proszę najpierw wyczyścić tabele bazy danych. - db_failed: Połączenie z bazą danych nie powiodło się - db_failed_desc: >- - Oznacza to, że informacje o bazie danych w pliku <1>config.yaml są nieprawidłowe lub że nie można nawiązać połączenia z serwerem bazy danych. Może to oznaczać, że serwer bazy danych wskazanego hosta nie działa. - counts: - views: widoki - votes: głosów - answers: odpowiedzi - accepted: Zaakceptowane - page_error: - http_error: Błąd HTTP {{ code }} - desc_403: Nie masz uprawnień do dostępu do tej strony. - desc_404: Niestety, ta strona nie istnieje. - desc_50X: Serwer napotkał błąd i nie mógł zrealizować twojego żądania. - back_home: Powrót do strony głównej - page_maintenance: - desc: "Trwa konserwacja, wrócimy wkrótce." - nav_menus: - dashboard: Panel kontrolny - contents: Zawartość - questions: Pytania - answers: Odpowiedzi - users: Użytkownicy - badges: Badges - flags: Flagi - settings: Ustawienia - general: Ogólne - interface: Interfejs - smtp: SMTP - branding: Marka - legal: Prawne - write: Pisanie - terms: Terms - tos: Warunki korzystania z usługi - privacy: Prywatność - seo: SEO - customize: Dostosowywanie - themes: Motywy - login: Logowanie - privileges: Uprawnienia - plugins: Wtyczki - installed_plugins: Zainstalowane wtyczki - apperance: Wygląd - website_welcome: Witamy w serwisie {{site_name}} - user_center: - login: Zaloguj się - qrcode_login_tip: Zeskanuj kod QR za pomocą {{ agentName }} i zaloguj się. - login_failed_email_tip: Logowanie nie powiodło się, przed ponowną próbą zezwól na dostęp tej aplikacji do informacji o Twojej skrzynce pocztowej. - badges: - modal: - title: Gratulacje - content: Zdobyłeś nową odznakę. - close: Zamknij - confirm: Zobacz odznaki - title: Odznaki - awarded: Przyznano - earned_×: Zdobyto ×{{ number }} - ×_awarded: „{{ number }} przyznano” - can_earn_multiple: Możesz zdobyć tę odznakę wielokrotnie. - earned: Zdobyto - admin: - admin_header: - title: Administrator - dashboard: - title: Panel - welcome: Witaj Administratorze! - site_statistics: Statystyki witryny - questions: "Pytania:" - resolved: "Rozwiązane:" - unanswered: "Bez odpowiedzi:" - answers: "Odpowiedzi:" - comments: "Komentarze:" - votes: "Głosy:" - users: "Użytkownicy:" - flags: "Zgłoszenia:" - reviews: "Przeglądy:" - site_health: "Stan serwisu" - version: "Wersja:" - https: "HTTPS:" - upload_folder: "Prześlij folder:" - run_mode: "Tryb pracy:" - private: Prywatne - public: Publiczne - smtp: "SMTP:" - timezone: "Strefa czasowa:" - system_info: Informacje o systemie - go_version: "Wersja Go:" - database: "Baza danych:" - database_size: "Wielkość bazy danych:" - storage_used: "Wykorzystane miejsce:" - uptime: "Czas pracy:" - links: Linki - plugins: Wtyczki - github: GitHub - blog: Blog - contact: Kontakt - forum: Forum - documents: Dokumenty - feedback: Opinie - support: Wsparcie - review: Przegląd - config: Konfiguracja - update_to: Zaktualizuj do - latest: Najnowszej - check_failed: Sprawdzanie nie powiodło się - "yes": "Tak" - "no": "Nie" - not_allowed: Nie dozwolone - allowed: Dozwolone - enabled: Włączone - disabled: Wyłączone - writable: Zapis i odczyt - not_writable: Nie można zapisać - flags: - title: Flagi - pending: Oczekujące - completed: Zakończone - flagged: Oznaczone - flagged_type: Oznaczone {{ type }} - created: Utworzone - action: Akcja - review: Przegląd - user_role_modal: - title: Zmień rolę użytkownika na... - btn_cancel: Anuluj - btn_submit: Wyślij - new_password_modal: - title: Ustaw nowe hasło - form: - fields: - password: - label: Hasło - text: Użytkownik zostanie wylogowany i musi zalogować się ponownie. - msg: Hasło musi mieć od 8 do 32 znaków. - btn_cancel: Anuluj - btn_submit: Prześlij - edit_profile_modal: - title: Edytuj profil - form: - fields: - display_name: - label: Wyświetlana nazwa - msg_range: Wyświetlana nazwa musi mieć od 2 do 30 znaków. - username: - label: Nazwa użytkownika - msg_range: Nazwa użytkownika musi mieć od 2 do 30 znaków. - email: - label: Email - msg_invalid: Błędny adres e-mail. - edit_success: Edycja zakończona pomyślnie - btn_cancel: Anuluj - btn_submit: Prześlij - user_modal: - title: Dodaj nowego użytkownika - form: - fields: - users: - label: Masowo dodaj użytkownika - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Oddziel "nazwa, e-mail, hasło" przecinkami. Jeden użytkownik na linię. - msg: "Podaj adresy e-mail użytkowników, jeden w każdej linii." - display_name: - label: Nazwa wyświetlana - msg: Wyświetlana nazwa musi mieć od 2 do 30 znaków. - email: - label: E-mail - msg: Email nie jest prawidłowy. - password: - label: Hasło - msg: Hasło musi mieć od 8 do 32 znaków. - btn_cancel: Anuluj - btn_submit: Prześlij - users: - title: Użytkownicy - name: Imię - email: E-mail - reputation: Reputacja - created_at: Czas utworzenia - delete_at: Czas usunięcia - suspend_at: Czas zawieszenia - suspend_until: Zawieszone do - status: Status - role: Rola - action: Akcja - change: Zmień - all: Wszyscy - staff: Personel - more: Więcej - inactive: Nieaktywni - suspended: Zawieszeni - deleted: Usunięci - normal: Normalni - Moderator: Moderator - Admin: Administrator - User: Użytkownik - filter: - placeholder: "Filtruj według imienia, użytkownik:id" - set_new_password: Ustaw nowe hasło - edit_profile: Edytuj profil - change_status: Zmień status - change_role: Zmień rolę - show_logs: Pokaż logi - add_user: Dodaj użytkownika - deactivate_user: - title: Dezaktywuj użytkownika - content: Nieaktywny użytkownik musi ponownie potwierdzić swój adres email. - delete_user: - title: Usuń tego użytkownika - content: Czy na pewno chcesz usunąć tego użytkownika? Ta operacja jest nieodwracalna! - remove: Usuń zawartość - label: Usuń wszystkie pytania, odpowiedzi, komentarze itp. - text: Nie zaznaczaj tego, jeśli chcesz usunąć tylko konto użytkownika. - suspend_user: - title: Zawieś tego użytkownika - content: Zawieszony użytkownik nie może się logować. - label: Na jak długo użytkownik zostanie zawieszony? - forever: Na zawsze - questions: - page_title: Pytania - unlisted: Unlisted - post: Wpis - votes: Głosy - answers: Odpowiedzi - created: Utworzone - status: Status - action: Akcja - change: Zmień - pending: Oczekuje - filter: - placeholder: "Filtruj według tytułu, pytanie:id" - answers: - page_title: Odpowiedzi - post: Wpis - votes: Głosy - created: Utworzone - status: Status - action: Akcja - change: Zmień - filter: - placeholder: "Filtruj według tytułu, odpowiedź:id" - general: - page_title: Ogólne - name: - label: Nazwa witryny - msg: Nazwa strony nie może być pusta. - text: "Nazwa tej strony, używana w tagu tytułu." - site_url: - label: URL strony - msg: Adres Url witryny nie może być pusty. - validate: Podaj poprawny adres URL. - text: Adres Twojej strony. - short_desc: - label: Krótki opis witryny - msg: Krótki opis strony nie może być pusty. - text: "Krótki opis, używany w tagu tytułu na stronie głównej." - desc: - label: Opis witryny - msg: Opis strony nie może być pusty. - text: "Opisz tę witrynę w jednym zdaniu, użytym w znaczniku meta description." - contact_email: - label: Email kontaktowy - msg: Email kontaktowy nie może być pusty. - validate: Email kontaktowy nie jest poprawny. - text: Adres email głównego kontaktu odpowiedzialnego za tę stronę. - check_update: - label: Aktualizacjia oprogramowania - text: Automatycznie sprawdzaj dostępność aktualizacji - interface: - page_title: Interfejs - language: - label: Język Interfejsu - msg: Język interfejsu nie może być pusty. - text: Język interfejsu użytkownika. Zmieni się po odświeżeniu strony. - time_zone: - label: Strefa czasowa - msg: Strefa czasowa nie może być pusta. - text: Wybierz miasto w tej samej strefie czasowej, co Ty. - avatar: - label: Domyślny awatar - text: Dla użytkowników, którzy nie ustawili własnego awatara. - gravatar_base_url: - label: Bazowy URL Gravatara - text: Adres bazowy API dostawcy Gravatara. Ignorowane, jeśli puste. - smtp: - page_title: SMTP - from_email: - label: Email nadawcy - msg: Email nadawcy nie może być pusty. - text: Adres email, z którego są wysyłane wiadomości. - from_name: - label: Nazwa w polu Od - msg: Nazwa nadawcy nie może być pusta. - text: Nazwa, z której są wysyłane wiadomości. - smtp_host: - label: Serwer SMTP - msg: Host SMTP nie może być pusty. - text: Twój serwer poczty. - encryption: - label: Szyfrowanie - msg: Szyfrowanie nie może być puste. - text: Dla większości serwerów zalecana jest opcja SSL. - ssl: SSL - tls: TLS - none: Brak - smtp_port: - label: Port SMTP - msg: Port SMTP musi być liczbą od 1 do 65535. - text: Port Twojego serwera poczty. - smtp_username: - label: Nazwa użytkownika SMTP - msg: Nazwa użytkownika SMTP nie może być pusta. - smtp_password: - label: Hasło SMTP - msg: Hasło SMTP nie może być puste. - test_email_recipient: - label: Odbiorcy testowych wiadomości email - text: Podaj adres email, który otrzyma testowe wiadomości. - msg: Odbiorcy testowych wiadomości email są nieprawidłowi - smtp_authentication: - label: Wymagaj uwierzytelniania - title: Uwierzytelnianie SMTP - msg: Uwierzytelnianie SMTP nie może być puste. - "yes": "Tak" - "no": "Nie" - branding: - page_title: Marka - logo: - label: Logo - msg: Logo nie może być puste. - text: Obrazek logo znajdujący się na górze lewej strony Twojej strony. Użyj szerokiego prostokątnego obrazka o wysokości 56 pikseli i proporcjach większych niż 3:1. Jeśli zostanie puste, wyświetlony zostanie tekst tytułu strony. - mobile_logo: - label: Logo mobilne - text: Logo używane w wersji mobilnej Twojej strony. Użyj szerokiego prostokątnego obrazka o wysokości 56 pikseli. Jeśli zostanie puste, użyty zostanie obrazek z ustawienia "logo". - square_icon: - label: Kwadratowa ikona - msg: Kwadratowa ikona nie może być pusta. - text: Obrazek używany jako podstawa dla ikon metadanych. Powinien mieć idealnie większe wymiary niż 512x512 pikseli. - favicon: - label: Ikona (favicon) - text: Ulubiona ikona witryny. Aby działać poprawnie przez CDN, musi to być png. Rozmiar zostanie zmieniony na 32x32. Jeśli pozostanie puste, zostanie użyta "kwadratowa ikona". - legal: - page_title: Prawne - terms_of_service: - label: Warunki korzystania z usługi - text: "Możesz tutaj dodać treść regulaminu. Jeśli masz dokument hostowany gdzie indziej, podaj tutaj pełny URL." - privacy_policy: - label: Polityka prywatności - text: "Możesz tutaj dodać treść polityki prywatności. Jeśli masz dokument hostowany gdzie indziej, podaj tutaj pełny URL." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Pisanie - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Każdy użytkownik może napisać tylko jedną odpowiedź na każde pytanie - text: "Wyłącz, aby pozwolić użytkownikom pisać wiele odpowiedzi na to samo pytanie, co może powodować, że odpowiedzi będą mniej skupione." - min_tags: - label: "Minimalna liczba tagów na pytanie" - text: "Minimalna liczba tagów wymagana w pytaniu." - recommend_tags: - label: Rekomendowane tagi - text: "Rekomendowane tagi będą domyślnie wyświetlane na liście wyboru." - msg: - contain_reserved: "Rekomendowane tagi nie mogą zawierać tagów zarezerwowanych." - required_tag: - title: Ustaw wymagane tagi - label: Ustaw „Rekomendowane tagi” jako wymagane - text: "Każde nowe pytanie musi mieć przynajmniej jeden rekomendowany tag." - reserved_tags: - label: Zarezerwowane tagi - text: "Zarezerwowane tagi mogą być używane tylko przez moderatorów." - image_size: - label: Maksymalny rozmiar obrazu (MB) - text: "Maksymalny dopuszczalny rozmiar przesyłanego obrazu." - attachment_size: - label: Maksymalny rozmiar załącznika (MB) - text: "Maksymalny dopuszczalny rozmiar przesyłanych plików." - image_megapixels: - label: Maksymalna liczba megapikseli - text: "Maksymalna liczba megapikseli dopuszczona dla obrazu." - image_extensions: - label: Dozwolone rozszerzenia obrazów - text: "Lista rozszerzeń plików dozwolonych dla obrazów; oddziel po przecinkach." - attachment_extensions: - label: Dozwolone rozszerzenia załączników - text: "Lista rozszerzeń plików dozwolonych do przesyłania; oddziel po przecinkach. UWAGA: Zezwolenie na przesyłanie plików może powodować ryzyko bezpieczeństwa." - seo: - page_title: SEO - permalink: - label: Link bezpośredni - text: Dostosowane struktury URL mogą poprawić użyteczność i kompatybilność w przyszłości Twoich linków. - robots: - label: robots.txt - text: To trwale zastąpi wszelkie związane z witryną ustawienia. - themes: - page_title: Motywy - themes: - label: Motywy - text: Wybierz istniejący motyw. - color_scheme: - label: Schemat kolorów - navbar_style: - label: Navbar background style - primary_color: - label: Kolor podstawowy - text: Zmodyfikuj kolory używane przez Twoje motywy. - css_and_html: - page_title: CSS i HTML - custom_css: - label: Własny CSS - text: > - - head: - label: Głowa - text: > - - header: - label: Nagłówek - text: > - - footer: - label: Stopka - text: Zostanie wstawione przed </body>. - sidebar: - label: Pasek boczny - text: Będzie wstawiony w pasku bocznym. - login: - page_title: Logowanie - membership: - title: Członkostwo - label: Zezwalaj na nowe rejestracje - text: Wyłącz, aby uniemożliwić komukolwiek tworzenie nowego konta. - email_registration: - title: Rejestracja przez email - label: Zezwalaj na rejestrację przez email - text: Wyłącz, aby uniemożliwić tworzenie nowego konta poprzez email. - allowed_email_domains: - title: Dozwolone domeny email - text: Domeny email, z których użytkownicy muszą rejestrować konta. Jeden domena na linię. Ignorowane, gdy puste. - private: - title: Prywatne - label: Wymagane logowanie - text: Dostęp do tej społeczności mają tylko zalogowani użytkownicy. - password_login: - title: Hasło logowania - label: Zezwalaj na logowanie email i hasłem - text: "OSTRZEŻENIE: Jeśli wyłączone, już się nie zalogujesz, jeśli wcześniej nie skonfigurowałeś innej metody logowania." - installed_plugins: - title: Zainstalowane wtyczki - plugin_link: Wtyczki rozszerzają i rozbudowują funkcjonalność. Wtyczki znajdziesz w <1>Repozytorium Wtyczek. - filter: - all: Wszystkie - active: Aktywne - inactive: Nieaktywne - outdated: Przestarzałe - plugins: - label: Wtyczki - text: Wybierz istniejącą wtyczkę. - name: Nazwa - version: Wersja - status: Status - action: Akcja - deactivate: Deaktywuj - activate: Aktywuj - settings: Ustawienia - settings_users: - title: Użytkownicy - avatar: - label: Domyślny Awatar - text: Dla użytkowników bez własnego awatara. - gravatar_base_url: - label: Adres URL bazy Gravatar - text: Adres URL bazy API dostawcy Gravatar. Ignorowane, gdy puste. - profile_editable: - title: Edycja profilu - allow_update_display_name: - label: Zezwalaj użytkownikom na zmianę wyświetlanej nazwy - allow_update_username: - label: Zezwalaj użytkownikom na zmianę nazwy użytkownika - allow_update_avatar: - label: Zezwalaj użytkownikom na zmianę obrazka profilowego - allow_update_bio: - label: Zezwalaj użytkownikom na zmianę opisu - allow_update_website: - label: Zezwalaj użytkownikom na zmianę witryny - allow_update_location: - label: Zezwalaj użytkownikom na zmianę lokalizacji - privilege: - title: Uprawnienia - level: - label: Wymagany poziom reputacji - text: Wybierz reputację wymaganą dla tego uprawnienia - msg: - should_be_number: Wartość musi być liczbą - number_larger_1: Liczba musi być równa 1 lub większa - badges: - action: Akcja - active: Aktywne - activate: Aktywuj - all: Wszystkie - awards: Przyznane - deactivate: Dezaktywuj - filter: - placeholder: Filtruj po nazwie, badge:id - group: Grupa - inactive: Nieaktywne - name: Nazwa - show_logs: Wyświetl dzienniki - status: Status - title: Odznaki - form: - optional: (opcjonalne) - empty: nie może być puste - invalid: jest nieprawidłowe - btn_submit: Zapisz - not_found_props: "Nie znaleziono wymaganej właściwości {{ key }}." - select: Wybierz - page_review: - review: Przegląd - proposed: zaproponowany - question_edit: Edycja pytania - answer_edit: Edycja odpowiedzi - tag_edit: Edycja tagu - edit_summary: Podsumowanie edycji - edit_question: Edytuj pytanie - edit_answer: Edytuj odpowiedź - edit_tag: Edytuj tag - empty: Nie ma więcej zadań do przeglądu. - approve_revision_tip: Czy akceptujesz tę wersję? - approve_flag_tip: Czy akceptujesz tę flagę? - approve_post_tip: Czy zatwierdzasz ten post? - approve_user_tip: Czy zatwierdzasz tego użytkownika? - suggest_edits: Sugerowane edycje - flag_post: Oznacz wpis - flag_user: Oznacz użytkownika - queued_post: Oczekujący post - queued_user: Oczekujący użytkownik - filter_label: Typ - reputation: reputacja - flag_post_type: Oznaczono ten wpis jako {{ type }}. - flag_user_type: Oznaczono tego użytkownika jako {{ type }}. - edit_post: Edytuj wpis - list_post: List post - unlist_post: Unlist post - timeline: - undeleted: nieusunięte - deleted: usunięty - downvote: odrzucenie - upvote: głos za - accept: akceptacja - cancelled: anulowane - commented: skomentowano - rollback: wycofaj - edited: edytowany - answered: odpowiedziano - asked: zapytano - closed: zamknięty - reopened: ponownie otwarty - created: utworzony - pin: przypięty - unpin: odpięty - show: wymieniony - hide: niewidoczne - title: "Historia dla" - tag_title: "Historia dla" - show_votes: "Pokaż głosy" - n_or_a: Nie dotyczy - title_for_question: "Historia dla" - title_for_answer: "Oś czasu dla odpowiedzi na {{ tytuł }} autorstwa {{ autor }}" - title_for_tag: "Oś czasu dla tagu" - datetime: Data i czas - type: Typ - by: Przez - comment: Komentarz - no_data: "Nie mogliśmy nic znaleźć." - users: - title: Użytkownicy - users_with_the_most_reputation: Użytkownicy o najwyższej reputacji w tym tygodniu - users_with_the_most_vote: Użytkownicy, którzy oddali najwięcej głosów w tym tygodniu - staffs: Nasz personel społeczności - reputation: reputacja - votes: głosy - prompt: - leave_page: Czy na pewno chcesz opuścić stronę? - changes_not_save: Twoje zmiany mogą nie zostać zapisane. - draft: - discard_confirm: Czy na pewno chcesz odrzucić swoją wersję roboczą? - messages: - post_deleted: Ten post został usunięty. - post_cancel_deleted: Usunięcie tego posta zostało anulowane. - post_pin: Ten post został przypięty. - post_unpin: Ten post został odpięty. - post_hide_list: Ten post został ukryty na liście. - post_show_list: Ten post został wyświetlony na liście. - post_reopen: Ten post został ponownie otwarty. - post_list: Ten wpis został umieszczony na liście. - post_unlist: Ten wpis został usunięty z listy. - post_pending: Twój wpis oczekuje na recenzje. Będzie widoczny po jej akceptacji. - post_closed: Ten post został zamknięty. - answer_deleted: Ta odpowiedź została usunięta. - answer_cancel_deleted: Ta odpowiedź została przywrócona. - change_user_role: Rola tego użytkownika została zmieniona. - user_inactive: Ten użytkownik jest już nieaktywny. - user_normal: Ten użytkownik jest już aktywny. - user_suspended: Ten użytkownik został zawieszony. - user_deleted: Ten użytkownik został usunięty. - badge_activated: Ta odznaka została aktywowana. - badge_inactivated: Ta odznaka została dezaktywowana. - users_deleted: Ci użytkownicy zostali usunięci. - posts_deleted: Te pytania zostały usunięte. - answers_deleted: Te odpowiedzi zostały usunięte. - copy: Skopiuj do schowka - copied: Skopiowano - external_content_warning: Zewnętrzne obrazy/media nie są wyświetlane. - diff --git a/data/i18n/pt_BR.yaml b/data/i18n/pt_BR.yaml deleted file mode 100644 index 45e00873c..000000000 --- a/data/i18n/pt_BR.yaml +++ /dev/null @@ -1,1381 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: Sucesso. - unknown: - other: Erro desconhecido. - request_format_error: - other: O formato da Requisição não é válido. - unauthorized_error: - other: Não autorizado. - database_error: - other: Erro no servidor de dados. - role: - name: - user: - other: Usuário - admin: - other: Administrador - moderator: - other: Moderador - description: - user: - other: Padrão sem acesso especial. - admin: - other: Possui controle total para acessar o site. - moderator: - other: Não possui controle a todas as postagens exceto configurações de administrador. - email: - other: E-mail - password: - other: Senha - email_or_password_wrong_error: - other: E-mail e Senha inválidos. - error: - admin: - email_or_password_wrong: - other: E-mail e Senha inválidos. - answer: - not_found: - other: Resposta não encontrada. - cannot_deleted: - other: Permissão insuficiente para deletar. - cannot_update: - other: Permissão insuficiente para atualizar. - comment: - edit_without_permission: - other: Não é permitido atualizar comentários. - not_found: - other: Comentário não encontrado. - cannot_edit_after_deadline: - other: O tempo para comentários expirou. - email: - duplicate: - other: E-mail já existe na base de dados. - need_to_be_verified: - other: E-mail precisa ser verificado. - verify_url_expired: - other: A URL de validação do e-mail expirou, por favor, re-envie o e-mail. - lang: - not_found: - other: Arquivo de idioma não encontrado. - object: - captcha_verification_failed: - other: Captcha inválido. - disallow_follow: - other: Você não possui permissão para seguir. - disallow_vote: - other: Você não possui permissão para votar. - disallow_vote_your_self: - other: Você não pode votar na sua própria postagem. - not_found: - other: Objeto não encontrado. - verification_failed: - other: Falha na verificação. - email_or_password_incorrect: - other: E-mail e Senha não conferem. - old_password_verification_failed: - other: Verficação de senhas antigas falhou. - new_password_same_as_previous_setting: - other: A nova senha é idêntica à senha anterior. - question: - not_found: - other: Pergunta não encontrada. - cannot_deleted: - other: Não possui permissão para deletar. - cannot_close: - other: Não possui permissão para fechar. - cannot_update: - other: Não possui permissão para atualizar.. - rank: - fail_to_meet_the_condition: - other: A classificação não atende à condição. - report: - handle_failed: - other: Falha no processamento do relatório. - not_found: - other: Relatório não encontrado. - tag: - not_found: - other: Marcador não encontada. - recommend_tag_not_found: - other: Marcador recomendado não existe. - recommend_tag_enter: - other: Por favor, insira ao menos um marcador obrigatório. - not_contain_synonym_tags: - other: Não pode contar marcadores de sinônimos. - cannot_update: - other: Não possui permissão para atualizar. - cannot_set_synonym_as_itself: - other: Você não pode definir o sinônimo do marcador atual como ela mesma. - smtp: - config_from_name_cannot_be_email: - other: O De Nome não pode ser um endereço de e-mail. - Tema: - not_found: - other: Tema não encontrado. - revision: - review_underway: - other: Não é possível editar no momento, há uma versão na fila de revisão. - no_permission: - other: Sem pemissão para revisar. - user: - email_or_password_wrong: - other: - other: E-mail e senha não correspondem. - not_found: - other: Usuário não encontrado. - suspended: - other: Usuário foi suspenso. - username_invalid: - other: Nome de usuário inválido. - username_duplicate: - other: Nome de usuário já está em uso. - set_avatar: - other: Falha ao configurar Avatar. - cannot_update_your_role: - other: Você não pode modificar a sua função. - not_allowed_registration: - other: Atualmente o site não está aberto para cadastro - config: - read_config_failed: - other: A leitura da configuração falhou - database: - connection_failed: - other: Falha na conexão com o banco de dados - create_table_failed: - other: Falha na criação de tabela - install: - create_config_failed: - other: Não foi possível criar o arquivo config.yaml. - upload: - unsupported_file_format: - other: Formato de arquivo não suportado. - report: - spam: - name: - other: spam - desc: - other: Este post é um anúncio, ou vandalismo. Não é útil ou relevante para o tópico atual. - rude: - name: - other: rude ou abusivo - desc: - other: Uma pessoa razoável acharia este conteúdo impróprio para um discurso respeitoso. - duplicate: - name: - other: uma duplicidade - desc: - other: Esta pergunta já foi feita antes e já tem uma resposta. - not_answer: - name: - other: não é uma resposta - desc: - other: Isso foi postado como uma resposta, mas não tenta responder à pergunta. Possivelmente deve ser uma edição, um comentário, outra pergunta ou excluído completamente. - not_need: - name: - other: não é mais necessário - desc: - other: Este comentário está desatualizado, coloquial ou não é relevante para esta postagem. - other: - name: - other: algo mais - desc: - other: Esta postagem requer atenção da equipe por outro motivo não listado acima. - question: - close: - duplicate: - name: - other: spam - desc: - other: Esta pergunta já foi feita antes e já tem uma resposta. - guideline: - name: - other: um motivo específico da comunidade - desc: - other: Esta pergunta não atende a uma diretriz da comunidade. - multiple: - name: - other: precisa de detalhes ou clareza - desc: - other: Esta pergunta atualmente inclui várias perguntas em uma. Deve se concentrar em apenas um problema. - other: - name: - other: algo mais - desc: - other: Este post requer outro motivo não listado acima. - operation_type: - asked: - other: perguntado - answered: - other: respondido - modified: - other: modificado - notification: - action: - update_question: - other: pergunta atualizada - answer_the_question: - other: pergunta respondida - update_answer: - other: resposta atualizada - accept_answer: - other: resposta aceita - comment_question: - other: pergunta comentada - comment_answer: - other: resposta comentada - reply_to_you: - other: respondeu a você - mention_you: - other: mencionou você - your_question_is_closed: - other: A sua pergunta foi fechada - your_question_was_deleted: - other: A sua pergunta foi deletada - your_answer_was_deleted: - other: A sua resposta foi deletada - your_comment_was_deleted: - other: O seu comentário foi deletado -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Como formatar - desc: >- -
        • para mais links

          <https://url.com>

          [Título](https://url.com)
        • colocar retornos entre parágrafos

        • _italic_ ou **bold**

        • identar código por 4 espaços

        • cotação colocando > no início da linha

        • aspas invertidas `tipo_isso`

        • criar cercas de código com aspas invertidas `

          ```
          código aqui
          ```
        - pagination: - prev: Anterior - next: Próximo - page_title: - question: Pergunta - questions: Perguntas - tag: Marcador - tags: Marcadores - tag_wiki: marcador wiki - edit_tag: Editar Marcador - ask_a_question: Adicionar Pergunta - edit_question: Editar Pergunta - edit_answer: Editar Resposta - search: Busca - posts_containing: Postagens contendo - settings: Configurações - notifications: Notificações - login: Entrar - sign_up: Criar conta - account_recovery: Recuperação de conta - account_activation: Ativação de conta - confirm_email: Confirmação de e-mail - account_suspended: Conta suspensa - admin: Administrador - change_email: Modificar e-mail - install: Instalação do Resposta - upgrade: Atualização do Resposta - maintenance: Manutenção do Website - users: Usuários - notifications: - title: Notificações - inbox: Caixa de entrada - achievement: Conquistas - all_read: Marcar todas como lidas - show_more: Mostrar mais - suspended: - title: A sua conta foi suspensa - until_time: "A sua conta foi suspensa até {{ time }}." - forever: Este usuário foi suspenso por tempo indeterminado. - end: Você não atende a uma diretriz da comunidade. - editor: - blockquote: - text: Bloco de citação - bold: - text: Forte - chart: - text: Gráfico - flow_chart: Fluxograma - sequence_diagram: Diagrama de sequência - class_diagram: Diagrama de classe - state_diagram: Diagrama de estado - entity_relationship_diagram: Diagrama de relacionamento de entidade - user_defined_diagram: Diagrama definido pelo usuário - gantt_chart: Diagrama de Gantt - pie_chart: Gráfico de pizza - code: - text: Código de exemplo - add_code: Adicione código de exemplo - form: - fields: - code: - label: Código - msg: - empty: Código não pode ser vazio. - language: - label: Idioma (opcional) - placeholder: Detecção automática - btn_cancel: Cancelar - btn_confirm: Adicionar - formula: - text: Fórmula - options: - inline: Fórmula em linha - block: Fórmula em bloco - Cabeçalho: - text: Cabeçalho - options: - h1: Cabeçalho 1 - h2: Cabeçalho 2 - h3: Cabeçalho 3 - h4: Cabeçalho 4 - h5: Cabeçalho 5 - h6: Cabeçalho 6 - help: - text: Ajuda - hr: - text: Régua horizontal - image: - text: Imagem - add_image: Adicionar imagem - tab_image: Enviar imagem - form_image: - fields: - file: - label: Arquivo de imagem - btn: Selecione imagem - msg: - empty: Arquivo não pode ser vazio. - only_image: Somente um arquivo de imagem é permitido. - max_size: O tamanho do arquivo não pode exceder 4 MB. - desc: - label: Descrição (opcional) - tab_url: URL da imagem - form_url: - fields: - url: - label: URL da imagem - msg: - empty: URL da imagem não pode ser vazia. - name: - label: Descrição (opcional) - btn_cancel: Cancelar - btn_confirm: Adicionar - uploading: Enviando - indent: - text: Identação - outdent: - text: Não identado - italic: - text: Ênfase - link: - text: Superlink (Hyperlink) - add_link: Adicionar superlink (hyperlink) - form: - fields: - url: - label: URL - msg: - empty: URL não pode ser vazia. - name: - label: Descrição (opcional) - btn_cancel: Cancelar - btn_confirm: Adicionar - ordered_list: - text: Lista numerada - unordered_list: - text: Lista com marcadores - table: - text: Tabela - Cabeçalho: Cabeçalho - cell: Célula - close_modal: - title: Estou fechando este post como... - btn_cancel: Cancelar - btn_submit: Enviar - remark: - empty: Não pode ser vazio. - msg: - empty: Por favor selecione um motivo. - report_modal: - flag_title: I am flagging to report this post as... - close_title: Estou fechando este post como... - review_question_title: Revisar pergunta - review_answer_title: Revisar resposta - review_comment_title: Revisar comentário - btn_cancel: Cancelar - btn_submit: Enviar - remark: - empty: Não pode ser vazio. - msg: - empty: Por favor selecione um motivo. - tag_modal: - title: Criar novo marcador - form: - fields: - display_name: - label: Nome de exibição - msg: - empty: Nome de exibição não pode ser vazio. - range: Nome de exibição tem que ter até 35 caracteres. - slug_name: - label: Slug de URL - desc: 'Deve usar o conjunto de caracteres "a-z", "0-9", "+ # - ."' - msg: - empty: URL slug não pode ser vazio. - range: URL slug até 35 caracteres. - character: URL slug contém conjunto de caracteres não permitido. - desc: - label: Descrição (opcional) - btn_cancel: Cancelar - btn_submit: Enviar - tag_info: - created_at: Criado - edited_at: Editado - history: Histórico - synonyms: - title: Sinônimos - text: Os marcadores a seguir serão re-mapeados para - empty: Sinônimos não encotrados. - btn_add: Adicionar um sinônimo - btn_edit: Editar - btn_save: Salvar - synonyms_text: Os marcadores a seguir serão re-mapeados para - delete: - title: Deletar este marcador - content: >- -

        Não permitimos a exclusão de marcadores com postagens.

        Por favor, remova este marcador das postagens primeiro.

        - content2: Você tem certeza que deseja deletar? - close: Fechar - edit_tag: - title: Editar marcador - default_reason: Editar marcador - form: - fields: - revision: - label: Revisão - display_name: - label: Nome de exibição - slug_name: - label: Slug de URL - info: 'Deve usar o conjunto de caracteres "a-z", "0-9", "+ # - ."' - desc: - label: Descrição - edit_summary: - label: Resumo da edição - placeholder: >- - Explique resumidamente suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada) - btn_save_edits: Salvar edições - btn_cancel: Cancelar - dates: - long_date: D MMM - long_date_with_year: "D MMM, YYYY" - long_date_with_time: "D MMM, YYYY [at] HH:mm" - now: agora - x_seconds_ago: "{{count}}s atrás" - x_minutes_ago: "{{count}}m atrás" - x_hours_ago: "{{count}}h atrás" - hour: hora - day: dia - comment: - btn_add_comment: Adicionar comentário - reply_to: Responder a - btn_reply: Responder - btn_edit: Editar - btn_delete: Deletar - btn_flag: Marcador - btn_save_edits: Salvar edições - btn_cancel: Cancelar - show_more: Mostrar mais comentários - tip_question: >- - Use os comentários para pedir mais informações ou sugerir melhorias. Evite responder perguntas nos comentários. - tip_answer: >- - Use comentários para responder a outros usuários ou notificá-los sobre alterações. Se você estiver adicionando novas informações, edite sua postagem em vez de comentar. - edit_answer: - title: Editar Resposta - default_reason: Editar Resposta - form: - fields: - revision: - label: Revisão - answer: - label: Resposta - feedback: - caracteres: conteúdo deve ser pelo menos 6 caracteres em comprimento. - edit_summary: - label: Resumo da edição - placeholder: >- - Explique resumidamente suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada) - btn_save_edits: Salvar edições - btn_cancel: Cancelar - tags: - title: Marcadores - sort_buttons: - popular: Popular - name: Nome - newest: mais recente - button_follow: Seguir - button_following: Seguindo - tag_label: perguntas - search_placeholder: Filtrar por nome de marcador - no_desc: O marcador não possui descrição. - more: Mais - ask: - title: Adicionar Pergunta - edit_title: Editar Pergunta - default_reason: Editar pergunta - similar_questions: Perguntas similares - form: - fields: - revision: - label: Revisão - title: - label: Título - placeholder: Seja específico e tenha em mente que está fazendo uma pergunta a outra pessoa - msg: - empty: Título não pode ser vazio. - range: Título até 150 caracteres - body: - label: Corpo - msg: - empty: Corpo da mensagem não pode ser vazio. - tags: - label: Marcadores - msg: - empty: Marcadores não podes ser vazios. - answer: - label: Resposta - msg: - empty: Resposta não pode ser vazia. - edit_summary: - label: Resumo da edição - placeholder: >- - Explique resumidamente suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada) - btn_post_question: Publicar a sua pergunta - btn_save_edits: Salvar edições - answer_question: Responda a sua própria pergunta - post_question&answer: Publicar a sua pergunta e resposta - tag_selector: - add_btn: Adicionar marcador - create_btn: Criar novo marcador - search_tag: Procurar marcador - hint: "Descreva do quê se trata a sua pergunta, ao menos um marcador é requirido." - no_result: Nenhum marcador correspondente - tag_required_text: Marcador obrigatório (ao menos um) - header: - nav: - question: Perguntas - tag: Marcadores - user: Usuários - profile: Perfil - setting: Configurações - logout: Sair - admin: Administrador - review: Revisar - search: - placeholder: Procurar - footer: - build_on: >- - Desenvolvido com base no <1> Answer — o software de código aberto que alimenta comunidades de perguntas e respostas.
        Feito com amor © {{cc}}. - upload_img: - name: Mudar - loading: carregando... - pic_auth_code: - title: Captcha - placeholder: Escreva o texto acima - msg: - empty: Captcha não pode ser vazio. - inactive: - first: >- - Você está quase pronto! Enviamos um e-mail de ativação para {{mail}}. Por favor, siga as instruções no e-mail para ativar uma conta sua. - info: "Se não chegar, verifique sua pasta de spam." - another: >- - Enviamos outro e-mail de ativação para você em {{mail}}. Pode levar alguns minutos para chegar; certifique-se de verificar sua pasta de spam. - btn_name: Reenviar e-mail de ativação - change_btn_name: Mudar email - msg: - empty: Não pode ser vazio. - login: - page_title: Bem vindo ao {{site_name}} - login_to_continue: Entre para continuar - info_sign: Não possui uma conta? <1>Cadastrar-se - info_login: Já possui uma conta? <1>Entre - agreements: Ao se registrar, você concorda com as <1>políticas de privacidades e os <3>termos de serviços. - forgot_pass: Esqueceu a sua senha? - name: - label: Nome - msg: - empty: Nome não pode ser vazio. - range: Nome até 30 caracteres. - email: - label: E-mail - msg: - empty: E-mail não pode ser vazio. - password: - label: Senha - msg: - empty: Senha não pode ser vazia. - different: As senhas inseridas em ambos os campos são inconsistentes - account_forgot: - page_title: Esqueceu a sua senha - btn_name: Enviar e-mail de recuperação de senha - send_success: >- - Se uma conta corresponder {{mail}}, você deve receber um e-mail com instruções sobre como redefinir sua senha em breve. - email: - label: E-mail - msg: - empty: E-mail não pode ser vazio. - change_email: - page_title: Bem vindo ao {{site_name}} - btn_cancel: Cancelar - btn_update: Atualiza email address - send_success: >- - Se uma conta corresponder {{mail}}, você deve receber um e-mail com instruções sobre como redefinir sua senha em breve. - email: - label: Novo E-mail - msg: - empty: E-mail não pode ser vazio. - password_reset: - page_title: Redefinir senha - btn_name: Redefinir minha senha - reset_success: >- - Você alterou com sucesso uma senha sua; você será redirecionado para a página de login. - link_invalid: >- - Desculpe, este link de redefinição de senha não é mais válido. Talvez uma senha sua já tenha sido redefinida? - to_login: Continuar para a tela de login - password: - label: Senha - msg: - empty: Senha não pode ser vazio. - length: O comprimento deve estar entre 8 e 32 - different: As senhas inseridas em ambos os campos são inconsistentes - password_confirm: - label: Confirmar Nova senha - settings: - page_title: Configurações - nav: - profile: Perfil - notification: Notificações - account: Conta - interface: Interface - profile: - Cabeçalho: Perfil - btn_name: Salvar - display_name: - label: Nome de exibição - msg: Nome de exibição não pode ser vazio. - msg_range: Nome de exibição tem que ter até 30 caracteres. - username: - label: Nome de usuário - caption: As pessoas poderão mensionar você com "@usuário". - msg: Nome de usuário não pode ser vazio. - msg_range: Nome de usuário até 30 caracteres. - character: 'Deve usar o conjunto de caracteres "a-z", "0-9", "- . _"' - avatar: - label: Perfil Imagem - gravatar: Gravatar - gravatar_text: Você pode mudar a imagem em <1>gravatar.com - custom: Customizado - btn_refresh: Atualizar - custom_text: Você pode enviar a sua image. - default: System - msg: Por favor envie um avatar - bio: - label: Sobre mim (opcional) - website: - label: Website (opcional) - placeholder: "https://exemplo.com.br" - msg: Formato incorreto de endereço de Website - location: - label: Localização (opcional) - placeholder: "Cidade, País" - notification: - Cabeçalho: Notificações - email: - label: E-mail Notificações - radio: "Responda as suas perguntas, comentários, e mais" - account: - Cabeçalho: Conta - change_email_btn: Mudar e-mail - change_pass_btn: Mudar senha - change_email_info: >- - Enviamos um e-mail para esse endereço. Siga as instruções de confirmação. - email: - label: E-mail - msg: E-mail não pode ser vazio. - password_title: Senha - current_pass: - label: Senha atual - msg: - empty: A Senha não pode ser vazia. - length: O comprimento deve estar entre 8 and 32. - different: As duas senhas inseridas não correspondem. - new_pass: - label: Nova Senha - pass_confirm: - label: Confirmar nova Senha - interface: - Cabeçalho: Interface - lang: - label: Idioma da Interface - text: Idioma da interface do usuário. A interface mudará quando você atualizar a página. - toast: - update: atualização realizada com sucesso - update_password: Senha alterada com sucesso. - flag_success: Obrigado por marcar. - forbidden_operate_self: Proibido para operar por você mesmo - review: A sua resposta irá aparecer após a revisão. - related_question: - title: Perguntas relacionadas - btn: Adicionar pegunta - answers: respostas - question_detail: - Perguntado: Perguntado - asked: perguntado - update: Modificado - edit: modificado - Views: Visualizado - Seguir: Seguir - Seguindo: Seguindo - answered: respondido - closed_in: Fechado em - show_exist: Mostrar pergunta existente. - answers: - title: Respostas - score: Pontuação - newest: Mais recente - btn_accept: Aceito - btn_accepted: Aceito - write_answer: - title: A sua Resposta - btn_name: Publicação a sua resposta - add_another_answer: Adicionar outra resposta - confirm_title: Continuar a responder - continue: Continuar - confirm_info: >- -

        Tem certeza de que deseja adicionar outra resposta?

        Você pode usar o link de edição para refinar e melhorar uma resposta existente.

        - empty: Resposta não pode ser vazio. - caracteres: conteúdo deve ser pelo menos 6 caracteres em comprimento. - reopen: - title: Reabrir esta postagem - content: Tem certeza que deseja reabrir? - success: Esta postagem foi reaberta - delete: - title: Excluir esta postagem - question: >- - Nós não recomendamos excluir perguntas com respostas porque isso priva os futuros leitores desse conhecimento.

        A exclusão repetida de perguntas respondidas pode resultar no bloqueio de perguntas de sua conta. Você tem certeza que deseja excluir? - answer_accepted: >- -

        Não recomendamos excluir resposta aceita porque isso priva os futuros leitores desse conhecimento.

        A exclusão repetida de respostas aceitas pode resultar no bloqueio de respostas de uma conta sua. Você tem certeza que deseja excluir? - other: Você tem certeza que deseja deletar? - tip_question_deleted: Esta postagem foi deletada - tip_answer_deleted: Esta resposta foi deletada - btns: - confirm: Confirmar - cancel: Cancelar - save: Salvar - delete: Deletar - login: Entrar - signup: Cadastrar-se - logout: Sair - verify: Verificar - add_question: Adicionar pergunta - approve: Aprovar - reject: Rejetar - skip: Pular - search: - title: Procurar Resultados - keywords: Palavras-chave - options: Opções - follow: Seguir - following: Seguindo - counts: "{{count}} Resultados" - more: Mais - sort_btns: - relevance: Relevância - newest: Mais recente - active: Ativar - score: Pontuação - more: Mais - tips: - title: Dicas de Pesquisa Avançada - tag: "<1>[tag] pesquisar dentro de um marcador" - user: "<1>user:username buscar por autor" - answer: "<1>answers:0 perguntas não respondidas" - score: "<1>score:3 postagens com mais de 3+ placares" - question: "<1>is:question buscar perguntas" - is_answer: "<1>is:answer buscar respostas" - empty: Não conseguimos encontrar nada.
        Tente palavras-chave diferentes ou menos específicas. - share: - name: Compartilhar - copy: Copiar link - via: Compartilhar postagem via... - copied: Copiado - facebook: Compartilhar no Facebook - twitter: Compartilhar no X - cannot_vote_for_self: Você não pode votar na sua própria postagem - modal_confirm: - title: Erro... - account_result: - page_title: Bem vindo ao {{site_name}} - success: A sua nova conta está confirmada; você será redirecionado para a página inicial. - link: Continuar para a página inicial. - invalid: >- - Desculpe, este link de confirmação não é mais válido. Talvez a sua já está ativa. - confirm_new_email: Seu e-mail foi atualizado. - confirm_new_email_invalid: >- - Desculpe, este link de confirmação não é mais válido. Talvez o seu e-mail já tenha sido alterado. - unsubscribe: - page_title: Cancelar subscrição - success_title: Cancelamento de inscrição bem-sucedido - success_desc: Você foi removido com sucesso desta lista de assinantes e não receberá mais nenhum e-mail nosso. - link: Mudar configurações - question: - following_tags: Seguindo Marcadores - edit: Editar - save: Salvar - follow_tag_tip: Siga as tags para selecionar sua lista de perguntas. - hot_questions: Perguntas quentes - all_questions: Todas Perguntas - x_questions: "{{ count }} perguntas" - x_answers: "{{ count }} respostas" - questions: Perguntas - answers: Respostas - newest: Mais recente - active: Ativo - hot: Hot - score: Pontuação - unanswered: Não Respondido - modified: modificado - answered: respondido - asked: perguntado - closed: fechado - follow_a_tag: Seguir o marcador - more: Mais - personal: - overview: Visão geral - answers: Respostas - answer: resposta - questions: Perguntas - question: pergunta - bookmarks: Favoritas - reputation: Reputação - comments: Comentários - Votos: Votos - newest: Mais recente - score: Pontuação - edit_profile: Editar Perfil - visited_x_days: "Visitado {{ count }} dias" - viewed: Visualizado - joined: Ingressou - last_login: Visto - about_me: Sobre mim - about_me_empty: "// Olá, Mundo !" - top_answers: Melhores Respostas - top_questions: Melhores Perguntas - stats: Estatísticas - list_empty: Postagens não encontradas.
        Talvez você queira selecionar uma guia diferente? - accepted: Aceito - answered: respondido - asked: perguntado - upvote: voto positivo - downvote: voto negativo - mod_short: Moderador - mod_long: Moderadores - x_reputation: reputação - x_Votos: votos recebidos - x_answers: respostas - x_questions: perguntas - install: - title: Instalação - next: Próximo - done: Completo - config_yaml_error: Não é possível criar o arquivo config.yaml. - lang: - label: Por favor Escolha um Idioma - db_type: - label: Mecanismo de banco de dados - db_username: - label: Nome de usuário - placeholder: root - msg: Nome de usuário não pode ser vazio. - db_password: - label: Senha - placeholder: root - msg: Senha não pode ser vazio. - db_host: - label: Host do banco de dados - placeholder: "db:3306" - msg: Host de banco de dados não pode ficar vazio. - db_name: - label: Nome do banco de dados - placeholder: answer - msg: O nome do banco de dados não pode ficar vazio. - db_file: - label: Arquivo de banco de dados - placeholder: /data/answer.db - msg: O arquivo de banco de dados não pode ficar vazio. - config_yaml: - title: Criar config.yaml - label: O arquivo config.yaml foi criado. - desc: >- - Você pode criar o arquivo <1>config.yaml manualmente no diretório <1>/var/www/xxx/ e colar o seguinte texto nele. - info: Depois de fazer isso, clique no botão "Avançar". - site_information: Informações do site - admin_account: Administrador Conta - site_name: - label: Site Nome - msg: Site Nome não pode ser vazio. - site_url: - label: Site URL - text: O endereço do seu site. - msg: - empty: Site URL não pode ser vazio. - incorrect: Formato incorreto da URL do site. - contact_email: - label: E-mail para contato - text: Endereço de e-mail do contato principal responsável por este site. - msg: - empty: E-mail para contato não pode ser vazio. - incorrect: E-mail para contato em formato incorreto. - admin_name: - label: Nome - msg: Nome não pode ser vazio. - admin_password: - label: Senha - text: >- - Você precisará dessa senha para efetuar login. Por favor, guarde-a em um local seguro. - msg: Senha não pode ser vazia. - admin_email: - label: Email - text: Você precisará deste e-mail para fazer login. - msg: - empty: Email não pode ser vazio. - incorrect: Formato de e-mail incorreto. - ready_title: Sua resposta está pronta! - ready_desc: >- - Se você quiser alterar mais configurações, visite a <1>seção de administração; encontre-a no menu do site. - good_luck: "Divirta-se e boa sorte!" - warn_title: Aviso - warn_desc: >- - O arquivo <1>config.yaml já existe. Se precisar redefinir algum item de configuração neste arquivo, exclua-o primeiro. - install_now: Você pode tentar <1>instalar agora. - installed: Já instalado - installed_desc: >- - Parece que você já instalou. Para reinstalar, limpe primeiro as tabelas antigas do seu banco de dados. - db_failed: Falha na conexão do banco de dados - db_failed_desc: >- - Isso significa que as informações do banco de dados em um arquivo <1>config.yaml do SUA estão incorretas ou que o contato com o servidor do banco de dados não pôde ser estabelecido. Isso pode significar que o servidor de banco de dados de um host SUA está inativo. - counts: - views: visualizações - Votos: votos - answers: respostas - accepted: Aceito - page_404: - desc: "Infelizmente, esta postagem não existe mais." - back_home: Voltar para a página inicial - page_50X: - desc: O servidor encontrou um erro e não pôde concluir sua solicitação. - back_home: Voltar para a página inicial - page_maintenance: - desc: "Estamos em manutenção, voltaremos em breve." - nav_menus: - dashboard: Painel - contents: Conteúdos - questions: Perguntas - answers: Respostas - users: Usuários - flags: Marcadores - settings: Configurações - general: Geral - interface: Interface - smtp: SMTP - branding: Marca - legal: Legal - write: Escrever - tos: Termos de Serviços - privacy: Privacidade - seo: SEO - customize: Personalização - Temas: Temas - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Administrador - dashboard: - title: Painel - welcome: Bem vindo ao Administrador! - site_statistics: Estatísticas do Site - questions: "Perguntas:" - answers: "Respostas:" - comments: "Comentários:" - Votos: "Votos:" - active_users: "Usuários ativos:" - flags: "Marcadores:" - site_health_status: Estatísticas da saúde do site - version: "Versão:" - https: "HTTPS:" - uploading_files: "Enviando arquivos:" - smtp: "SMTP:" - timezone: "Fuso horário:" - system_info: Informações do Sistema - storage_used: "Armazenamento usado:" - uptime: "Tempo de atividade:" - answer_links: Links das Respostas - documents: Documentos - feedback: Opinião - support: Suporte - review: Revisar - config: Configurações - update_to: Atualizar ao - latest: Ultimo - check_failed: Falha na verificação - "yes": "Sim" - "no": "Não" - not_allowed: Não permitido - allowed: Permitido - enabled: Ativo - disabled: Disponível - flags: - title: Marcadores - pending: Pendente - completed: Completo - flagged: Marcado - created: Criado - action: Ação - review: Revisar - change_modal: - title: Mudar user status to... - btn_cancel: Cancelar - btn_submit: Enviar - normal_name: normal - normal_desc: Um usuário normal pode fazer e responder perguntas. - suspended_name: suspenso - suspended_desc: Um usuário suspenso não pode fazer login. - deleted_name: removido - deleted_desc: "Deletar perfil, associações de autenticação." - inactive_name: inativo - inactive_desc: Um usuário inativo deve revalidar seu e-mail. - confirm_title: Remover este usuário - confirm_content: Tem certeza de que deseja excluir este usuário? Isso é permanente! - confirm_btn: Deletar - msg: - empty: Por favor selecione um motivo. - status_modal: - title: "Mudar {{ type }} status para..." - normal_name: normal - normal_desc: Um post normal disponível para todos. - closed_name: fechado - closed_desc: "Uma pergunta fechada não pode responder, mas ainda pode editar, votar e comentar." - deleted_name: removido - deleted_desc: Toda reputação ganha e perdida será restaurada. - btn_cancel: Cancelar - btn_submit: Enviar - btn_next: Próximo - user_role_modal: - title: Altere a função do usuário para... - btn_cancel: Cancelar - btn_submit: Enviar - users: - title: Usuários - name: Nome - email: Email - reputation: Reputação - created_at: Hora de criação - delete_at: Hora da remoção - suspend_at: Hora da suspensão - status: Status - role: Função - action: Ação - change: Mudar - all: Todos - staff: Funcionários - inactive: Inativo - suspended: Suspenso - deleted: Removido - normal: Normal - Moderador: Moderador - Administrador: Administrador - Usuário: Usuário - filter: - placeholder: "Filtrar por nome, user:id" - set_new_password: Configurar nova senha - change_status: Mudar status - change_role: Mudar função - show_logs: Mostrar registros - add_user: Adicionar usuário - new_password_modal: - title: Configurar nova senha - form: - fields: - password: - label: Senha - text: O usuário será desconectado e precisará fazer login novamente. - msg: Senha de ver entre 8-32 caracteres em comprimento. - btn_cancel: Cancelar - btn_submit: Enviar - user_modal: - title: Adicionar novo usuário - form: - fields: - display_name: - label: Nome de exibição - msg: Nome de exibição deve ser 2-30 caracteres em comprimento. - email: - label: Email - msg: Email não é válido. - password: - label: Senha - msg: Senha deve ser 8-32 caracteres em comprimento. - btn_cancel: Cancelar - btn_submit: Enviar - questions: - page_title: Perguntas - normal: Normal - closed: Fechado - deleted: Removido - post: Publicação - Votos: Votos - answers: Respostas - created: Criado - status: Status - action: Ação - change: Mudar - filter: - placeholder: "Filtrar por título, question:id" - answers: - page_title: Respostas - normal: Normal - deleted: Removido - post: Publicação - Votos: Votos - created: Criado - status: Status - action: Ação - change: Mudar - filter: - placeholder: "Filtrar por título, answer:id" - general: - page_title: General - name: - label: Site Nome - msg: Site name não pode ser vazio. - text: "O nome deste site, conforme usado na tag de título." - site_url: - label: URL do Site - msg: Site url não pode ser vazio. - validate: Por favor digite uma URL válida. - text: O endereço do seu site. - short_desc: - label: Breve Descrição do site (opcional) - msg: Breve Descrição do site não pode ser vazio. - text: "Breve descrição, conforme usado na tag de título na página inicial." - desc: - label: Site Descrição (opcional) - msg: Descrição do site não pode ser vazio. - text: "Descreva este site em uma única sentença, conforme usado na meta tag de descrição." - contact_email: - label: E-mail para contato - msg: E-mail par contato não pode ser vazio. - validate: E-mail par contato não é válido. - text: Endereço de e-mail do principal contato responsável por este site. - interface: - page_title: Interface - logo: - label: Logo (opcional) - msg: Site logo não pode ser vazio. - text: Você pode enviar a sua image ou <1>reiniciar ao texto do título do site. - Tema: - label: Tema - msg: Tema não pode ser vazio. - text: Selecione um tema existente. - language: - label: Idioma da interface - msg: Idioma da Interface não pode ser vazio. - text: Idioma da interface do Usuário. Ele mudará quando você atualizar a página. - time_zone: - label: Fuso horário - msg: Fuso horário não pode ser vazio. - text: Escolha a cidade no mesmo fuso horário que você. - smtp: - page_title: SMTP - from_email: - label: E-mail de origem - msg: E-mail de origem não pode ser vazio. - text: O endereço de e-mail de onde os e-mails são enviados. - from_name: - label: Nome de origem - msg: Nome de origem não pode ser vazio. - text: O nome de onde os e-mails são enviados. - smtp_host: - label: SMTP Host - msg: SMTP host não pode ser vazio. - text: O seu servidor de e-mails. - encryption: - label: Criptografia - msg: Criptografia não pode ser vazio. - text: Para a maioria dos servidores SSL é a opção recomendada. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: A porta para seu servidor de e-mail. - smtp_username: - label: SMTP Nome de usuário - msg: SMTP username não pode ser vazio. - smtp_password: - label: SMTP Senha - msg: SMTP password não pode ser vazio. - test_email_recipient: - label: Destinatários de e-mail de teste - text: Forneça o endereço de e-mail que receberá os envios de testes. - msg: Os destinatários do e-mail de teste são inválidos - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication não pode ser vazio. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (opcional) - msg: Logo não pode ser vazio. - text: A imagem do logotipo no canto superior esquerdo do seu site. Use uma imagem retangular larga com altura de 56 e proporção maior que 3:1. Se deixada em branco, o texto do título do site será exibido. - mobile_logo: - label: Mobile Logo (opcional) - text: O logotipo usado na versão mobile do seu site. Use uma imagem retangular larga com altura de 56. Se deixado em branco, a imagem da configuração "logotipo" será usada. - square_icon: - label: Square Icon (opcional) - msg: Square icon não pode ser vazio. - text: Imagem usada como base para ícones de metadados. Idealmente, deve ser maior que 512x512. - favicon: - label: Favicon (opcional) - text: Um favicon para o seu site. Para funcionar corretamente em uma CDN, ele deve ser um png. Será redimensionado para 32x32. Se deixado em branco, o "ícone quadrado" será usado. - legal: - page_title: Legal - terms_of_service: - label: Termos de Serviço - text: "Você pode adicionar conteúdo dos termos de serviço aqui. Se você já possui um documento hospedado em outro lugar, informe o URL completo aqui." - privacy_policy: - label: Política de Privacidade - text: "Você pode adicionar o conteúdo da política de privacidade aqui. Se você já possui um documento hospedado em outro lugar, informe o URL completo aqui." - write: - page_title: Escrever - recommend_tags: - label: Recomendar Marcadores - text: "Por favor, insira o slug da tag acima, uma tag por linha." - required_tag: - title: Tag necessária - label: Definir tag recomendada como necessária - text: "Cada nova pergunta deve ter pelo menos uma tag de recomendação." - reserved_tags: - label: Marcadores Reservados - text: "Tags reservadas só podem ser adicionadas a uma postagem pelo moderador." - seo: - page_title: SEO - permalink: - label: Permalink - text: Estruturas de URL personalizadas podem melhorar a usabilidade e a compatibilidade futura de seus links. - robots: - label: robots.txt - text: Isso substituirá permanentemente todas as configurações relacionadas do site. - Temas: - page_title: Temas - Temas: - label: Temas - text: Selecione um tema existente. - navbar_style: - label: Estilo da barra de navegação - text: Selecione um tema existente. - primary_color: - label: Cor primária - text: Modifique as cores usadas por seus Temas - css_and_html: - page_title: CSS e HTML - custom_css: - label: Custom CSS - text: Isto será inserido como - head: - label: Head - text: Isto será inserido antes de - header: - label: Header - text: Isto será inserido após - footer: - label: Footer - text: Isso será inserido antes de . - login: - page_title: Login - membership: - title: Associação - label: Permitir novos registros - text: Desative para impedir que alguém crie uma nova conta. - private: - title: Privado - label: Login requirido - text: Somente usuários logados podem acessar esta comunidade. - form: - empty: não pode ser vazio - invalid: é inválido - btn_submit: Salvar - not_found_props: "Propriedade necessária {{ key }} não encontrada." - page_review: - review: Revisar - proposed: proposta - question_edit: Editar Pergunta - answer_edit: Editar Resposta - tag_edit: Editar Tag - edit_summary: Editar resumo - edit_question: Editar pergunta - edit_answer: Editar resposta - edit_tag: Editar tag - empty: Não há mais tarefas de revisão. - timeline: - undeleted: não excluído - deleted: apagado - downvote: voto negativo - upvote: voto positivo - accept: aceitar - cancelled: cancelado - commented: comentado - rollback: rollback - edited: editado - answered: respondido - asked: perguntado - closed: fechado - reopened: reaberto - created: criado - title: "Histórico para" - tag_title: "Linha do tempo para" - show_Votos: "Mostrar votos" - n_or_a: N/A - title_for_question: "Linha do tempo para" - title_for_answer: "Linha do tempo para resposta a {{ title }} por {{ author }}" - title_for_tag: "Linha do tempo para tag" - datetime: Datetime - type: Tipo - by: Por - comment: Comentário - no_data: "Não conseguimos encontrar nada." - users: - title: Usuários - users_with_the_most_reputation: Usuários com as maiores pontuações de reputação - users_with_the_most_vote: Usuários que mais votaram - staffs: Nossa equipe comunitária - reputation: reputação - Votos: Votos diff --git a/data/i18n/pt_PT.yaml b/data/i18n/pt_PT.yaml deleted file mode 100644 index eba40d2f6..000000000 --- a/data/i18n/pt_PT.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Sucesso. - unknown: - other: Erro desconhecido. - request_format_error: - other: Formato de solicitação inválido. - unauthorized_error: - other: Não autorizado. - database_error: - other: Erro no servidor de dados. - forbidden_error: - other: Proibido. - duplicate_request_error: - other: Solicitação duplicada. - action: - report: - other: Bandeira - edit: - other: Editar - delete: - other: Excluir - close: - other: Fechar - reopen: - other: Reabrir - forbidden_error: - other: Proibido. - pin: - other: Fixar - hide: - other: Não listar - unpin: - other: Desafixar - show: - other: Lista - invite_someone_to_answer: - other: Editar - undelete: - other: Desfazer - merge: - other: Merge - role: - name: - user: - other: Usuário - admin: - other: Administrador - moderator: - other: Moderador - description: - user: - other: Padrão sem acesso especial. - admin: - other: Possui acesso total. - moderator: - other: Acesso a todas as postagens, exceto configurações administrativas. - privilege: - level_1: - description: - other: Nível 1 (Menos reputação necessária para a equipe privado, grupo) - level_2: - description: - other: Nível 2 (pouca reputação necessária para a comunidade de inicialização) - level_3: - description: - other: Nível 3 (Alta reputação necessária para a comunidade adulta) - level_custom: - description: - other: Nível customizado - rank_question_add_label: - other: Perguntar - rank_answer_add_label: - other: Escrever resposta - rank_comment_add_label: - other: Comentar - rank_report_add_label: - other: Bandeira - rank_comment_vote_up_label: - other: Aprovar um comentário - rank_link_url_limit_label: - other: Poste mais de 2 links por vez - rank_question_vote_up_label: - other: Avaliar perguntar - rank_answer_vote_up_label: - other: Votar na resposta - rank_question_vote_down_label: - other: Desaprovar pergunta - rank_answer_vote_down_label: - other: Desaprovar resposta - rank_invite_someone_to_answer_label: - other: Convide alguém para responder - rank_tag_add_label: - other: Criar marcador - rank_tag_edit_label: - other: Editar descrição de um marcador (revisão necessária) - rank_question_edit_label: - other: Editar pergunta do outro (revisão necessária) - rank_answer_edit_label: - other: Editar a resposta do outro (revisão necessária) - rank_question_edit_without_review_label: - other: Editar a pergunta do outro sem revisar - rank_answer_edit_without_review_label: - other: Editar a resposta do outro sem revisar - rank_question_audit_label: - other: Rever edições de perguntas - rank_answer_audit_label: - other: Revisar edições de respostas - rank_tag_audit_label: - other: Revisar edições de marcadores - rank_tag_edit_without_review_label: - other: Editar descrições de marcadores sem revisar - rank_tag_synonym_label: - other: Gerenciar sinônimos de marcação - email: - other: E-mail - e_mail: - other: Email - password: - other: Senha - pass: - other: Senha - old_pass: - other: Current password - original_text: - other: Esta publicação - email_or_password_wrong_error: - other: O e-mail e a palavra-passe não coincidem. - error: - common: - invalid_url: - other: URL inválida. - status_invalid: - other: Estado inválido. - password: - space_invalid: - other: A senha não pode conter espaços. - admin: - cannot_update_their_password: - other: Você não pode modificar sua senha. - cannot_edit_their_profile: - other: Você não pode alterar o seu perfil. - cannot_modify_self_status: - other: Você não pode modificar seu status - email_or_password_wrong: - other: O e-mail e a palavra-passe não coincidem. - answer: - not_found: - other: Resposta não encontrada. - cannot_deleted: - other: Sem permissão para remover. - cannot_update: - other: Sem permissão para atualizar. - question_closed_cannot_add: - other: Perguntas são fechadas e não podem ser adicionadas. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Não é possível alterar comentários. - not_found: - other: Comentário não encontrado. - cannot_edit_after_deadline: - other: O tempo do comentário foi muito longo para ser modificado. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: O e-mail já existe. - need_to_be_verified: - other: O e-mail deve ser verificado. - verify_url_expired: - other: O e-mail verificado URL expirou, por favor, reenvie o e-mail. - illegal_email_domain_error: - other: O email não é permitido a partir desse email de domínio. Por favor, use outro. - lang: - not_found: - other: Arquivo de idioma não encontrado. - object: - captcha_verification_failed: - other: O Captcha está incorreto. - disallow_follow: - other: Você não tem permissão para seguir. - disallow_vote: - other: Você não possui permissão para votar. - disallow_vote_your_self: - other: Você não pode votar na sua própria postagem. - not_found: - other: Objeto não encontrado. - verification_failed: - other: A verificação falhou. - email_or_password_incorrect: - other: O e-mail e a senha não correspondem. - old_password_verification_failed: - other: Falha na verificação de senha antiga - new_password_same_as_previous_setting: - other: A nova senha é a mesma que a anterior. - already_deleted: - other: Esta publicação foi removida. - meta: - object_not_found: - other: Objeto meta não encontrado - question: - already_deleted: - other: Essa publicação foi deletado. - under_review: - other: Sua postagem está aguardando revisão. Ela ficará visível depois que for aprovada. - not_found: - other: Pergunta não encontrada. - cannot_deleted: - other: Sem permissão para remover. - cannot_close: - other: Sem permissão para fechar. - cannot_update: - other: Sem permissão para atualizar. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: A classificação não atende à condição. - vote_fail_to_meet_the_condition: - other: Obrigado pela sugestão. Você precisa ser {{.Rank}} para poder votar. - no_enough_rank_to_operate: - other: Você precisa ser pelo menos {{.Rank}} para fazer isso. - report: - handle_failed: - other: Falha ao manusear relatório. - not_found: - other: Relatório não encontrado. - tag: - already_exist: - other: Marcação já existe. - not_found: - other: Marca não encontrada. - recommend_tag_not_found: - other: Marcador recomendado não existe. - recommend_tag_enter: - other: Por favor, insira pelo menos um marcador obrigatório. - not_contain_synonym_tags: - other: Não deve conter marcadores sinónimos. - cannot_update: - other: Sem permissão para atualizar. - is_used_cannot_delete: - other: Não é possível excluir um marcador em uso. - cannot_set_synonym_as_itself: - other: Você não pode definir o sinônimo do marcador atual como a si mesmo. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: O De Nome não pode ser um endereço de e-mail. - theme: - not_found: - other: Tema não encontrado. - revision: - review_underway: - other: Não é possível editar atualmente, há uma versão na fila de análise. - no_permission: - other: Sem pemissão para revisar. - user: - external_login_missing_user_id: - other: A plataforma de terceiros não fornece um ID único de usuário, então você não pode fazer login, entre em contato com o administrador do site. - external_login_unbinding_forbidden: - other: Por favor, defina uma senha de login para sua conta antes de remover esta conta. - email_or_password_wrong: - other: - other: O e-mail e a senha não conferem. - not_found: - other: Usuário não encontrado. - suspended: - other: O utilizador foi suspenso. - username_invalid: - other: Nome de usuário inválido. - username_duplicate: - other: O nome de usuário já em uso. - set_avatar: - other: Configuração de avatar falhou. - cannot_update_your_role: - other: Você não pode modificar a sua função. - not_allowed_registration: - other: Atualmente o site não está aberto para cadastro - not_allowed_login_via_password: - other: Atualmente o site não tem permissão para acessar utilizando senha. - access_denied: - other: Acesso negado - page_access_denied: - other: Você não tem permissão de acesso para esta página. - add_bulk_users_format_error: - other: "Erro no formato {{.Field}} próximo '{{.Content}}' na linha {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "O número de usuários que você adicionou de uma vez deve estar no intervalo de 1 -{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Falha ao ler configuração - database: - connection_failed: - other: Falha ao conectar-se ao banco de dados - create_table_failed: - other: Falha ao criar tabela - install: - create_config_failed: - other: Não foi possível criar o arquivo de configuração. - upload: - unsupported_file_format: - other: Formato de arquivo não suportado. - site_info: - config_not_found: - other: Configuração do site não encontrada. - badge: - object_not_found: - other: Objeto emblema não encontrado - reason: - spam: - name: - other: spam - desc: - other: Essa postagem é um anúncio, ou vandalismo. Não é útil ou relevante para o tópico atual. - rude_or_abusive: - name: - other: rude ou abusivo - desc: - other: "Uma pessoa razoável consideraria esse conteúdo inapropriado para um discurso respeitoso." - a_duplicate: - name: - other: uma duplicação - desc: - other: Esta pergunta já foi feita antes e já possui uma resposta. - placeholder: - other: Insira o link existente para a pergunta - not_a_answer: - name: - other: não é uma resposta - desc: - other: "Foi apresentada como uma resposta, mas não tenta responder à pergunta. Talvez deva ser uma edição, um comentário, outra pergunta ou totalmente apagada." - no_longer_needed: - name: - other: não é mais necessário - desc: - other: Este comentário está desatualizado, conversacional ou não é relevante para esta publicação. - something: - name: - other: outro assunto - desc: - other: Esta postagem requer atenção da equipe por outra razão não listada acima. - placeholder: - other: Conte-nos especificamente com o que você está preocupado - community_specific: - name: - other: um motivo específico para a comunidade - desc: - other: Esta questão não atende a uma orientação da comunidade. - not_clarity: - name: - other: precisa de detalhes ou clareza - desc: - other: Atualmente esta pergunta inclui várias perguntas em um só. Deve se concentrar apenas em um problema. - looks_ok: - name: - other: parece estar OK - desc: - other: Este post é bom como está e não de baixa qualidade. - needs_edit: - name: - other: necessitava de edição, assim o fiz - desc: - other: Melhore e corrija problemas com este post você mesmo. - needs_close: - name: - other: precisa ser fechado - desc: - other: Uma pergunta fechada não pode responder, mas ainda pode editar, votar e comentar. - needs_delete: - name: - other: precisa ser excluído - desc: - other: Esta postagem será excluída. - question: - close: - duplicate: - name: - other: spam - desc: - other: Esta pergunta já foi feita antes e já tem uma resposta. - guideline: - name: - other: um motivo específico da comunidade - desc: - other: Esta pergunta não atende a uma diretriz da comunidade. - multiple: - name: - other: precisa de detalhes ou clareza - desc: - other: Esta pergunta atualmente inclui várias perguntas em uma só. Por isso, deve focar em apenas um problema. - other: - name: - other: algo mais - desc: - other: Este post requer outro motivo não listado acima. - operation_type: - asked: - other: perguntado - answered: - other: respondido - modified: - other: modificado - deleted_title: - other: Questão excluída - questions_title: - other: Questões - tag: - tags_title: - other: Marcadores - no_description: - other: O marcador não possui descrição. - notification: - action: - update_question: - other: pergunta atualizada - answer_the_question: - other: pergunta respondida - update_answer: - other: resposta atualizada - accept_answer: - other: resposta aceita - comment_question: - other: pergunta comentada - comment_answer: - other: resposta comentada - reply_to_you: - other: respondeu a você - mention_you: - other: mencionou você - your_question_is_closed: - other: A sua pergunta foi fechada - your_question_was_deleted: - other: A sua pergunta foi deletada - your_answer_was_deleted: - other: A sua resposta foi deletada - your_comment_was_deleted: - other: O seu comentário foi deletado - up_voted_question: - other: votos positivos da pergunta - down_voted_question: - other: votos negativos da pergunta - up_voted_answer: - other: votos positivos da resposta - down_voted_answer: - other: votos negativos da resposta - up_voted_comment: - other: votos positivos do comentário - invited_you_to_answer: - other: lhe convidou para responder - earned_badge: - other: Ganhou o emblema "{{.BadgeName}}" emblema - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Confirme seu novo endereço de e-mail" - body: - other: "Confirme seu novo endereço de e-mail para {{.SiteName}} clicando no seguinte link:
        \n{{.ChangeEmailUrl}}

        \n\nSe você não solicitou esta alteração, por favor, ignore este email.

        \n\n--
        \nNota: Este é um e-mail automático do sistema, por favor, não responda a esta mensagem, pois a sua resposta não será vista." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} respondeu à sua pergunta" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nVisualizar no {{.SiteName}}

        \n\n--
        \nNota: Este é um e-mail de sistema automático, por favor, não responda a esta mensagem, pois a sua resposta não será vista.

        \n\nCancelar inscrição" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} convidou-lhe para responder" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        acho que você pode saber a resposta.

        \nVisualizar na {{.SiteName}}

        \n\n--
        \nNota: Este é um e-mail de sistema automático, por favor, não responda a esta mensagem, pois a sua resposta não será vista.

        \n\nCancelar Inscrição" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} comentou em sua publicação" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nVisualizar no {{.SiteName}}

        \n\n--
        \nNota: Este é um e-mail de sistema automático, por favor, não responda a esta mensagem, pois a sua resposta não será vista.

        \n\nCancelar inscrição" - new_question: - title: - other: "[{{.SiteName}}] Nova pergunta: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Redefinição de senha" - body: - other: "Alguém pediu para redefinir a sua senha em {{.SiteName}}.

        \n\nSe não foi você, você pode ignorar este e-mail.

        \n\nClique no seguinte link para escolher uma nova senha:
        \n{{.PassResetUrl}}

        \n\n--
        \nNota: Este é um e-mail de sistema automático, por favor, não responda a esta mensagem, pois a sua resposta não será vista." - register: - title: - other: "[{{.SiteName}}] Confirme seu novo endereço de e-mail" - body: - other: "Bem-vindo a {{.SiteName}}!

        \n\nClique no seguinte link para confirmar e ativar sua nova conta:
        \n{{.RegisterUrl}}

        \n\nSe o link acima não for clicável, tente copiá-lo e colá-lo na barra de endereços do seu navegador web.\n

        \n\n--
        \nNota: Este é um e-mail de sistema automático. por favor, não responda a esta mensagem, pois a sua resposta não será vista." - test: - title: - other: "[{{.SiteName}}] E-mail de teste" - body: - other: "Este é um e-mail de teste.\n

        \n\n--
        \nNota: Este é um e-mail automático do sistema, por favor, não responda a esta mensagem, pois a sua resposta não será vista." - action_activity_type: - upvote: - other: voto positivo - upvoted: - other: votos positivos - downvote: - other: voto negativo - downvoted: - other: voto negativo - accept: - other: aceito - accepted: - other: aceito - edit: - other: editar - review: - queued_post: - other: Publicação na fila - flagged_post: - other: Postagem sinalizada - suggested_post_edit: - other: Edições sugeridas - reaction: - tooltip: - other: "{{ .Names }} e mais {{ .Count }}..." - badge: - default_badges: - autobiographer: - name: - other: Autobiógrafo - desc: - other: Preenchido com perfil . - certified: - name: - other: Certificado - desc: - other: Completou o nosso tutorial de novo usuário. - editor: - name: - other: Editor - desc: - other: Primeira edição em publicação. - first_flag: - name: - other: Primeira Sinalização - desc: - other: Primeiro sinalização numa publicação. - first_upvote: - name: - other: Primeiro voto - desc: - other: Primeiro post votado. - first_link: - name: - other: Primeiro link - desc: - other: First added a link to another post. - first_reaction: - name: - other: Primeira Reação - desc: - other: Primeira reação a um post. - first_share: - name: - other: Primeiro Compartilhamento - desc: - other: Primeiro a compartilhar um post. - scholar: - name: - other: Académico - desc: - other: Fez uma pergunta e aceitou uma resposta. - commentator: - name: - other: Comentador - desc: - other: Fez 5 comentários. - new_user_of_the_month: - name: - other: Novo usuário do mês - desc: - other: Contribuições pendentes no seu primeiro mês. - read_guidelines: - name: - other: Ler diretrizes - desc: - other: Leia as [diretrizes da comunidade]. - reader: - name: - other: Leitor - desc: - other: Leia todas as respostas num tópico com mais de 10 respostas. - welcome: - name: - other: Bem-vindo - desc: - other: Recebeu um voto positivo. - nice_share: - name: - other: Bom compartilhador - desc: - other: Compartilhou um post com 25 visitantes únicos. - good_share: - name: - other: Bom compartilhador - desc: - other: Compartilhou um post com 300 visitantes únicos. - great_share: - name: - other: Grande Compartilhador - desc: - other: Compartilhou um post com 1000 visitantes únicos. - out_of_love: - name: - other: Por amor - desc: - other: Cinquenta votos positivos em um dia. - higher_love: - name: - other: Amor Superior - desc: - other: Usou 50 votos positivos em um dia — 5 vezes. - crazy_in_love: - name: - other: Amor Louco - desc: - other: Usou 50 votos positivos em um dia — 20 vezes. - promoter: - name: - other: Promotor - desc: - other: Convidou um usuário. - campaigner: - name: - other: Ativista - desc: - other: Foram convidados 3 usuários básicos. - champion: - name: - other: Campeão - desc: - other: Cinco membros convidados. - thank_you: - name: - other: Obrigado - desc: - other: Recebeu 20 votos positivos e deu 10 votos. - gives_back: - name: - other: Dar de volta - desc: - other: Recebeu100 votos positivos e deu 100 votos a favor. - empathetic: - name: - other: Empático - desc: - other: Recebeu 500 votos e deu 1000 votos. - enthusiast: - name: - other: Entusiasta - desc: - other: . - aficionado: - name: - other: Aficionado - desc: - other: Visitou 100 dias consecutivos. - devotee: - name: - other: Devoto - desc: - other: Visitou 365 dias consecutivos. - anniversary: - name: - other: Aniversário - desc: - other: Membro ativo por um ano, postando pelo menos uma vez. - appreciated: - name: - other: Apreciado - desc: - other: Recebeu 1 voto positivo em 20 posts. - respected: - name: - other: Respeitado - desc: - other: Novos 2 votos em 100 posts. - admired: - name: - other: Admirado - desc: - other: Recebeu 5 votos positivos em 300 posts. - solved: - name: - other: Resolvido - desc: - other: Ter uma resposta aceita. - guidance_counsellor: - name: - other: Orientador Educacional - desc: - other: Tenham 10 respostas aceitas. - know_it_all: - name: - other: Sabichão - desc: - other: Tenha 50 respostas aceitas. - solution_institution: - name: - other: Instituição de Soluções - desc: - other: Tenham 150 respostas aceitas. - nice_answer: - name: - other: Resposta legal - desc: - other: Resposta com pontuação maior que 10. - good_answer: - name: - other: Boa resposta - desc: - other: Resposta com pontuação maior que 25. - great_answer: - name: - other: Ótima Resposta - desc: - other: Resposta com pontuação maior que 50. - nice_question: - name: - other: Questão legal - desc: - other: Pergunta com pontuação maior que 10. - good_question: - name: - other: Boa questão - desc: - other: Questão com pontuação maior que 25. - great_question: - name: - other: Otima questão - desc: - other: Questão com pontuação maior que 50. - popular_question: - name: - other: Pergunta Popular - desc: - other: Pergunta com 500 visualizações. - notable_question: - name: - other: Pergunta Notável - desc: - other: Pergunta com 1000 visualizações. - famous_question: - name: - other: Pergunta Famosa - desc: - other: Pergunta com 5000 visualizações. - popular_link: - name: - other: Link Popular - desc: - other: Postou um link externo com 50 cliques. - hot_link: - name: - other: Link Quente - desc: - other: Postou um link externo com 300 cliques. - famous_link: - name: - other: Link Famoso - desc: - other: Postou um link externo com 100 cliques. - default_badge_groups: - getting_started: - name: - other: Começando - community: - name: - other: Comunidade - posting: - name: - other: Postando -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Como formatar - desc: >- -
        • mencionar uma postagem: #post_id

        • para mais links

          <https://url.com>

          [Título](https://url.com)
        • colocar retornos entre parágrafos

        • _italic_ ou **bold**

        • identar código por 4 espaços

        • cotação colocando > no início da linha

        • aspas invertidas `tipo_isso`

        • criar cercas de código com aspas invertidas `

          ```
          código aqui
          ```
        - pagination: - prev: Anterior - next: Próximo - page_title: - question: Pergunta - questions: Perguntas - tag: Marcador - tags: Marcadores - tag_wiki: marcador wiki - create_tag: Criar Marcador - edit_tag: Editar Marcador - ask_a_question: Create Question - edit_question: Editar Pergunta - edit_answer: Editar Resposta - search: Busca - posts_containing: Postagens contendo - settings: Configurações - notifications: Notificações - login: Entrar - sign_up: Registar-se - account_recovery: Recuperação de conta - account_activation: Ativação de conta - confirm_email: Confirmar E-mail - account_suspended: Conta suspensa - admin: Administrador - change_email: Modificar e-mail - install: Instalação do Answer - upgrade: Atualização do Answer - maintenance: Manutenção do website - users: Usuários - oauth_callback: Processando - http_404: HTTP Erro 404 - http_50X: HTTP Erro 500 - http_403: HTTP Erro 403 - logout: Encerrar Sessão - posts: Posts - notifications: - title: Notificações - inbox: Caixa de entrada - achievement: Conquistas - new_alerts: Novos alertas - all_read: Marcar todos como lida - show_more: Mostrar mais - someone: Alguém - inbox_type: - all: Tudo - posts: Postagens - invites: Convites - votes: Votos - answer: Resposta - question: Questão - badge_award: Emblema - suspended: - title: A sua conta foi suspensa - until_time: "Sua conta está suspensa até {{ time }}." - forever: Este usuário foi suspenso permanentemente. - end: Você não atende a uma diretriz da comunidade. - contact_us: Entre em contato conosco - editor: - blockquote: - text: Bloco de citação - bold: - text: Negrito - chart: - text: Gráfico - flow_chart: Gráfico de fluxo - sequence_diagram: Diagrama de sequência - class_diagram: Diagrama de classe - state_diagram: Diagrama de estado - entity_relationship_diagram: Diagrama de relacionamento de entidade - user_defined_diagram: Diagrama definido pelo usuário - gantt_chart: Gráfico de Gantt - pie_chart: Gráfico de pizza - code: - text: Exemplo de código - add_code: Adicionar exemplo de código - form: - fields: - code: - label: Código - msg: - empty: Código não pode ser vazio. - language: - label: Idioma - placeholder: Deteção automática - btn_cancel: Cancelar - btn_confirm: Adicionar - formula: - text: Fórmula - options: - inline: Fórmula na linha - block: Bloco de fórmula - heading: - text: Cabeçalho - options: - h1: Cabeçalho 1 - h2: Cabeçalho 2 - h3: Cabeçalho 3 - h4: Cabeçalho 4 - h5: Cabeçalho 5 - h6: Cabeçalho 6 - help: - text: Ajuda - hr: - text: Régua horizontal - image: - text: Imagem - add_image: Adicionar imagem - tab_image: Enviar image, - form_image: - fields: - file: - label: Arquivo de imagem - btn: Selecione imagem - msg: - empty: Arquivo não pode ser vazio. - only_image: Somente um arquivo de imagem é permitido. - max_size: O tamanho do arquivo não pode exceder {{size}} MB. - desc: - label: Descrição (opcional) - tab_url: URL da imagem - form_url: - fields: - url: - label: URL da imagem - msg: - empty: URL da imagem não pode ser vazia. - name: - label: Descrição (opcional) - btn_cancel: Cancelar - btn_confirm: Adicionar - uploading: Enviando - indent: - text: Identação - outdent: - text: Não identado - italic: - text: Emphase - link: - text: Superlink (Hyperlink) - add_link: Adicionar superlink (hyperlink) - form: - fields: - url: - label: URL - msg: - empty: URL não pode ser vazia. - name: - label: Descrição (opcional) - btn_cancel: Cancelar - btn_confirm: Adicionar - ordered_list: - text: Lista numerada - unordered_list: - text: Lista com marcadores - table: - text: Tabela - heading: heading - cell: Célula - file: - text: Anexar arquivos - not_supported: "Não suporta esse tipo de arquivo. Tente novamente com {{file_type}}." - max_size: "Anexar arquivos não pode exceder {{size}} MB." - close_modal: - title: Estou fechando este post como... - btn_cancel: Cancelar - btn_submit: Enviar - remark: - empty: Não pode ser vazio. - msg: - empty: Por favor selecione um motivo. - report_modal: - flag_title: Estou marcando para denunciar este post como... - close_title: Estou fechando este post como... - review_question_title: Revisar pergunta - review_answer_title: Revisar resposta - review_comment_title: Revisar comentário - btn_cancel: Cancelar - btn_submit: Enviar - remark: - empty: Não pode ser vazio. - msg: - empty: Por favor selecione um motivo. - not_a_url: Formato da URL incorreto. - url_not_match: A origem da URL não corresponde ao site atual. - tag_modal: - title: Criar novo marcador - form: - fields: - display_name: - label: Nome de exibição - msg: - empty: Nome de exibição não pode ser vazio. - range: Nome de exibição tem que ter até 35 caracteres. - slug_name: - label: Slug de URL - desc: 'Deve usar o conjunto de caracteres "a-z", "0-9", "+ # - ."' - msg: - empty: URL slug não pode ser vazio. - range: URL slug até 35 caracteres. - character: URL slug contém conjunto de caracteres não permitido. - desc: - label: Descrição (opcional) - revision: - label: Revisão - edit_summary: - label: Editar descrição - placeholder: >- - Explique resumidamente as suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada) - btn_cancel: Cancelar - btn_submit: Enviar - btn_post: Postar novo marcador - tag_info: - created_at: Criado - edited_at: Editado - history: Histórico - synonyms: - title: Sinônimos - text: Os marcadores a seguir serão re-mapeados para - empty: Sinônimos não encotrados. - btn_add: Adicionar um sinônimo - btn_edit: Editar - btn_save: Salvar - synonyms_text: Os marcadores a seguir serão re-mapeados para - delete: - title: Remover este marcador - tip_with_posts: >- -

        Nós não permitimos remover marcadores com postagens.

        Por favor, remova este marcador a partir da postagem.

        - tip_with_synonyms: >- -

        Nós não permitimos remover marcadores com postagens.

        Por favor, remova este marcador a partir da postagem.

        - tip: Você tem certeza que deseja remover? - close: Fechar - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Editar marcador - default_reason: Editar marcador - default_first_reason: Adicionar marcador - btn_save_edits: Salvar edições - btn_cancel: Cancelar - dates: - long_date: D MMM - long_date_with_year: "D MMM, YYYY" - long_date_with_time: "D MMM, YYYY [at] HH:mm" - now: agora - x_seconds_ago: "{{count}}s atrás" - x_minutes_ago: "{{count}}m atrás" - x_hours_ago: "{{count}}h atrás" - hour: hora - day: dia - hours: horas - days: dias - month: month - months: months - year: year - reaction: - heart: coração - smile: sorrir - frown: cara feia - btn_label: adicionar ou remover reações - undo_emoji: desfazer reação {{ emoji }} - react_emoji: reagir com {{ emoji }} - unreact_emoji: remover reação {{ emoji }} - comment: - btn_add_comment: Adicionar comentário - reply_to: Responder a - btn_reply: Responder - btn_edit: Editar - btn_delete: Excluir - btn_flag: Marcador - btn_save_edits: Salvar edições - btn_cancel: Cancelar - show_more: "Mais {{count}} comentários" - tip_question: >- - Use os comentários para pedir mais informações ou sugerir melhorias. Evite responder perguntas nos comentários. - tip_answer: >- - Use comentários para responder a outros usuários ou notificá-los sobre alterações. Se você estiver adicionando novas informações, edite sua postagem em vez de comentar. - tip_vote: Isto adiciona alguma utilidade à postagem - edit_answer: - title: Editar Resposta - default_reason: Editar Resposta - default_first_reason: Adicionar resposta - form: - fields: - revision: - label: Revisão - answer: - label: Resposta - feedback: - characters: conteúdo deve ser pelo menos 6 characters em comprimento. - edit_summary: - label: Resumo da edição - placeholder: >- - Explique resumidamente suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada) - btn_save_edits: Salvar edições - btn_cancel: Cancelar - tags: - title: Marcadores - sort_buttons: - popular: Popular - name: Nome - newest: mais recente - button_follow: Seguir - button_following: Seguindo - tag_label: perguntas - search_placeholder: Filtrar por nome de marcador - no_desc: O marcador não possui descrição. - more: Mais - wiki: Wiki - ask: - title: Create Question - edit_title: Editar Pergunta - default_reason: Editar pergunta - default_first_reason: Create question - similar_questions: Similar perguntas - form: - fields: - revision: - label: Revisão - title: - label: Título - placeholder: What's your topic? Be specific. - msg: - empty: Título não pode ser vazio. - range: Título até 150 caracteres - body: - label: Corpo - msg: - empty: Corpo da mensagem não pode ser vazio. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Marcadores - msg: - empty: Marcadores não podes ser vazios. - answer: - label: Resposta - msg: - empty: Resposta não pode ser vazia. - edit_summary: - label: Resumo da edição - placeholder: >- - Explique resumidamente suas alterações (ortografia corrigida, gramática corrigida, formatação aprimorada) - btn_post_question: Publicação a sua pergunta - btn_save_edits: Salvar edições - answer_question: Responda a sua própria pergunta - post_question&answer: Publicação a sua pergunta e resposta - tag_selector: - add_btn: Adicionar marcador - create_btn: Criar novo marcador - search_tag: Procurar marcador - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: Nenhum marcador correspondente - tag_required_text: Marcador obrigatório (ao menos um) - header: - nav: - question: Perguntas - tag: Marcadores - user: Usuários - badges: Emblemas - profile: Perfil - setting: Configurações - logout: Sair - admin: Administrador - review: Revisar - bookmark: Favoritos - moderation: Moderação - search: - placeholder: Procurar - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Mudar - loading: carregando... - pic_auth_code: - title: Captcha - placeholder: Escreva o texto acima - msg: - empty: Captcha não pode ser vazio. - inactive: - first: >- - Você está quase pronto! Enviamos um e-mail de ativação para {{mail}}. Por favor, siga as instruções no e-mail para ativar uma conta sua. - info: "Se não chegar, verifique sua pasta de spam." - another: >- - Enviamos outro e-mail de ativação para você em {{mail}}. Pode levar alguns minutos para chegar; certifique-se de verificar sua pasta de spam. - btn_name: Reenviar e-mail de ativação - change_btn_name: Mudar email - msg: - empty: Não pode ser vazio. - resend_email: - url_label: Tem certeza de que deseja reenviar o e-mail de ativação? - url_text: Você também pode fornecer o link de ativação acima para o usuário. - login: - login_to_continue: Entre para continue - info_sign: Não possui uma conta? <1>Cadastrar-se - info_login: Já possui uma conta? <1>Entre - agreements: Ao se registrar, você concorda com as <1>políticas de privacidades e os <3>termos de serviços. - forgot_pass: Esqueceu a sua senha? - name: - label: Nome - msg: - empty: Nome não pode ser vazio. - range: O nome deve ter entre 2 e 30 caracteres. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: E-mail - msg: - empty: E-mail não pode ser vazio. - password: - label: Senha - msg: - empty: Senha não pode ser vazia. - different: As senhas inseridas em ambos os campos são inconsistentes - account_forgot: - page_title: Esqueceu a sua senha - btn_name: Enviar e-mail de recuperação de senha - send_success: >- - Se uma conta corresponder {{mail}}, você deve receber um e-mail com instruções sobre como redefinir sua senha em breve. - email: - label: E-mail - msg: - empty: E-mail não pode ser vazio. - change_email: - btn_cancel: Cancelar - btn_update: Atualiza email address - send_success: >- - Se uma conta corresponder {{mail}}, você deve receber um e-mail com instruções sobre como redefinir sua senha em breve. - email: - label: Novo E-mail - msg: - empty: E-mail não pode ser vazio. - oauth: - connect: Conecte com {{ auth_name }} - remove: Remover {{ auth_name }} - oauth_bind_email: - subtitle: Adicione um e-mail para recuperação da conta. - btn_update: Atualizar endereço de e-mail - email: - label: E-mail - msg: - empty: E-mail não pode ser vazio. - modal_title: E-mail já existe. - modal_content: Este e-mail já está cadastrado. Você tem certeza que deseja conectar à conta existente? - modal_cancel: Alterar E-mail - modal_confirm: Conectar a uma conta existente - password_reset: - page_title: Redefinir senha - btn_name: Redefinir minha senha - reset_success: >- - Você alterou com sucesso uma senha sua; você será redirecionado para a página de login. - link_invalid: >- - Desculpe, este link de redefinição de senha não é mais válido. Talvez uma senha sua já tenha sido redefinida? - to_login: Continuar para a tela de login - password: - label: Senha - msg: - empty: Senha não pode ser vazio. - length: O comprimento deve estar entre 8 e 32 - different: As senhas inseridas em ambos os campos são inconsistentes - password_confirm: - label: Confirmar Nova senha - settings: - page_title: Configurações - goto_modify: Ir para modificar - nav: - profile: Perfil - notification: Notificações - account: Conta - interface: Interface - profile: - heading: Perfil - btn_name: Salvar - display_name: - label: Nome de exibição - msg: Nome de exibição não pode ser vazio. - msg_range: Display name must be 2-30 characters in length. - username: - label: Nome de usuário - caption: As pessoas poderão mensionar você com "@usuário". - msg: Nome de usuário não pode ser vazio. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Perfil Imagem - gravatar: Gravatar - gravatar_text: Você pode mudar a imagem em <1>gravatar.com - custom: Customizado - custom_text: Você pode enviar a sua image. - default: Padrão do Sistema - msg: Por favor envie um avatar - bio: - label: Sobre mim (opcional) - website: - label: Website (opcional) - placeholder: "https://exemplo.com.br" - msg: Formato incorreto de endereço de Website - location: - label: Localização (opcional) - placeholder: "Cidade, País" - notification: - heading: Notificações por e-mail - turn_on: Ativar - inbox: - label: Notificações na caixa de entrada - description: Responda suas próprias perguntas, comentários, convites e muito mais. - all_new_question: - label: Todas as perguntas novas - description: Seja notificado de todas as novas perguntas. Até 50 perguntas por semana. - all_new_question_for_following_tags: - label: Novas perguntas para os seguintes marcadores - description: Seja notificado de novas perguntas para os seguintes marcadores. - account: - heading: Conta - change_email_btn: Mudar e-mail - change_pass_btn: Mudar senha - change_email_info: >- - Enviamos um e-mail para esse endereço. Siga as instruções de confirmação. - email: - label: Correio eletrónico - new_email: - label: Novo correio eletrónico - msg: Novo correio eletrónico não pode ser vazio. - pass: - label: Senha atual - msg: Senha não pode ser vazio. - password_title: Senha - current_pass: - label: Senha atual - msg: - empty: A Senha não pode ser vazia. - length: O comprimento deve estar entre 8 and 32. - different: As duas senhas inseridas não correspondem. - new_pass: - label: Nova Senha - pass_confirm: - label: Confirmar nova Senha - interface: - heading: Interface - lang: - label: Idioma da Interface - text: Idioma da interface do usuário. A interface mudará quando você atualizar a página. - my_logins: - title: Meus logins - label: Entre ou cadastre-se neste site utilizando estas contas. - modal_title: Remover login - modal_content: Você tem certeza que deseja remover este login da sua conta? - modal_confirm_btn: Remover - remove_success: Removido com sucesso - toast: - update: atualização realizada com sucesso - update_password: Senha alterada com sucesso. - flag_success: Obrigado por marcar. - forbidden_operate_self: Proibido para operar por você mesmo - review: A sua resposta irá aparecer após a revisão. - sent_success: Enviado com sucesso - related_question: - title: Related - answers: respostas - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Pessoas Perguntaram - desc: Select people who you think might know the answer. - invite: Convidar para responder - add: Adicionar pessoas - search: Procurar pessoas - question_detail: - action: Acção - created: Created - Asked: Perguntado - asked: perguntado - update: Modificado - Edited: Edited - edit: modificado - commented: comentado - Views: Visualizado - Follow: Seguir - Following: Seguindo - follow_tip: Siga esta pergunta para receber notificações - answered: respondido - closed_in: Fechado em - show_exist: Mostrar pergunta existente. - useful: Útil - question_useful: Isso é útil e claro - question_un_useful: Isso não está claro ou não é útil - question_bookmark: Favoritar esta pergunta - answer_useful: Isso é útil - answer_un_useful: Isso não é útil - answers: - title: Respostas - score: Pontuação - newest: Mais recente - oldest: Mais Antigos - btn_accept: Aceito - btn_accepted: Aceito - write_answer: - title: A sua Resposta - edit_answer: Editar a minha resposta existente - btn_name: Publicação a sua resposta - add_another_answer: Adicionar outra resposta - confirm_title: Continuar a responder - continue: Continuar - confirm_info: >- -

        Tem certeza de que deseja adicionar outra resposta?

        Você pode usar o link de edição para refinar e melhorar uma resposta existente.

        - empty: Resposta não pode ser vazio. - characters: conteúdo deve ser pelo menos 6 caracteres em comprimento. - tips: - header_1: Obrigado pela sua resposta - li1_1: Por favor, não esqueça de responder a pergunta. Providencie detalhes e compartilhe a sua pesquisa. - li1_2: Faça backup de quaisquer declarações que você fizer com referências ou experiência pessoal. - header_2: Mas evite ... - li2_1: Pedir ajuda, buscar esclarecimentos ou responder a outras respostas. - reopen: - confirm_btn: Reabrir - title: Reabrir esta postagem - content: Você tem certeza que deseja reabrir? - list: - confirm_btn: Lista - title: Liste esta postagem - content: Você tem certeza que deseja listar? - unlist: - confirm_btn: Remover da lista - title: Remover da lista de postagens - content: Tem certeza de que deseja remover da lista? - pin: - title: Fixe esta postagem - content: Tem certeza de que deseja fixar globalmente? Esta postagem aparecerá no topo de todas as listas de postagens. - confirm_btn: Fixar - delete: - title: Excluir esta postagem - question: >- - Nós não recomendamos excluindo perguntas com respostas porque isso priva os futuros leitores desse conhecimento.

        Repeated deletion of answered questions can result in a sua account being blocked from asking. Você tem certeza que deseja deletar? - answer_accepted: >- -

        Nós não recomendamos excluir perguntas com respostas porque isso priva os futuros leitores desse conhecimento.

        A exclusão repetida de respostas aceitas pode resultar no bloqueio de respostas de sua conta.. Você tem certeza que deseja deletar? - other: Você tem certeza que deseja deletar? - tip_answer_deleted: Esta resposta foi deletada - undelete_title: Recuperar esta publicação - undelete_desc: Você tem certeza que deseja recuperar? - btns: - confirm: Confirmar - cancel: Cancelar - edit: Editar - save: Salvar - delete: Excluir - undelete: Recuperar - list: Lista - unlist: Não listar - unlisted: Não listado - login: Entrar - signup: Cadastrar-se - logout: Sair - verify: Verificar - create: Create - approve: Aprovar - reject: Rejetar - skip: Pular - discard_draft: Descartar rascunho - pinned: Fixado - all: Todos - question: Pergunta - answer: Resposta - comment: Comentário - refresh: Atualizar - resend: Reenviar - deactivate: Desativar - active: Ativar - suspend: Suspender - unsuspend: Suspensão cancelada - close: Fechar - reopen: Reabrir - ok: OK - light: Claro - dark: Escuro - system_setting: Definições de sistema - default: Padrão - reset: Reset - tag: Marcador - post_lowercase: publicação - filter: Filtro - ignore: Ignorar - submit: Submeter - normal: Normal - closed: Fechado - deleted: Removido - deleted_permanently: Deleted permanently - pending: Pendente - more: Mais - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Procurar Resultados - keywords: Palavras-chave - options: Opções - follow: Seguir - following: Seguindo - counts: "{{count}} Resultados" - counts_loading: "... Results" - more: Mais - sort_btns: - relevance: Relevância - newest: Mais recente - active: Ativar - score: Pontuação - more: Mais - tips: - title: Dicas de Pesquisa Avançada - tag: "<1>[tag] pesquisar com um marcador" - user: "<1>user:username buscar por autor" - answer: "<1>answers:0 perguntas não respondidas" - score: "<1>score:3 postagens com mais de 3+ placares" - question: "<1>is:question buscar perguntas" - is_answer: "<1>is:answer buscar respostas" - empty: Não conseguimos encontrar nada.
        Tente palavras-chave diferentes ou menos específicas. - share: - name: Compartilhar - copy: Copiar link - via: Compartilhar postagem via... - copied: Copiado - facebook: Compartilhar no Facebook - twitter: Share to X - cannot_vote_for_self: Você não pode votar na sua própria postagem - modal_confirm: - title: Erro... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: A sua nova conta está confirmada; você será redirecionado para a página inicial. - link: Continuar para a página inicial. - oops: Oops! - invalid: O link utilizado não funciona mais. - confirm_new_email: O seu e-mail foi atualizado. - confirm_new_email_invalid: >- - Desculpe, este link de confirmação não é mais válido. Talvez o seu e-mail já tenha sido alterado. - unsubscribe: - page_title: Cancelar subscrição - success_title: Cancelamento de inscrição bem-sucedido - success_desc: Você foi removido com sucesso desta lista de assinantes e não receberá mais nenhum e-mail nosso. - link: Mudar configurações - question: - following_tags: Seguindo Marcadores - edit: Editar - save: Salvar - follow_tag_tip: Seguir tags to curate a sua lista de perguntas. - hot_questions: Perguntas quentes - all_questions: Todas Perguntas - x_questions: "{{ count }} perguntas" - x_answers: "{{ count }} respostas" - x_posts: "{{ count }} Posts" - questions: Perguntas - answers: Respostas - newest: Mais recente - active: Ativo - hot: Popular - frequent: Frequente - recommend: Recomendado - score: Pontuação - unanswered: Não Respondido - modified: modificado - answered: respondido - asked: perguntado - closed: fechado - follow_a_tag: Seguir o marcador - more: Mais - personal: - overview: Visão geral - answers: Respostas - answer: resposta - questions: Perguntas - question: pergunta - bookmarks: Favoritas - reputation: Reputação - comments: Comentários - votes: Votos - badges: Emblemas - newest: Mais recente - score: Pontuação - edit_profile: Editar Perfil - visited_x_days: "Visitado {{ count }} dias" - viewed: Visualizado - joined: Ingressou - comma: "," - last_login: Visto - about_me: Sobre mim - about_me_empty: "// Olá, Mundo !" - top_answers: Melhores Respostas - top_questions: Melhores Perguntas - stats: Estatísticas - list_empty: Postagens não encontradas.
        Talvez você queira selecionar uma guia diferente? - content_empty: Nenhum post encontrado. - accepted: Aceito - answered: respondido - asked: perguntado - downvoted: voto negativo - mod_short: Moderador - mod_long: Moderadores - x_reputation: reputação - x_votes: votos recebidos - x_answers: respostas - x_questions: perguntas - recent_badges: Emblemas recentes - install: - title: Instalação - next: Proximo - done: Completo - config_yaml_error: Não é possível criar o arquivo config.yaml. - lang: - label: Por favor Escolha um Idioma - db_type: - label: Motor do Banco de dados - db_username: - label: Nome de usuário - placeholder: raiz - msg: Nome de usuário não pode ser vazio. - db_password: - label: Senha - placeholder: raiz - msg: Senha não pode ser vazio. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host não pode ser vazio. - db_name: - label: Database Nome - placeholder: resposta - msg: Database Nome não pode ser vazio. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File não pode ser vazio. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Criar config.yaml - label: Arquivo config.yaml criado. - desc: >- - Você pode criar o arquivo <1>config.yaml manualmente no diretório <1>/var/ww/xxx/ e colar o seguinte texto nele. - info: Qlique no botão "Próximo" após finalizar. - site_information: Informação do Site - admin_account: Administrador Conta - site_name: - label: Site Nome - msg: Site Nome não pode ser vazio. - msg_max_length: O nome do site deve ter no máximo 30 caracteres. - site_url: - label: URL do Site - text: O endereço do seu site. - msg: - empty: Site URL não pode ser vazio. - incorrect: URL do site está incorreto. - max_length: O nome do site deve ter no máximo 512 caracteres. - contact_email: - label: E-mail par contato - text: O endereço de e-mail do contato principal deste site. - msg: - empty: E-mail par contato não pode ser vazio. - incorrect: E-mail par contato incorrect format. - login_required: - label: Privado - switch: É necessário fazer login - text: Somente usuários conectados podem acessar esta comunidade. - admin_name: - label: Nome - msg: Nome não pode ser vazio. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Senha - text: >- - You will need this password to log in. Por favor store it in a secure location. - msg: Senha não pode ser vazio. - msg_min_length: A senha deve ser ter pelo menos 8 caracteres. - msg_max_length: A senha deve ter no máximo 32 caracteres. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: E-mail - text: Você precisará deste e-mail para efetuar o login. - msg: - empty: Email não pode ser vazio. - incorrect: O formato do e-mail está incorreto. - ready_title: Seu site está pronto - ready_desc: >- - Se você quiser alterar mais configurações, visite <1>seção de administrador; encontre-o no menu do site. - good_luck: "Divirta-se, e boa sorte!" - warn_title: Atenção - warn_desc: >- - O arquivo <1>config.yaml já existe. Se você precisa redefinir algum dos itens de configuração deste arquivo, apague-o primeiro. - install_now: Você pode tentar <1>instalando agora. - installed: Já instalado - installed_desc: >- - You appear to have already installed. To reinstall please clear a sua old database tables first. - db_failed: Falha ao conectar-se ao banco de dados - db_failed_desc: >- - This either means that the database information in a sua <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean a sua host's database server is down. - counts: - views: visualizações - votes: votos - answers: respostas - accepted: Aceito - page_error: - http_error: Erro HTTP {{ code }} - desc_403: Você não possui permissão para acessar esta página. - desc_404: Infelizmente esta página não existe. - desc_50X: Houve um erro no servidor e não foi possível completar a sua requisição. - back_home: Voltar para a página inicial - page_maintenance: - desc: "Estamos em manutenção, voltaremos em breve." - nav_menus: - dashboard: Painel - contents: Conteúdos - questions: Perguntas - answers: Respostas - users: Usuários - badges: Emblemas - flags: Marcadores - settings: Configurações - general: Geral - interface: Interface - smtp: SMTP - branding: Marca - legal: Informação legal - write: Escrever - terms: Terms - tos: Termos de Serviços - privacy: Privacidade - seo: SEO - customize: Personalização - themes: Temas - login: Entrar - privileges: Privilégios - plugins: Extensões - installed_plugins: Plugins instalados - apperance: Appearance - website_welcome: Bem vindo(a) ao {{site_name}} - user_center: - login: Entrar - qrcode_login_tip: Por favor, utilize {{ agentName }} para escanear o QR code para entrar. - login_failed_email_tip: Falha ao entrar, por favor, permita que este aplicativo acesse a informação do seu e-mail antes de tentar novamente. - badges: - modal: - title: Parabéns - content: Você ganhou um novo emblema. - close: Fechar - confirm: Ver emblemas - title: Emblemas - awarded: Premiado - earned_×: Ganhou ×{{ number }} - ×_awarded: "{{ number }} premiado" - can_earn_multiple: Você pode ganhar isto várias vezes. - earned: Ganhou - admin: - admin_header: - title: Administrador - dashboard: - title: Painel - welcome: Bem-vindo ao Admin! - site_statistics: Estatísticas do site - questions: "Perguntas:" - resolved: "Resolvido:" - unanswered: "Não Respondido:" - answers: "Respostas:" - comments: "Comentários:" - votes: "Votos:" - users: "Usuários:" - flags: "Marcadores:" - reviews: "Revisão:" - site_health: Saúde do site - version: "Versão:" - https: "HTTPS:" - upload_folder: "Upload da pasta:" - run_mode: "Mode de execução:" - private: Privado - public: Público - smtp: "SMTP:" - timezone: "Fuso horário:" - system_info: Informação do sistema - go_version: "Versão do Go:" - database: "Banco de dados:" - database_size: "Tamanho do banco de dados:" - storage_used: "Armazenamento usado:" - uptime: "Tempo de atividade:" - links: Links - plugins: Plugins - github: GitHub - blog: Blog - contact: Contato - forum: Fórum - documents: Documentos - feedback: Opinião - support: Supporte - review: Revisar - config: Configurações - update_to: Atualizar ao - latest: Ultimo - check_failed: Falha na verificação - "yes": "Sim" - "no": "Não" - not_allowed: Não permitido - allowed: Permitido - enabled: Ativo - disabled: Disponível - writable: Possível escrever - not_writable: Não é possível escrever - flags: - title: Marcadores - pending: Pendente - completed: Completo - flagged: Marcado - flagged_type: '{{ type }} sinalizado' - created: Criado - action: Ação - review: Revisar - user_role_modal: - title: Altere a função do usuário para... - btn_cancel: Cancelar - btn_submit: Enviar - new_password_modal: - title: Criar nova senha - form: - fields: - password: - label: Senha - text: O usuário será desconectado e precisar entrar novamente. - msg: A senha precisa ter no mínimo 8-32 caracteres. - btn_cancel: Cancelar - btn_submit: Enviar - edit_profile_modal: - title: Editar profile - form: - fields: - display_name: - label: Nome no display - msg_range: Display name must be 2-30 characters in length. - username: - label: Nome do usuário - msg_range: Username must be 2-30 characters in length. - email: - label: Correio eletrônico - msg_invalid: Correio eletrônico invalido. - edit_success: Editado com sucesso - btn_cancel: Cancelar - btn_submit: Submeter - user_modal: - title: Adicionar novo usuário - form: - fields: - users: - label: Adicionar usuários em massa - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separe "nome, e-mail, senha" com vírgulas. Um usuário por linha. - msg: "Por favor insira o e-mail do usuário, um por linha." - display_name: - label: Nome de exibição - msg: O nome de exibição deve ter entre 2 e 30 caracteres. - email: - label: E-mail - msg: E-mail inválido. - password: - label: Senha - msg: A senha precisa ter no mínimo 8-32 caracteres. - btn_cancel: Cancelar - btn_submit: Enviar - users: - title: Usuários - name: Nome - email: E-mail - reputation: Reputação - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Estado - role: Função - action: Ação - change: Mudar - all: Todos - staff: Funcionários - more: Mais - inactive: Inativo - suspended: Suspenso - deleted: Removido - normal: Normal - Moderator: Moderador - Admin: Administrador - User: Usuário - filter: - placeholder: "Filtrar por nome, user:id" - set_new_password: Configurar nova senha - edit_profile: Editar profile - change_status: Mudar status - change_role: Mudar função - show_logs: Mostrar registros - add_user: Adicionar usuário - deactivate_user: - title: Desativar usuários - content: Um usuário inativo deve revalidar seu e-mail. - delete_user: - title: Remover este usuário - content: Tem certeza de que deseja excluir este usuário? Isso é permanente! - remove: Remover o conteúdo dele - label: Remover todas as perguntas, respostas, comentários etc. - text: Não marque isso se deseja excluir apenas a conta do usuário. - suspend_user: - title: Suspender este usuário - content: Um usuário suspenso não pode fazer login. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Perguntas - unlisted: Não-listado - post: Publicação - votes: Votos - answers: Respostas - created: Criado - status: Estado - action: Ação - change: Mudar - pending: Pendente - filter: - placeholder: "Filtrar por título, question:id" - answers: - page_title: Respostas - post: Publicação - votes: Votos - created: Criado - status: Estado - action: Ação - change: Mudar - filter: - placeholder: "Filtrar por título, answer:id" - general: - page_title: Geral - name: - label: Site Nome - msg: Site name não pode ser vazio. - text: "O nome deste site, conforme usado na tag de título." - site_url: - label: URL do Site - msg: Site url não pode ser vazio. - validate: Por favor digite uma URL válida. - text: O endereço do seu site. - short_desc: - label: Breve Descrição do site (opcional) - msg: Breve Descrição do site não pode ser vazio. - text: "Breve descrição, conforme usado na tag de título na página inicial." - desc: - label: Site Descrição (opcional) - msg: Descrição do site não pode ser vazio. - text: "Descreva este site em uma única sentença, conforme usado na meta tag de descrição." - contact_email: - label: E-mail para contato - msg: E-mail par contato não pode ser vazio. - validate: E-mail par contato não é válido. - text: Endereço de e-mail do principal contato responsável por este site. - check_update: - label: Atualizações de software - text: Verificar se há atualizações automaticamente - interface: - page_title: Interface - language: - label: Idioma da interface - msg: Idioma da Interface não pode ser vazio. - text: Idioma da interface do Usuário. Ele mudará quando você atualizar a página. - time_zone: - label: Fuso horário - msg: Fuso horário não pode ser vazio. - text: Escolha a cidade no mesmo fuso horário que você. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: E-mail de origem - msg: E-mail de origem não pode ser vazio. - text: O endereço de e-mail de onde os e-mails são enviados. - from_name: - label: Nome de origem - msg: Nome de origem não pode ser vazio. - text: O nome de onde os e-mails são enviados. - smtp_host: - label: SMTP Host - msg: SMTP host não pode ser vazio. - text: O seu servidor de e-mails. - encryption: - label: Criptografia - msg: Criptografia não pode ser vazio. - text: Para a maioria dos servidores SSL é a opção recomendada. - ssl: SSL - tls: TLS - none: Nenhum - smtp_port: - label: SMTP Port - msg: Porta SMTP deve ser o número 1 ~ 65535. - text: The port to a sua mail server. - smtp_username: - label: SMTP Nome de usuário - msg: SMTP username não pode ser vazio. - smtp_password: - label: SMTP Senha - msg: SMTP password não pode ser vazio. - test_email_recipient: - label: Test Email Recipients - text: Forneça o endereço de e-mail que irá receber envios de teste. - msg: O e-mail de teste é inválido - smtp_authentication: - label: Habilitar autenticação - title: Autenticação SMTP - msg: Autenticação SMTP não pode ser vazio. - "yes": "Sim" - "no": "Não" - branding: - page_title: Marca - logo: - label: Logo (opcional) - msg: Logo não pode ser vazio. - text: The logo image at the top left of a sua site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (opcional) - text: The logo used on mobile version of a sua site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square Icon (opcional) - msg: Square icon não pode ser vazio. - text: Imagem used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (opcional) - text: A favicon for a sua site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Informação legal - terms_of_service: - label: Terms of Service - text: "Você pode adicionar termos de conteúdo de serviço aqui. Se você já tem um documento hospedado em outro lugar, forneça a URL completa aqui." - privacy_policy: - label: Privacy Policy - text: "Você pode adicionar termos de conteúdo de serviço aqui. Se você já tem um documento hospedado em outro lugar, forneça a URL completa aqui." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Escrever - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Escrever resposta - label: Each user can only write one answer for each question - text: "Desative para permitir que os usuários escrevam várias respostas para a mesma pergunta, o que pode fazer com que as respostas fiquem menos focadas." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Recommend Marcadores - text: "Os marcadores recomendados serão exibidos na lista dropdown por padrão." - msg: - contain_reserved: "tags recomendadas não podem conter tags reservadas" - required_tag: - title: Definir tags necessárias - label: Definir "Tags recomendadas" como tags necessárias - text: "Every new question must have ao menos one recommend tag." - reserved_tags: - label: Reserved Marcadores - text: "Tags reservadas só podem ser usadas pelo moderador." - image_size: - label: Tamanho máximo da imagem (MB) - text: "O tamanho máximo para upload de imagem." - attachment_size: - label: Tamanho máximo do anexo (MB) - text: "O tamanho máximo para o carregamento de arquivos anexados." - image_megapixels: - label: Máximo megapíxels da imagem - text: "Número máximo de megapixels permitido para uma imagem." - image_extensions: - label: Extensões de imagens autorizadas - text: "Uma lista de extensões de arquivo permitidas para exibição de imagens, separadas por vírgula." - attachment_extensions: - label: Extensões autorizadas para anexos - text: "Uma lista de extensões de arquivo permitidas para carregamento, separar por vírgula. AVISO: permitir o carregamento pode causar problemas de segurança." - seo: - page_title: SEO - permalink: - label: Link permanente - text: Custom URL structures can improve the usability, and forward-compatibility of a sua links. - robots: - label: robos.txt - text: Isto irá substituir permanentemente quaisquer configurações do site relacionadas. - themes: - page_title: Temas - themes: - label: Temas - text: Selecionar um tema existente. - color_scheme: - label: Esquema de cores - navbar_style: - label: Navbar background style - primary_color: - label: Cor primária - text: Modifica as cores usadas por seus temas - css_and_html: - page_title: CSS e HTML - custom_css: - label: CSS Personalizado - text: > - - head: - label: Cabeçalho - text: > - - header: - label: Cabeçalho - text: > - - footer: - label: Rodapé - text: Isto será inserido antes de </body>. - sidebar: - label: Barra lateral - text: Isto irá inserir na barra lateral. - login: - page_title: Entrar - membership: - title: Afiliação - label: Permitir novas inscrições - text: Desligue para impedir que alguém crie uma nova conta. - email_registration: - title: Registrar e-mail - label: Permitir registro utilizando e-mail - text: Desative para impedir que qualquer pessoa crie uma nova conta por e-mail. - allowed_email_domains: - title: Domínios de e-mail permitidos - text: Domínios de e-mail com os quais os usuários devem registrar contas. Um domínio por linha. Ignorado quando vazio. - private: - title: Privado - label: Login requirido - text: Somente usuários conectados podem acessar esta comunidade. - password_login: - title: Login com senha - label: Permitir login por e-mail e senha - text: "AVISO: Se desativar, você pode ser incapaz de efetuar login se você não tiver configurado anteriormente outro método de login." - installed_plugins: - title: Extensões instaladas - plugin_link: Plugins ampliam e expandem a funcionalidade. Você pode encontrar plugins no <1>Repositório de Plugins. - filter: - all: Todos - active: Ativo - inactive: Inativo - outdated: Desactualizado - plugins: - label: Extensões - text: Selecionar uma extensão existente. - name: Nome - version: Versão - status: Estado - action: Ação - deactivate: Desativar - activate: Ativado - settings: Configurações - settings_users: - title: Usuários - avatar: - label: Avatar padrão - text: Para usuários sem um avatar personalizado próprio. - gravatar_base_url: - label: Gravatar Base URL - text: URL da API do provedor Gravatar ignorado quando vazio. - profile_editable: - title: Perfil editável - allow_update_display_name: - label: Permitir que os usuários mudem seus nomes de exibição - allow_update_username: - label: Permitem que os usuário mudem seus nomes de usuário - allow_update_avatar: - label: Permitem que os usuário mudem a sua imagem de perfil - allow_update_bio: - label: Permitir que os usuários mudem suas descrições - allow_update_website: - label: Permitir que os usuários mudem seus web-sites - allow_update_location: - label: Permitir que usuários alterem suas localizações - privilege: - title: Privilégios - level: - label: Nível de reputação necessário - text: Escolha a reputação necessária para os privilégios - msg: - should_be_number: o valor de entrada deve ser número - number_larger_1: número deve ser igual ou maior que 1 - badges: - action: Ação - active: Ativo - activate: Ativado - all: Todos - awards: Prêmios - deactivate: Desativar - filter: - placeholder: Filtrar por nome, badge:id - group: Grupo - inactive: Inativo - name: Nome - show_logs: Mostrar registros - status: Status - title: Emblemas - form: - optional: (opcional) - empty: não pode ser vazio - invalid: é inválido - btn_submit: Salvar - not_found_props: "Propriedade requerida {{ key }} não encontrada." - select: Selecionar - page_review: - review: Revisar - proposed: proposto - question_edit: Editar pergunta - answer_edit: Editar resposta - tag_edit: Editar marcador - edit_summary: Editar descrição - edit_question: Editar pergunta - edit_answer: Editar resposta - edit_tag: Editar marcador - empty: Nenhuma tarefa de revisão restante. - approve_revision_tip: Você aprova esta revisão? - approve_flag_tip: Você aprova esta sinalização? - approve_post_tip: Você aprova esta publicação? - approve_user_tip: Você aprova este usuário? - suggest_edits: Edições sugeridas - flag_post: Post sinalizado - flag_user: Sinalizar usuário - queued_post: Publicação na fila - queued_user: Usuário na fila - filter_label: Tipo - reputation: reputação - flag_post_type: Sinalizou esta publicação como {{ type }}. - flag_user_type: Sinalizou este usuário como {{ type }}. - edit_post: Editar publicação - list_post: Listar postagem - unlist_post: Remover postagem da lista - timeline: - undeleted: não removido - deleted: removido - downvote: voto negativo - upvote: voto positivo - accept: aceito - cancelled: cancelado - commented: comentado - rollback: reversão - edited: editado - answered: respondido - asked: perguntado - closed: fechado - reopened: reaberto - created: criado - pin: fixado - unpin: desafixado - show: listadas - hide: não listado - title: "Histórico para" - tag_title: "Título para" - show_votes: "Mostrar Votos" - n_or_a: Não aplicável - title_for_question: "Título para" - title_for_answer: "Título para resposta {{ title }} por {{ author }}" - title_for_tag: "Título para marcador" - datetime: Data e hora - type: Tipo - by: Por - comment: Comentário - no_data: "Não conseguimos encontrar nada." - users: - title: Usuários - users_with_the_most_reputation: Usuários com maior pontuação - users_with_the_most_vote: Usuários que mais votaram - staffs: Nossos colaboradores - reputation: reputação - votes: votos - prompt: - leave_page: Tem a certeza que quer sair desta página? - changes_not_save: Suas alterações não podem ser salvas. - draft: - discard_confirm: Tem certeza que deseja descartar o rascunho? - messages: - post_deleted: Esta publicação foi removida. - post_cancel_deleted: Esta postagem foi restaurada. - post_pin: Esta publicação foi fixada. - post_unpin: Esta postagem foi desafixada. - post_hide_list: Esta postagem foi ocultada da lista. - post_show_list: Esta postagem foi exibida à lista. - post_reopen: Esta publicação foi re-aberta. - post_list: Esta postagem foi listada. - post_unlist: Esta publicação foi removida da lista. - post_pending: A sua postagem está aguardando revisão. Ela ficará visível depois que for aprovada. - post_closed: Esta postagem foi fechada. - answer_deleted: Esta resposta foi excluída. - answer_cancel_deleted: Esta resposta foi restaurada. - change_user_role: O papel deste usuário foi alterado. - user_inactive: Este usuário já está inativo. - user_normal: Este usuário já está normal. - user_suspended: Este usuário foi suspenso. - user_deleted: Este usuário foi removido. - badge_activated: Este emblema foi ativado. - badge_inactivated: Este emblema foi desativado. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/ro_RO.yaml b/data/i18n/ro_RO.yaml deleted file mode 100644 index f001328b6..000000000 --- a/data/i18n/ro_RO.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Succes. - unknown: - other: Eroare necunoscută. - request_format_error: - other: Formatul cererii nu este valid. - unauthorized_error: - other: Neautorizat. - database_error: - other: Eroare la serverul de date. - forbidden_error: - other: Interzis. - duplicate_request_error: - other: Trimitere dublă. - action: - report: - other: Steag - edit: - other: Editează - delete: - other: Ștergere - close: - other: Închide - reopen: - other: Redeschidere - forbidden_error: - other: Interzis. - pin: - other: Fixează - hide: - other: Dezlistare - unpin: - other: Anulați fixarea - show: - other: Listă - invite_someone_to_answer: - other: Editează - undelete: - other: Restabilește - merge: - other: Îmbinare - role: - name: - user: - other: Utilizator - admin: - other: Administrator - moderator: - other: Moderator - description: - user: - other: Implicit fără acces special. - admin: - other: Ai puterea deplină de a accesa site-ul. - moderator: - other: Are acces la toate postările cu excepţia setărilor administratorului. - privilege: - level_1: - description: - other: Nivel 1 (mai puțină reputație pentru echipa privată, grup) - level_2: - description: - other: Nivelul 2 (reputație scăzută necesară pentru comunitatea de pornire) - level_3: - description: - other: Nivelul 3 (reputație ridicată necesară pentru comunitatea mature) - level_custom: - description: - other: Nivel personalizat - rank_question_add_label: - other: Întreabă ceva - rank_answer_add_label: - other: Scrie răspunsul - rank_comment_add_label: - other: Scrie comentariu - rank_report_add_label: - other: Steag - rank_comment_vote_up_label: - other: Votează comentariul - rank_link_url_limit_label: - other: Postează mai mult de 2 link-uri simultan - rank_question_vote_up_label: - other: Votează întrebarea - rank_answer_vote_up_label: - other: Votează răspunsul - rank_question_vote_down_label: - other: Votează întrebarea ca negativa - rank_answer_vote_down_label: - other: Voteaza răspunsul ca negativ - rank_invite_someone_to_answer_label: - other: Invită pe cineva să răspundă - rank_tag_add_label: - other: Creează o etichetă nouă - rank_tag_edit_label: - other: Editați descrierea etichetei (este nevoie de revizuire) - rank_question_edit_label: - other: Editați altă întrebare (este nevoie de revizuire) - rank_answer_edit_label: - other: Editați altă întrebare (este nevoie de revizuire) - rank_question_edit_without_review_label: - other: Editează întrebarea celuilalt fără revizuire - rank_answer_edit_without_review_label: - other: Editează întrebarea celuilalt fără revizuire - rank_question_audit_label: - other: Revizuiește editarea întrebărilor - rank_answer_audit_label: - other: Revizuiește editările răspunsurilor - rank_tag_audit_label: - other: Revizuiește editarea etichetelor - rank_tag_edit_without_review_label: - other: Editează descrierea etichetei fără revizuire - rank_tag_synonym_label: - other: Gestionează sinonimele etichetelor - email: - other: E-mail - e_mail: - other: E-mail - password: - other: Parolă - pass: - other: Parolă - old_pass: - other: Parolă actuală - original_text: - other: Acest articol - email_or_password_wrong_error: - other: E-mailul și parola nu se potrivesc. - error: - common: - invalid_url: - other: URL invalid. - status_invalid: - other: Stare nevalidă. - password: - space_invalid: - other: Parola nu poate conține spații. - admin: - cannot_update_their_password: - other: Nu vă puteți modifica parola. - cannot_edit_their_profile: - other: Nu vă puteți modifica profilul. - cannot_modify_self_status: - other: Nu vă puteți modifica starea. - email_or_password_wrong: - other: E-mailul și parola nu se potrivesc. - answer: - not_found: - other: Răspunsul nu a fost găsit. - cannot_deleted: - other: Nu există permisiunea de ștergere. - cannot_update: - other: Nu există permisiunea de ștergere. - question_closed_cannot_add: - other: Întrebările sunt închise şi nu pot fi adăugate. - content_cannot_empty: - other: Conținutul răspunsului nu poate fi gol. - comment: - edit_without_permission: - other: Comentariul nu poate fi editat. - not_found: - other: Comentariul nu a fost găsit. - cannot_edit_after_deadline: - other: Comentariul a durat prea mult pentru a fi modificat. - content_cannot_empty: - other: Conținutul comentariului nu poate fi gol. - email: - duplicate: - other: Email-ul există deja. - need_to_be_verified: - other: E-mailul trebuie verificat. - verify_url_expired: - other: Adresa de e-mail verificată a expirat, vă rugăm să retrimiteți e-mailul. - illegal_email_domain_error: - other: E-mailul nu este permis din acel domeniu de e-mail. Vă rugăm să folosiți altul. - lang: - not_found: - other: Fișierul de limbă nu a fost găsit. - object: - captcha_verification_failed: - other: Captcha este greșit. - disallow_follow: - other: Nu vă este permis să urmăriți. - disallow_vote: - other: Nu ai permisiunea de a vota. - disallow_vote_your_self: - other: Nu poți vota pentru propria ta postare. - not_found: - other: Obiectul nu a fost găsit. - verification_failed: - other: Verificarea a eșuat. - email_or_password_incorrect: - other: E-mailul și parola nu se potrivesc. - old_password_verification_failed: - other: Verificarea parolei vechi a eșuat - new_password_same_as_previous_setting: - other: Noua parolă este identică cu cea anterioară. - already_deleted: - other: Acest articol a fost șters. - meta: - object_not_found: - other: Nu s-a găsit obiectul Meta - question: - already_deleted: - other: Această postare a fost ștearsă. - under_review: - other: Articolul tău este în așteptare. Acesta va fi vizibil după ce a fost aprobat. - not_found: - other: Întrebarea nu a fost găsită. - cannot_deleted: - other: Nu există permisiunea de ștergere. - cannot_close: - other: Nu există permisiunea de a închide. - cannot_update: - other: Nu aveți permisiunea de a actualiza. - content_cannot_empty: - other: Conținutul nu poate fi gol. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Rangul de reputaţie nu îndeplineşte condiţia. - vote_fail_to_meet_the_condition: - other: Mulțumim pentru feedback. Aveți nevoie cel puțin de reputația {{.Rank}} pentru a vota. - no_enough_rank_to_operate: - other: Aveți nevoie cel puțin de reputația {{.Rank}} pentru a face asta. - report: - handle_failed: - other: Procesarea raportării a eșuat. - not_found: - other: Raportul nu a fost găsit. - tag: - already_exist: - other: Eticheta există deja. - not_found: - other: Eticheta nu a fost găsită. - recommend_tag_not_found: - other: Eticheta recomandată nu există. - recommend_tag_enter: - other: Te rugăm să introduci cel puțin o etichetă necesară. - not_contain_synonym_tags: - other: Nu trebuie să conțină etichete sinonime. - cannot_update: - other: Nu aveți permisiunea de a actualiza. - is_used_cannot_delete: - other: Nu puteți șterge o etichetă care este în uz. - cannot_set_synonym_as_itself: - other: Nu se poate seta sinonimul etichetei curente ca atare. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: Numele nu poate fi o adresă de e-mail. - theme: - not_found: - other: Tema nu a fost găsită. - revision: - review_underway: - other: Nu se poate edita momentan, există o versiune în coada de revizuire. - no_permission: - other: Nu ai permisiunea de a revizui. - user: - external_login_missing_user_id: - other: Platforma terță nu oferă un Id de utilizator unic, deci nu vă puteți autentifica, contactați administratorul site-ului. - external_login_unbinding_forbidden: - other: Vă rugăm să setaţi o parolă de conectare pentru contul dumneavoastră înainte de a elimina această autentificare. - email_or_password_wrong: - other: - other: E-mailul și parola nu se potrivesc. - not_found: - other: Utilizatorul nu a fost găsit. - suspended: - other: Utilizatorul a fost suspendat. - username_invalid: - other: Numele de utilizator nu este valid. - username_duplicate: - other: Numele de utilizator este deja luat. - set_avatar: - other: Setarea avatarului a eșuat. - cannot_update_your_role: - other: Nu vă puteți modifica rolul. - not_allowed_registration: - other: În prezent, site-ul nu este deschis pentru înregistrare. - not_allowed_login_via_password: - other: În prezent, site-ul nu este permis să se autentifice prin parolă. - access_denied: - other: Acces Blocat - page_access_denied: - other: Nu aveți acces la această pauză. - add_bulk_users_format_error: - other: "{{.Field}} format lângă '{{.Content}}' la linia {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "Numărul de utilizatori pe care îi adăugați odată trebuie să fie în intervalul 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Citirea configurației a eșuat - database: - connection_failed: - other: Conexiunea la baza de date a eșuat - create_table_failed: - other: Crearea tabelului a eșuat - install: - create_config_failed: - other: Nu se poate crea fișierul config.yaml. - upload: - unsupported_file_format: - other: Format de fișier incompatibil. - site_info: - config_not_found: - other: Configurarea site-ului nu a fost găsită. - badge: - object_not_found: - other: Nu s-a găsit obiectul Insignă - reason: - spam: - name: - other: nedorite - desc: - other: Acest post este o reclamă sau un vandalism. Nu este util sau relevant pentru subiectul actual. - rude_or_abusive: - name: - other: nepoliticos sau abuziv - desc: - other: "O persoană rezonabilă ar considera acest conținut nepotrivit pentru un discurs respectuos." - a_duplicate: - name: - other: un duplicat - desc: - other: Această întrebare a fost adresată înainte şi are deja un răspuns. - placeholder: - other: Introduceți link-ul de întrebare existent - not_a_answer: - name: - other: nu este un răspuns - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." - no_longer_needed: - name: - other: nu mai este necesar - desc: - other: Acest comentariu este învechit, conversaţional sau nu are relevanţă pentru această postare. - something: - name: - other: altceva - desc: - other: Acest post necesită atenție din partea personalului, din alt motiv nemenționat mai sus. - placeholder: - other: Spune-ne ce anume vă îngrijorează - community_specific: - name: - other: un motiv specific comunității - desc: - other: Această întrebare nu corespunde cu ghidul comunității. - not_clarity: - name: - other: are nevoie de detalii sau de claritate - desc: - other: Această întrebare include în prezent mai multe întrebări. Ar trebui să se concentreze asupra unei singure probleme. - looks_ok: - name: - other: arată OK - desc: - other: Această postare este bună și nu este de slabă calitate. - needs_edit: - name: - other: are nevoie de editare și am făcut-o - desc: - other: Îmbunătățește și corectează problemele cu această postare. - needs_close: - name: - other: necesită închidere - desc: - other: La o întrebare închisă nu poți răspunde, dar poți totuși să o editezi, să o votezi și să o comentezi. - needs_delete: - name: - other: necesită ștergere - desc: - other: Această postare va fi ștearsă. - question: - close: - duplicate: - name: - other: nedorite - desc: - other: Această întrebare a fost adresată înainte şi are deja un răspuns. - guideline: - name: - other: un motiv specific comunității - desc: - other: Această întrebare nu corespunde cu ghidul comunității. - multiple: - name: - other: necesită detalii sau claritate - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: altceva - desc: - other: Acest post necesită un alt motiv care nu este listat mai sus. - operation_type: - asked: - other: întrebat - answered: - other: răspunse - modified: - other: modificat - deleted_title: - other: Întrebare ștearsă - questions_title: - other: Questions - tag: - tags_title: - other: Tags - no_description: - other: The tag has no description. - notification: - action: - update_question: - other: întrebarea actualizată - answer_the_question: - other: întrebare răspunsă - update_answer: - other: răspuns actualizat - accept_answer: - other: răspuns acceptat - comment_question: - other: întrebare comentată - comment_answer: - other: răspuns comentat - reply_to_you: - other: ți-a răspuns - mention_you: - other: te-a menționat - your_question_is_closed: - other: Întrebarea dumneavoastră a fost închisă - your_question_was_deleted: - other: Întâlnirea dumneavoastră a fost ştearsă - your_answer_was_deleted: - other: Răspunsul dumneavoastră a fost șters - your_comment_was_deleted: - other: Contul dumneavoastră a fost șters - up_voted_question: - other: votează întrebarea - down_voted_question: - other: votează întrebarea negativ - up_voted_answer: - other: votează răspunsul - down_voted_answer: - other: răspuns negativ - up_voted_comment: - other: votează comentariul - invited_you_to_answer: - other: te-a invitat să răspunzi - earned_badge: - other: You've earned the "{{.BadgeName}}" badge - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Confirmați noua dvs. adresă de e-mail" - body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} a răspuns la întrebarea dvs" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} vă invită să răspundeți" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} a răspuns la întrebarea dvs" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_question: - title: - other: "[{{.SiteName}}] Întrebare nouă: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Resetare parolă" - body: - other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - register: - title: - other: "[{{.SiteName}}] Confirmă noul tău cont" - body: - other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - test: - title: - other: "[{{.SiteName}}] Test de e-mail" - body: - other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: - upvote: - other: votat - upvoted: - other: vot pozitiv - downvote: - other: vot negativ - downvoted: - other: vot negativ - accept: - other: acceptat - accepted: - other: acceptat - edit: - other: editează - review: - queued_post: - other: Posturi în așteptare - flagged_post: - other: Postare marcată - suggested_post_edit: - other: Suggested edits - reaction: - tooltip: - other: "{{ .Names }} and {{ .Count }} more..." - badge: - default_badges: - autobiographer: - name: - other: Autobiographer - desc: - other: Filled out profile information. - certified: - name: - other: Certified - desc: - other: Completed our new user tutorial. - editor: - name: - other: Editor - desc: - other: First post edit. - first_flag: - name: - other: First Flag - desc: - other: First flagged a post. - first_upvote: - name: - other: First Upvote - desc: - other: First up voted a post. - first_link: - name: - other: First Link - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: First Share - desc: - other: First shared a post. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Leave 5 comments. - new_user_of_the_month: - name: - other: New User of the Month - desc: - other: Contribuții restante în prima lor lună. - read_guidelines: - name: - other: Read Guidelines - desc: - other: Read the [community guidelines]. - reader: - name: - other: Reader - desc: - other: Read every answers in a topic with more than 10 answers. - welcome: - name: - other: Welcome - desc: - other: Received a up vote. - nice_share: - name: - other: Nice Share - desc: - other: Shared a post with 25 unique visitors. - good_share: - name: - other: Good Share - desc: - other: Shared a post with 300 unique visitors. - great_share: - name: - other: Distribuire grozavă - desc: - other: Shared a post with 1000 unique visitors. - out_of_love: - name: - other: Out of Love - desc: - other: Used 50 up votes in a day. - higher_love: - name: - other: Higher Love - desc: - other: Used 50 up votes in a day 5 times. - crazy_in_love: - name: - other: Crazy in Love - desc: - other: Used 50 up votes in a day 20 times. - promoter: - name: - other: Promoter - desc: - other: Invited a user. - campaigner: - name: - other: Campaigner - desc: - other: Invited 3 basic users. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: Thank You - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Active member for a year, posted at least once. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Cum se formatează - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Înapoi - next: Înainte - page_title: - question: Întrebare - questions: Întrebări - tag: Etichetă - tags: Etichete - tag_wiki: etichetă wiki - create_tag: Creați etichetă - edit_tag: Modificați eticheta - ask_a_question: Create Question - edit_question: Editați întrebarea - edit_answer: Editaţi răspunsul - search: Caută - posts_containing: Posturi care conțin - settings: Setări - notifications: Notificări - login: Conectează-te - sign_up: Înregistrează-te - account_recovery: Recuperarea contului - account_activation: Activare cont - confirm_email: Confirmare e-mail - account_suspended: Cont suspendat - admin: Administrator - change_email: Modifică E-mail - install: Instalează Answer - upgrade: Actualizare Answer - maintenance: Mentenanță website - users: Utilizatori - oauth_callback: Se procesează - http_404: Eroare HTTP 404 - http_50X: Eroare HTTP 500 - http_403: Eroare HTTP 403 - logout: Deconectare - posts: Posts - notifications: - title: Notificări - inbox: Mesaje primite - achievement: Realizări - new_alerts: Alerte noi - all_read: Marchează totul ca fiind citit - show_more: Arată mai mult - someone: Cineva - inbox_type: - all: Toate - posts: Postări - invites: Invitați - votes: Voturi - answer: Answer - question: Question - badge_award: Badge - suspended: - title: Contul dumneavoastră a fost suspendat - until_time: "Contul dumneavoastră a fost suspendat până la {{ time }}." - forever: Acest utilizator a fost suspendat pentru totdeauna. - end: Această întrebare nu corespunde cu ghidul comunității. - contact_us: Contactați-ne - editor: - blockquote: - text: Citat - bold: - text: Bolt - chart: - text: Diagramă - flow_chart: Diagrama fluxului - sequence_diagram: Diagrama secvenței - class_diagram: Diagrama clasei - state_diagram: Diagrama stării - entity_relationship_diagram: Diagrama relației entității - user_defined_diagram: Diagramă definită de utilizator - gantt_chart: Grafic Gantt - pie_chart: Grafic circular - code: - text: Exemplu de cod - add_code: Adaugă exemplu de cod - form: - fields: - code: - label: Cod - msg: - empty: Corpul mesajului trebuie să conțină text. - language: - label: Limbă - placeholder: Detectare automată - btn_cancel: Anulați - btn_confirm: Adaugă - formula: - text: Formulă - options: - inline: Formula inline - block: Formula blocului - heading: - text: Titlu - options: - h1: Titlu 1 - h2: Titlu 2 - h3: Titlu 3 - h4: Titlu 4 - h5: Titlu 5 - h6: Titlu 6 - help: - text: Ajutor - hr: - text: Linie orizontală - image: - text: Imagine - add_image: Adaugă imagine - tab_image: Incarca poza - form_image: - fields: - file: - label: Fișier imagine - btn: Selectați imaginea - msg: - empty: Fișierul nu poate fi gol. - only_image: Sunt permise doar fișierele imagine. - max_size: File size cannot exceed {{size}} MB. - desc: - label: Descriere - tab_url: URL-ul imaginii - form_url: - fields: - url: - label: URL-ul imaginii - msg: - empty: URL-ul imaginii nu poate fi gol. - name: - label: Descriere - btn_cancel: Anulați - btn_confirm: Adaugă - uploading: Se încarcă - indent: - text: Indentare - outdent: - text: Outdent - italic: - text: Accentuare - link: - text: Hyperlink - add_link: Adaugă hiperlink - form: - fields: - url: - label: URL - msg: - empty: URL-ul nu poate fi gol. - name: - label: Descriere - btn_cancel: Anulează - btn_confirm: Adaugă - ordered_list: - text: Listă numerotată - unordered_list: - text: Listă cu marcatori - table: - text: Tabelă - heading: Titlu - cell: Celulă - file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: Închid această postare ca... - btn_cancel: Anulează - btn_submit: Trimiteți - remark: - empty: Nu poate fi lăsat necompletat. - msg: - empty: Te rugăm să selectezi un motiv. - report_modal: - flag_title: Fac un semnal de alarmă pentru a raporta acest post ca... - close_title: Închid această postare ca... - review_question_title: Revizuiește întrebarea - review_answer_title: Revizuiește răspunsul - review_comment_title: Revizuiește comentariul - btn_cancel: Anulează - btn_submit: Trimiteți - remark: - empty: Nu poate fi lăsat necompletat. - msg: - empty: Te rugăm să selectezi un motiv. - not_a_url: URL format is incorrect. - url_not_match: URL origin does not match the current website. - tag_modal: - title: Creează o etichetă nouă - form: - fields: - display_name: - label: Nume afișat - msg: - empty: Numele afișat nu poate fi gol. - range: Nume afișat până la 35 de caractere. - slug_name: - label: Slug URL - desc: Slug-ul URL pana la 35 de caractere. - msg: - empty: Slug-ul URL nu poate fi gol. - range: Slug-ul URL pana la 35 de caractere. - character: URL-ul slug conţine un set de caractere nepermis. - desc: - label: Descriere - revision: - label: Versiunea - edit_summary: - label: Editează sumarul - placeholder: >- - Explicați pe scurt modificările (ortografie corectată, gramatică fixată, formatare îmbunătățită) - btn_cancel: Anulează - btn_submit: Trimiteți - btn_post: Postează o nouă etichetă - tag_info: - created_at: Creat - edited_at: Editat - history: Istoric - synonyms: - title: Sinonime - text: Următoarele etichete vor fi păstrate la - empty: Nu s-au găsit sinonime. - btn_add: Adaugă un sinonim - btn_edit: Editează - btn_save: Salvează - synonyms_text: Următoarele etichete vor rămâne la - delete: - title: Șterge această etichetă - tip_with_posts: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - tip_with_synonyms: >- -

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        - tip: Sunteţi sigur că doriţi să ştergeţi? - close: Închide - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Editează eticheta - default_reason: Editare etichetă - default_first_reason: Adaugă etichetă - btn_save_edits: Salvați modificările - btn_cancel: Anulați - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, AAAA [at] HH:mm" - now: acum - x_seconds_ago: "acum {{count}} sec" - x_minutes_ago: "acum {{count}} min" - x_hours_ago: "acum {{count}} ore" - hour: oră - day: zi - hours: ore - days: zile - month: month - months: months - year: year - reaction: - heart: heart - smile: smile - frown: frown - btn_label: add or remove reactions - undo_emoji: undo {{ emoji }} reaction - react_emoji: react with {{ emoji }} - unreact_emoji: unreact with {{ emoji }} - comment: - btn_add_comment: Adaugă comentariu - reply_to: Raspunde la - btn_reply: Răspunde - btn_edit: Editează - btn_delete: Ștergeți - btn_flag: Marcaj - btn_save_edits: Salvați modificările - btn_cancel: Anulați - show_more: "{{count}} alte comentarii" - tip_question: >- - Utilizați comentariile pentru a solicita mai multe informații sau pentru a sugera îmbunătățiri. Evitați răspunsul la întrebări în comentarii. - tip_answer: >- - Utilizați comentarii pentru a răspunde la alți utilizatori sau pentru a le notifica modificările. Dacă adăugați informații noi, editați postarea în loc să comentați. - tip_vote: Adaugă ceva util postării - edit_answer: - title: Editaţi răspunsul - default_reason: Editați răspunsul - default_first_reason: Adăugare răspuns - form: - fields: - revision: - label: Revizuire - answer: - label: Răspuns - feedback: - characters: conţinutul trebuie să aibă cel puţin 6 caractere. - edit_summary: - label: Editează sumarul - placeholder: >- - Explicați pe scurt modificările (ortografie corectată, gramatică fixă, formatare îmbunătățită) - btn_save_edits: Salvați modificările - btn_cancel: Anulează - tags: - title: Etichete - sort_buttons: - popular: Popular - name: Nume - newest: Cele mai noi - button_follow: Urmărește - button_following: Urmăriți - tag_label: întrebări - search_placeholder: Filtrare după numele etichetei - no_desc: Această echipă nu are o descriere. - more: Mai multe - wiki: Wiki - ask: - title: Create Question - edit_title: Editați întrebarea - default_reason: Editați întrebarea - default_first_reason: Create question - similar_questions: Întrebări similare - form: - fields: - revision: - label: Revizuire - title: - label: Titlu - placeholder: What's your topic? Be specific. - msg: - empty: Titlul nu poate fi gol. - range: Titlu de până la 150 de caractere - body: - label: Corp - msg: - empty: Corpul mesajului trebuie să conțină text. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Etichete - msg: - empty: Etichetele nu pot fi goale. - answer: - label: Răspuns - msg: - empty: Răspunsul nu poate fi gol. - edit_summary: - label: Editează sumarul - placeholder: >- - Explicați pe scurt modificările (ortografie corectată, gramatică fixă, formatare îmbunătățită) - btn_post_question: Postează întrebarea ta - btn_save_edits: Salvați modificările - answer_question: Răspundeți la propria întrebare - post_question&answer: Postează-ți întrebarea și răspunsul - tag_selector: - add_btn: Adaugă etichetă - create_btn: Creează o etichetă nouă - search_tag: Căutare etichetă - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: Nicio etichetă potrivită - tag_required_text: Etichetă necesară (cel puțin una) - header: - nav: - question: Întrebări - tag: Etichete - user: Utilizatori - badges: Badges - profile: Profil - setting: Setări - logout: Deconectaţi-vă - admin: Administrator - review: Recenzie - bookmark: Semne de carte - moderation: Moderare - search: - placeholder: Caută - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Schimbare - loading: încarcare... - pic_auth_code: - title: Captcha - placeholder: Introdu textul de mai sus - msg: - empty: Captcha nu poate fi gol. - inactive: - first: >- - Ești aproape gata! Am trimis un e-mail de activare la {{mail}}. Te rugăm să urmezi instrucțiunile din e-mail pentru a-ți activa contul. - info: "Dacă nu ajunge, verifică folderul Spam." - another: >- - Ți-am trimis un alt e-mail de activare la {{mail}}. Poate dura câteva minute până ajuns; asiguraţi-vă că verificaţi folderul Spam. - btn_name: Retrimitere link de activare - change_btn_name: Schimbați e-mailul - msg: - empty: Nu poate fi lăsat necompletat. - resend_email: - url_label: Sunteţi sigur că doriţi să retrimiteţi e-mailul de activare? - url_text: De asemenea, puteți da link-ul de activare de mai sus utilizatorului. - login: - login_to_continue: Conectează-te pentru a continua - info_sign: Nu ai un cont? Înregistrează-te - info_login: Ai deja un cont? <1>Autentifică-te - agreements: Prin înregistrare, ești de acord cu <1>politica de confidențialitate și <3>termenii și condițiile de utilizare. - forgot_pass: Ai uitat parola? - name: - label: Nume - msg: - empty: Câmpul Nume trebuie completat. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: E-mail - msg: - empty: Câmpul e-mail nu poate fi gol. - password: - label: Parolă - msg: - empty: Parola nu poate fi goală. - different: Parolele introduse pe ambele părți sunt incompatibile - account_forgot: - page_title: Ati uitat parola - btn_name: Trimite-mi e-mail de recuperare - send_success: >- - Dacă un cont corespunde cu {{mail}}, ar trebui să primiți un e-mail cu instrucțiuni despre cum să resetați parola în scurt timp. - email: - label: E-mail - msg: - empty: Câmpul e-mail nu poate fi gol. - change_email: - btn_cancel: Anulați - btn_update: Actualizare adresă de e-mail - send_success: >- - Dacă un cont corespunde cu {{mail}}, ar trebui să primiți un e-mail cu instrucțiuni despre cum să resetați parola în scurt timp. - email: - label: E-mail nou - msg: - empty: Câmpul e-mail nu poate fi gol. - oauth: - connect: Conectează-te cu {{ auth_name }} - remove: Elimină {{ auth_name }} - oauth_bind_email: - subtitle: Adăugați un e-mail de recuperare la contul dvs. - btn_update: Actualizare adresă de e-mail - email: - label: E-mail - msg: - empty: E-mail-ul nu poate fi gol. - modal_title: E-mail deja existent. - modal_content: Această adresă de e-mail este deja înregistrată. Sigur doriți să vă conectați la contul existent? - modal_cancel: Schimbați e-mailul - modal_confirm: Conectează-te la contul existent - password_reset: - page_title: Resetează parola - btn_name: Resetează-mi parola - reset_success: >- - Ați schimbat cu succes parola; veți fi redirecționat către pagina de conectare. - link_invalid: >- - Ne pare rău, acest link de resetare a parolei nu mai este valabil. Poate că parola este deja resetată? - to_login: Continuă autentificarea în pagină - password: - label: Parolă - msg: - empty: Parola nu poate fi goală. - length: Lungimea trebuie să fie între 8 și 32 - different: Parolele introduse pe ambele părți sunt incompatibile - password_confirm: - label: Confirmă parola nouă - settings: - page_title: Setări - goto_modify: Du-te pentru a modifica - nav: - profile: Profil - notification: Notificări - account: Cont - interface: Interfață - profile: - heading: Profil - btn_name: Salvează - display_name: - label: Nume afișat - msg: Numele afișat nu poate fi gol. - msg_range: Display name must be 2-30 characters in length. - username: - label: Nume de utilizator - caption: Oamenii te pot menționa ca "@utilizator". - msg: Numele de utilizator nu poate fi gol. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Imaginea de profil - gravatar: Gravatar - gravatar_text: Poți schimba imaginea pe - custom: Personalizat - custom_text: Poți să încarci imaginea. - default: Sistem - msg: Te rugăm să încarci un avatar - bio: - label: Despre mine - website: - label: Website - placeholder: "https://exemplu.com" - msg: Format incorect pentru website - location: - label: Locație - placeholder: "Oraş, Ţară" - notification: - heading: Notificări prin e-mail - turn_on: Pornire - inbox: - label: Notificări primite - description: Răspunde la întrebări, comentarii, invitații și multe altele. - all_new_question: - label: Adauga o intrebare noua - description: Primiți notificări despre toate întrebările noi. Până la 50 de întrebări pe săptămână. - all_new_question_for_following_tags: - label: Toate întrebările noi pentru etichetele următoare - description: Primiți notificări despre întrebări noi pentru următoarele etichete. - account: - heading: Cont - change_email_btn: Schimbați e-mailul - change_pass_btn: Schimbați parola - change_email_info: >- - Am trimis un e-mail la acea adresă. Vă rugăm să urmați instrucțiunile de confirmare. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - pass: - label: Parolă actuală - msg: Parola nu poate fi goală. - password_title: Parolă - current_pass: - label: Parola curentă - msg: - empty: Parola curentă nu poate fi goală. - length: Lungimea trebuie să fie între 8 și 32. - different: Cele două parole introduse nu se potrivesc. - new_pass: - label: Parola nouă - pass_confirm: - label: Confirmă parola nouă - interface: - heading: Interfață - lang: - label: Limba interfeței - text: Limba interfeței utilizatorului. Se va schimba atunci când se reîmprospătează pagina. - my_logins: - title: Autentificările mele - label: Autentifică-te sau înregistrează-te pe acest site folosind aceste conturi. - modal_title: Elimină autentificarea - modal_content: Sunteţi sigur că doriţi să eliminaţi această autentificare din contul dumneavoastră? - modal_confirm_btn: Eliminare - remove_success: Eliminată cu succes - toast: - update: actualizare reușită - update_password: Parola schimbata cu succes. - flag_success: Mulțumim pentru marcare. - forbidden_operate_self: Interzis să operezi singur - review: Revizuirea ta va arăta după recenzie. - sent_success: Trimis cu succes - related_question: - title: Related - answers: răspunsuri - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Persoane întrebate - desc: Invită persoane care crezi că știu răspunsul. - invite: Invită să răspundă - add: Adaugă persoane - search: Caută persoane - question_detail: - action: Acţiune - created: Created - Asked: Întrebat - asked: întrebat - update: Modificat - Edited: Edited - edit: editat - commented: commented - Views: Văzute - Follow: Urmărește - Following: Urmăriți - follow_tip: Urmărește această întrebare pentru a primi notificări - answered: răspunse - closed_in: Închis în - show_exist: Arată întrebarea existentă. - useful: Utilă - question_useful: Acest lucru este util și clar - question_un_useful: Nu este clar sau nu este util - question_bookmark: Marchează această întrebare - answer_useful: Este util - answer_un_useful: Nu este util - answers: - title: Răspunsuri - score: Scor - newest: Cele mai noi - oldest: Cel mai vechi - btn_accept: Acceptă - btn_accepted: Acceptă - write_answer: - title: Răspunsul tău - edit_answer: Editează răspunsul meu existent - btn_name: Postează răspunsul tău - add_another_answer: Adaugă un alt răspuns - confirm_title: Continuă să răspunzi - continue: Continuare - confirm_info: >- -

        Sunteţi sigur că doriţi să adăugaţi un alt răspuns?

        Puteţi folosi link-ul de editare pentru a perfecţiona şi îmbunătăţi răspunsul existent, în schimb.

        - empty: Răspunsul nu poate fi gol. - characters: conţinutul trebuie să aibă cel puţin 6 caractere. - tips: - header_1: Îți mulțumim pentru răspuns - li1_1: Asigurați-vă că răspundeți la întrebarea. Furnizați detalii și împărtășiți cercetările dvs. - li1_2: Faceți o copie de rezervă cu referințe sau experiență personală. - header_2: Dar evită... - li2_1: Solicită ajutor, caută clarificări sau răspunsuri la alte răspunsuri. - reopen: - confirm_btn: Redeschide - title: Redeschide această postare - content: Sunteţi sigur că doriţi să redeschideţi? - list: - confirm_btn: List - title: List this post - content: Are you sure you want to list? - unlist: - confirm_btn: Unlist - title: Unlist this post - content: Are you sure you want to unlist? - pin: - title: Fixează această postare - content: Sunteţi sigur că doriţi să fixaţi la nivel global? Acest post va apărea în partea de sus a tuturor listelor de postări. - confirm_btn: Fixează - delete: - title: Șterge această postare - question: >- - Nu recomandăm ștergerea întrebărilor cu răspunsuri deoarece acest lucru privează viitorii cititori de aceste cunoștințe.

        Ștergerea repetată a întrebărilor cu răspuns poate duce la blocarea contului dvs. de a întreba. Sigur doriți să ștergeți? - answer_accepted: >- -

        Nu recomandăm ștergerea răspunsului acceptat deoarece acest lucru privează viitorii cititori de aceste cunoștințe.

        Ștergerea repetată a răspunsurilor acceptate poate duce la blocarea contului dvs. de a răspunde. Sigur doriți să ștergeți? - other: Sunteţi sigur că doriţi să ştergeţi? - tip_answer_deleted: Aceasta postare a fost stearsa - undelete_title: Anulează ștergerea acestei postări - undelete_desc: Sunteți sigur că doriți să adulați ștergerea? - btns: - confirm: Confirmați - cancel: Anulați - edit: Editează - save: Salvează - delete: Ștergeți - undelete: Restabilește - list: List - unlist: Unlist - unlisted: Unlisted - login: Autentifică-te - signup: Înscrieți-vă - logout: Deconectaţi-vă - verify: Verificare - create: Create - approve: Aprobă - reject: Respins - skip: Treci peste - discard_draft: Respingeți draftul - pinned: Fixat - all: Toate - question: Întrebare - answer: Răspuns - comment: Comentariu - refresh: Actualizare - resend: Retrimite - deactivate: Dezactivare - active: Activați - suspend: Suspendați - unsuspend: Anulează suspendare - close: Închide - reopen: Redeschide - ok: OK - light: Luminoasă - dark: Întunecată - system_setting: Setări de sistem - default: Default - reset: Resetează - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignore - submit: Submit - normal: Normal - closed: Closed - deleted: Deleted - deleted_permanently: Deleted permanently - pending: Pending - more: More - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Rezultatele căutării - keywords: Cuvinte cheie - options: Opţiuni - follow: Urmărește - following: Urmăriți - counts: "{{count}} rezultatele" - counts_loading: "... Results" - more: Mai mult - sort_btns: - relevance: Relevanță - newest: Cele mai noi - active: Activ - score: Scor - more: Mai mult - tips: - title: Sfaturi de căutare avansate - tag: "<1>[tag] search with a tag" - user: "<1>utilizator:username căutare de către autor" - answer: "<1>răspunsuri:0 întrebări fără răspuns" - score: "<1>scor:3 postări cu un scor de 3+" - question: "<1>este:question întrebări de căutare" - is_answer: "<1>este:răspuner răspunsuri la căutare" - empty: Nu am putut găsi nimic.
        Încearcă cuvinte cheie diferite sau mai puţin specifice. - share: - name: Distribuiți - copy: Copiază linkul - via: Distribuie postarea prin... - copied: Copiat - facebook: Partajează pe Facebook - twitter: Share to X - cannot_vote_for_self: Nu poți vota pentru propria ta postare. - modal_confirm: - title: Eroare... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Noul tău cont este confirmat; vei fi redirecționat către pagina de pornire. - link: Continuă la pagina principală - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: E-mailul dvs. a fost actualizat. - confirm_new_email_invalid: >- - Ne pare rău, acest link de confirmare nu mai este valabil. Poate că e-mailul dvs. a fost deja modificat? - unsubscribe: - page_title: Dezabonează-te - success_title: Dezabonare cu succes - success_desc: Ați fost eliminat cu succes din această listă de abonați și nu veți mai primi alte e-mailuri de la noi. - link: Modificați setările - question: - following_tags: Etichete urmărite - edit: Editează - save: Salvează - follow_tag_tip: Urmărește etichetele pentru a curăța lista ta de întrebări. - hot_questions: Întrebări importante - all_questions: Toate întrebările - x_questions: "{{ count }} Întrebări" - x_answers: "{{ count }} răspunsuri" - x_posts: "{{ count }} Posts" - questions: Întrebări - answers: Răspunsuri - newest: Cele mai noi - active: Activ - hot: Hot - frequent: Frequent - recommend: Recommend - score: Scor - unanswered: Fără răspuns - modified: modificat - answered: răspunse - asked: întrebat - closed: închise - follow_a_tag: Urmărește o etichetă - more: Mai multe - personal: - overview: Privire de ansamblu - answers: Răspunsuri - answer: răspuns - questions: Întrebări - question: întrebare - bookmarks: Semne de carte - reputation: Reputație - comments: Comentarii - votes: Voturi - badges: Badges - newest: Cele mai noi - score: Scor - edit_profile: Editare profil - visited_x_days: "{{ count }} zile vizitate" - viewed: Văzute - joined: Înscris - comma: "," - last_login: Văzut - about_me: Despre mine - about_me_empty: "// Salut, Lumea !" - top_answers: Top răspunsuri - top_questions: Top Intrebari - stats: Statistici - list_empty: Nici o postare găsită.
        Poate doriţi să selectaţi o filă diferită? - content_empty: No posts found. - accepted: Acceptat - answered: răspunse - asked: întrebat - downvoted: vot negativ - mod_short: MOD - mod_long: Moderatori - x_reputation: reputație - x_votes: voturi primite - x_answers: răspunsuri - x_questions: întrebări - recent_badges: Recent Badges - install: - title: Installation - next: Înainte - done: Finalizat - config_yaml_error: Nu se poate crea fișierul config.yaml. - lang: - label: Vă rugăm să selectați limba - db_type: - label: Motorul Bazei de Date - db_username: - label: Nume de utilizator - placeholder: root - msg: Numele de utilizator nu poate fi gol. - db_password: - label: Parolă - placeholder: root - msg: Parola nu poate fi goală. - db_host: - label: Numele serverului de baze de date - placeholder: "db:3306" - msg: Adresa bazei de date nu poate fi goală. - db_name: - label: Numele bazei de date - placeholder: răspuns - msg: Numele bazei de date nu poate fi gol. - db_file: - label: Fișierul bazei de date - placeholder: /data/answer.db - msg: Fişierul bazei de date nu poate fi gol. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Crează config.yaml - label: Fișierul config.yaml a fost creat. - desc: >- - Puteți crea fișierul <1>config.yaml manual în directorul <1>/var/wwww/xxx/ și inserați următorul text în el. - info: După ce ai făcut asta, apasă butonul "Înainte". - site_information: Informatii site - admin_account: Contul de admin - site_name: - label: Numele site-ului - msg: Numele site-ului nu poate fi gol. - msg_max_length: Numele site-ului trebuie să aibă maximum 30 de caractere lungime. - site_url: - label: URL-ul site-ului - text: Adresa site-ului dvs. - msg: - empty: URL-ul site-ului nu poate fi gol. - incorrect: Format incorect pentru URL-ul site-ului. - max_length: URL-ul site-ului trebuie să aibă maximum 512 caractere lungime. - contact_email: - label: E-mail de contact - text: Adresa de e-mail a persoanei cheie responsabile pentru acest site. - msg: - empty: E-mailul de contact nu poate fi gol. - incorrect: E-mail de contact are un format incorect. - login_required: - label: Privat - switch: Autentificare necesară - text: Numai utilizatorii autentificați pot accesa această comunitate. - admin_name: - label: Nume - msg: Câmpul Nume trebuie completat. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Parolă - text: >- - Veți avea nevoie de această parolă pentru autentificare. Vă rugăm să o păstrați într-o locație sigură. - msg: Parola nu poate fi goală. - msg_min_length: Parola trebuie să aibă cel puțin 8 caractere. - msg_max_length: Parola trebuie să aibă cel puțin 32 caractere. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: E-mail - text: Veţi avea nevoie de acest e-mail pentru a vă autentifica. - msg: - empty: Câmpul e-mail nu poate fi gol. - incorrect: Campul e-mail are formatul incorect. - ready_title: Your site is ready - ready_desc: >- - Dacă te simți vreodată ca și cum ai schimba mai multe setări, vizitează <1>secțiunea de administrare ; găsește-o în meniul site-ului. - good_luck: "Distracție plăcută și noroc!" - warn_title: Atenţie - warn_desc: >- - Fișierul <1>config.yaml există deja. Dacă trebuie să resetați oricare dintre elementele de configurare din acest fișier, vă rugăm să îl ștergeți mai întâi. - install_now: Puteți încerca <1>să instalați acum. - installed: Deja instalat - installed_desc: >- - Se pare că ai instalat deja. Pentru a reinstala vă rugăm să ștergeți mai întâi vechile tabele ale bazei de date. - db_failed: Conexiunea la baza de date a eșuat - db_failed_desc: >- - Acest lucru înseamnă fie că baza de date este în configurația ta <1>. config yaml este incorect sau contactul cu serverul bazei de date nu a putut fi stabilit. Acest lucru ar putea însemna că serverul gazdei nu este în funcțiune. - counts: - views: vizualizări - votes: voturi - answers: răspunsuri - accepted: Acceptat - page_error: - http_error: HTTP - {{ code }} - desc_403: Nu ai permisiunea să accesezi pagina. - desc_404: Din păcate, această pagină nu există. - desc_50X: Serverul a întâmpinat o eroare și nu a putut finaliza cererea. - back_home: Înapoi la pagina principală - page_maintenance: - desc: "Suntem în mentenanță, ne vom întoarce în curând." - nav_menus: - dashboard: Panou de control - contents: Conţinut - questions: Întrebări - answers: Răspunsuri - users: Utilizatori - badges: Badges - flags: Marcaj - settings: Setări - general: General - interface: Interfață - smtp: SMTP - branding: Marcă - legal: Juridic - write: Scrie - terms: Terms - tos: Condiții de utilizare - privacy: Confidențialitate - seo: SEO - customize: Personalizează - themes: Teme - login: Autentifică-te - privileges: Privilegii - plugins: Extensii - installed_plugins: Extensii instalate - apperance: Appearance - website_welcome: Bun venit la {{site_name}} - user_center: - login: Autentifică-te - qrcode_login_tip: Vă rugăm să folosiți {{ agentName }} pentru a scana codul QR și a vă autentifica. - login_failed_email_tip: Autentificare eșuată. Vă rugăm să permiteți acestei aplicații să vă acceseze informațiile de e-mail înainte de a încerca din nou. - badges: - modal: - title: Congratulations - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - admin: - admin_header: - title: Administrator - dashboard: - title: Panou de control - welcome: Welcome to Admin! - site_statistics: Statisticile site-ului - questions: "Întrebări:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "Răspunsuri:" - comments: "Comentarii:" - votes: "Voturi:" - users: "Utilizatori:" - flags: "Marcaje:" - reviews: "Reviews:" - site_health: Site health - version: "Versiune:" - https: "HTTPS:" - upload_folder: "Director încărcare:" - run_mode: "Modul de rulare:" - private: Privat - public: Public - smtp: "SMTP:" - timezone: "Fusul orar:" - system_info: Informaţii despre sistem - go_version: "Versiune Go:" - database: "Baza de date:" - database_size: "Dimensiune bază de date:" - storage_used: "Spațiu utilizat:" - uptime: "Timpul de funcționare:" - links: Links - plugins: Pluginuri - github: GitHub - blog: Blog - contact: Contact - forum: Forum - documents: Ducumente - feedback: Feedback - support: Suport - review: Recenzie - config: Configurație - update_to: Actualizare la - latest: Recente - check_failed: Verificarea eșuată - "yes": "Da" - "no": "Nu" - not_allowed: Nu este permis - allowed: Permis - enabled: Activat - disabled: Dezactivat - writable: Inscriptibil - not_writable: Neinscriptibil - flags: - title: Steaguri - pending: În așteptare - completed: Finalizată - flagged: Semnalizat - flagged_type: Marcat {{ type }} - created: Creată - action: Actiune - review: Recenzie - user_role_modal: - title: Schimbă rolul utilizatorului la... - btn_cancel: Anulați - btn_submit: Trimiteți - new_password_modal: - title: Setați parola nouă - form: - fields: - password: - label: Parolă - text: Utilizatorul va fi deconectat și trebuie să se conecteze din nou. - msg: Parola trebuie să aibă o lungime de 8-32 caractere. - btn_cancel: Anulați - btn_submit: Trimiteți - edit_profile_modal: - title: Edit profile - form: - fields: - display_name: - label: Display name - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Invalid Email Address. - edit_success: Edited successfully - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Adaugă un nou utilizator - form: - fields: - users: - label: Adăugare utilizator în bloc - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separați “nume, email, parola” cu virgulă. Un utilizator pe linie. - msg: "Te rugăm să introduci e-mailul utilizatorului, câte unul pe linie." - display_name: - label: Nume afișat - msg: Display name must be 2-30 characters in length. - email: - label: E-mail - msg: E-mail nu este validă. - password: - label: Parolă - msg: Parola trebuie să aibă o lungime de 8-32 caractere. - btn_cancel: Anulați - btn_submit: Trimiteți - users: - title: Utilizatori - name: Nume - email: E-mail - reputation: Reputație - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Stare - role: Rol - action: Acţiune - change: Schimbare - all: Toate - staff: Personal - more: Mai mult - inactive: Inactiv - suspended: Suspendat - deleted: Şters - normal: Normal - Moderator: Moderator - Admin: Administrator - User: Utilizator - filter: - placeholder: "Filtrare după nume, utilizator:id" - set_new_password: Setați parola nouă - edit_profile: Edit profile - change_status: Schimba starea - change_role: Schimbare rol - show_logs: Arată jurnalele - add_user: Adaugă utilizator - deactivate_user: - title: Dezactivare utilizator - content: Un utilizator inactiv trebuie să își revalideze e-mailul. - delete_user: - title: Ștergeți acest utilizator - content: Sunteţi sigur că doriţi să ştergeţi acest utilizator? Acest lucru este permanent! - remove: Eliminaţi acest conţinut - label: Elimină toate întrebările, răspunsurile, comentariile etc. - text: Nu bifați acest lucru dacă doriți să ștergeți doar contul utilizatorului. - suspend_user: - title: Suspendă acest utilizator - content: Un utilizator suspendat nu se poate autentifica. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Întrebări - unlisted: Unlisted - post: Postare - votes: Voturi - answers: Răspunsuri - created: Creată - status: Stare - action: Actiune - change: Schimbare - pending: În așteptare - filter: - placeholder: "Filtrează după titlu, întrebare: id" - answers: - page_title: Răspunsuri - post: Postare - votes: Voturi - created: Creată - status: Stare - action: Acţiune - change: Schimbare - filter: - placeholder: "Filtrează după titlu, întrebare: id" - general: - page_title: General - name: - label: Numele site-ului - msg: Numele site-ului nu poate fi gol. - text: "Numele acestui site, așa cum este folosit în eticheta de titlu." - site_url: - label: URL-ul site-ului - msg: Url-ul site-ului nu poate fi gol. - validate: Introduceți un URL valid. - text: Adresa site-ului dvs. - short_desc: - label: Scurtă descriere a site-ului - msg: Scurtă descriere a site-ului nu poate fi goală. - text: "Scurtă descriere, așa cum este folosit în eticheta titlu pe website." - desc: - label: Descriere site - msg: Descrierea site-ului nu poate fi goală. - text: "Descrie acest site într-o propoziție, așa cum este folosit în tag-ul meta descriere." - contact_email: - label: E-mail de contact - msg: E-mailul de contact nu poate fi gol. - validate: E-mailul de contact nu este valid. - text: Adresa de e-mail a persoanei cheie responsabile pentru acest site. - check_update: - label: Software updates - text: Automatically check for updates - interface: - page_title: Interfață - language: - label: Limba interfeței - msg: Limba interfata nu poate fi goala. - text: Limba interfeței utilizatorului. Se va schimba atunci când se reîmprospătează pagina. - time_zone: - label: Fusul orar - msg: Fusul orar nu poate fi gol. - text: Alege un oraș în același fus orar cu tine. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: De la e-mail - msg: Câmpul e-mail nu poate fi gol. - text: Adresa de e-mail de la care e-mailurile sunt trimise. - from_name: - label: Din numele - msg: Numele nu poate fi gol. - text: Numele de la care sunt trimise e-mailurile. - smtp_host: - label: Gazda SMTP - msg: Gazda SMTP nu poate fi goală. - text: Serverul tau de mail. - encryption: - label: Criptare - msg: Câmpul decriptare nu poate fi gol. - text: Pentru majoritatea serverelor SSL este opțiunea recomandată. - ssl: SSL - tls: TLS - none: Niciuna - smtp_port: - label: Portul SMTP - msg: Portul SMTP trebuie să fie numărul 1 ~ 65535. - text: Portul către serverul de mail. - smtp_username: - label: Utilizatorul SMTP - msg: Numele de utilizator SMTP nu poate fi gol. - smtp_password: - label: Parola SMTP - msg: Parola SMTP nu poate fi goală. - test_email_recipient: - label: Destinatari de e-mail test - text: Furnizați adresa de e-mail care va primi trimiterile de teste. - msg: Destinatarii de e-mail de test sunt invalizi - smtp_authentication: - label: Activare Authenticator - title: Autentificare SMTP - msg: Autentificarea SMTP nu poate fi goală. - "yes": "Da" - "no": "Nu" - branding: - page_title: Marcă - logo: - label: Logo - msg: Logo-ul nu poate fi gol. - text: Imaginea logo-ului din stânga sus a site-ului dvs. Utilizaţi o imagine dreptunghiulară largă cu o înălţime de 56 şi un raport de aspect mai mare de 3:1. Dacă nu se completează, textul pentru titlul site-ului va fi afișat. - mobile_logo: - label: Logo mobil - text: Logo-ul folosit pe versiunea mobila a site-ului dvs. Utilizați o imagine dreptunghiulară largă cu o înălțime de 56. Dacă nu o completați, va fi utilizată imaginea din setarea "logo". - square_icon: - label: Pictogramă pătrată - msg: Pictograma pătrată nu poate fi goală. - text: Imaginea folosită ca bază pentru pictogramele de metadate. Ar trebui să fie, în mod ideal, mai mare de 512x512. - favicon: - label: Favicon - text: O pictogramă favorită pentru site-ul dvs. Pentru a lucra corect peste un CDN trebuie să fie un png. Va fi redimensionată la 32x32. Dacă este lăsat necompletat, va fi folosită "iconiță pătrată". - legal: - page_title: Juridic - terms_of_service: - label: Termeni și condiții - text: "Puteți adăuga aici termeni de conținut pentru serviciu. Dacă aveți deja un document găzduit în altă parte, furnizați URL-ul complet aici." - privacy_policy: - label: Politică de confidențialitate - text: "Puteți adăuga aici termeni politicii de confidențialitate. Dacă aveți deja un document găzduit în altă parte, furnizați URL-ul complet aici." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Scrie - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Fiecare utilizator poate scrie doar câte un răspuns pentru fiecare întrebare - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Etichete recomandate - text: "Recommend tags will show in the dropdown list by default." - msg: - contain_reserved: "recommended tags cannot contain reserved tags" - required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags - text: "Fiecare întrebare nouă trebuie să aibă cel puțin o etichetă recomandată." - reserved_tags: - label: Etichete rezervate - text: "Reserved tags can only be used by moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: SEO - permalink: - label: Legătură permanenta - text: Structurile URL personalizate pot îmbunătăți capacitatea de utilizare și compatibilitatea link-urilor tale. - robots: - label: robots.txt - text: Acest lucru va suprascrie permanent orice setări ale site-ului. - themes: - page_title: Teme - themes: - label: Teme - text: Selectaţi o temă existentă. - color_scheme: - label: Paletă de culori - navbar_style: - label: Navbar background style - primary_color: - label: Culoare primară - text: Modifică culorile folosite de temele tale - css_and_html: - page_title: CSS și HTML - custom_css: - label: CSS personalizat - text: > - - head: - label: Cap - text: > - - header: - label: Antet - text: > - - footer: - label: Subsol - text: Se va insera înainte de </body>. - sidebar: - label: Bară laterală - text: Acesta va fi inserat în bara laterală. - login: - page_title: Autentifică-te - membership: - title: Calitatea de membru - label: Permite înregistrări noi - text: Dezactivați pentru a împiedica pe oricine să creeze un cont nou. - email_registration: - title: Înregistrare e-mail - label: Permite înregistrări noi - text: Dezactivați pentru a preveni crearea unui cont nou prin e-mail. - allowed_email_domains: - title: Domenii de e-mail permise - text: Domeniile de e-mail cu care utilizatorii trebuie să înregistreze conturi. Un domeniu pe linie. Se ignoră atunci când este gol. - private: - title: Privat - label: Autentificare necesară - text: Numai utilizatorii autentificați pot accesa această comunitate. - password_login: - title: Parola de login - label: Permiteți autentificarea prin e-mail și parolă - text: "AVERTISMENT: Dacă opriți, este posibil să nu vă puteți conecta dacă nu ați configurat anterior o altă metodă de autentificare." - installed_plugins: - title: Extensii instalate - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. - filter: - all: Toate - active: Activ - inactive: Inactiv - outdated: Învechit - plugins: - label: Extensii - text: Selectați un plugin existent. - name: Nume - version: Versiune - status: Stare - action: Acţiune - deactivate: Dezactivare - activate: Activare - settings: Setări - settings_users: - title: Utilizatori - avatar: - label: Avatarul implicit - text: Pentru utilizatorii fără un avatar personalizat propriu. - gravatar_base_url: - label: URL de bază Gravatar - text: URL-ul bazei API a furnizorului de Gravatar. Ignorat când este gol. - profile_editable: - title: Profil editabil - allow_update_display_name: - label: Permite utilizatorilor să își schimbe numele afișat - allow_update_username: - label: Permite utilizatorilor să își schimbe numele de utilizator - allow_update_avatar: - label: Permite utilizatorilor să își schimbe imaginea de profil - allow_update_bio: - label: Permite utilizatorilor să își schimbe propriul lor despre mine - allow_update_website: - label: Permite utilizatorilor să îşi schimbe website-ul - allow_update_location: - label: Permite utilizatorilor să își schimbe locația - privilege: - title: Privilegii - level: - label: Nivel necesar de reputație - text: Alegeți reputația necesară pentru privilegii - msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 - badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate - filter: - placeholder: Filter by name, badge:id - group: Group - inactive: Inactive - name: Name - show_logs: Show logs - status: Status - title: Badges - form: - optional: (opțional) - empty: nu poate fi lăsat necompletat - invalid: nu este valid - btn_submit: Salvează - not_found_props: "Proprietatea solicitată {{ key }} nu a fost găsită." - select: Selectează - page_review: - review: Recenzie - proposed: propus - question_edit: Editare întrebări - answer_edit: Editările răspunsului - tag_edit: Editare etichetă - edit_summary: Editează sumarul - edit_question: Editați întrebarea - edit_answer: Editați răspunsul - edit_tag: Editare etichetă - empty: Nu au mai rămas sarcini de evaluare. - approve_revision_tip: Do you approve this revision? - approve_flag_tip: Do you approve this flag? - approve_post_tip: Do you approve this post? - approve_user_tip: Do you approve this user? - suggest_edits: Suggested edits - flag_post: Flag post - flag_user: Flag user - queued_post: Queued post - queued_user: Queued user - filter_label: Tip - reputation: reputation - flag_post_type: Acest post a fost marcat de {{ type }}. - flag_user_type: Flagged this user as {{ type }}. - edit_post: Editează postarea - list_post: Listează postarea - unlist_post: Unlist post - timeline: - undeleted: restabilește - deleted: şterse - downvote: vot negativ - upvote: vot pozitiv - accept: acceptat - cancelled: anulat - commented: comentat - rollback: revenire - edited: editat - answered: răspunse - asked: întrebat - closed: închise - reopened: redeschise - created: creat - pin: fixat - unpin: nefixat - show: listă - hide: nelistat - title: "Istoric pentru" - tag_title: "Cronologie pentru" - show_votes: "Afișare voturi" - n_or_a: N/A - title_for_question: "Cronologie pentru" - title_for_answer: "Calendarul răspunsului la {{ title }} cu {{ author }}" - title_for_tag: "Cronologie pentru etichetă" - datetime: Dată și oră - type: Tip - by: De către - comment: Comentariu - no_data: "Nu a fost găsit nimic." - users: - title: Utilizatori - users_with_the_most_reputation: Utilizatori cu cele mai mari scoruri ale reputaţiei în această săptămână - users_with_the_most_vote: Utilizatorii care au votat cel mai mult săptămâna aceasta - staffs: Personalul acestei comunități - reputation: reputație - votes: voturi - prompt: - leave_page: Sunteți sigur că doriți să ieșiți din pagina asta? - changes_not_save: Modificările nu pot fi salvate. - draft: - discard_confirm: Ești sigur că vrei să renunți la ciornă? - messages: - post_deleted: Această postare a fost ștearsă. - post_cancel_deleted: This post has been undeleted. - post_pin: Această postare a fost fixată. - post_unpin: Această postare nu a fost fixată. - post_hide_list: Această postare a fost ascunsă din listă. - post_show_list: Această postare a fost afișată în listă. - post_reopen: Această postare a fost redeschisă. - post_list: This post has been listed. - post_unlist: This post has been unlisted. - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/ru_RU.yaml b/data/i18n/ru_RU.yaml deleted file mode 100644 index e181656f4..000000000 --- a/data/i18n/ru_RU.yaml +++ /dev/null @@ -1,2360 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Выполнено. - unknown: - other: Неизвестная ошибка. - request_format_error: - other: Формат файла не корректен. - unauthorized_error: - other: Авторизация не выполнена. - database_error: - other: Ошибка сервера данных. - forbidden_error: - other: Доступ запрещен. - duplicate_request_error: - other: Дублирующая отправка. - action: - report: - other: Пожаловаться - edit: - other: Редактировать - delete: - other: Удалить - close: - other: Закрыть - reopen: - other: Открыть - forbidden_error: - other: Доступ запрещен. - pin: - other: Закрепить - hide: - other: Убрать - unpin: - other: Открепить - show: - other: Список - invite_someone_to_answer: - other: Редактировать - undelete: - other: Отменить удаление - merge: - other: Merge - role: - name: - user: - other: Пользователь - admin: - other: Администратор - moderator: - other: Модератор - description: - user: - other: По умолчанию, без специального доступа. - admin: - other: Имейте все полномочия для доступа к сайту. - moderator: - other: Имеет доступ ко всем сообщениям, кроме настроек администратора. - privilege: - level_1: - description: - other: Уровень 1 (для приватной команды, группы требуется наименьшая репутация) - level_2: - description: - other: Уровень 2 (для стартапа достаточен низкий уровень репутации) - level_3: - description: - other: Уровень 3 (для зрелого сообщества требуется высокая репутация) - level_custom: - description: - other: Настраиваемый уровень - rank_question_add_label: - other: Задать вопрос - rank_answer_add_label: - other: Написать ответ - rank_comment_add_label: - other: Написать комментарий - rank_report_add_label: - other: Пожаловаться - rank_comment_vote_up_label: - other: Полезный комментарий - rank_link_url_limit_label: - other: Опубликовать более 2 ссылок за раз - rank_question_vote_up_label: - other: Полезный вопрос - rank_answer_vote_up_label: - other: Полезный ответ - rank_question_vote_down_label: - other: Бесполезный вопрос - rank_answer_vote_down_label: - other: Бесполезный ответ - rank_invite_someone_to_answer_label: - other: Пригласить кого-нибудь ответить - rank_tag_add_label: - other: Новый тег - rank_tag_edit_label: - other: Редактировать описание тега (требуется проверка) - rank_question_edit_label: - other: Редактировать вопрос другого пользователя (требуется проверка) - rank_answer_edit_label: - other: Редактировать ответ другого пользователя (требуется проверка) - rank_question_edit_without_review_label: - other: Редактировать вопрос другого пользователя без проверки - rank_answer_edit_without_review_label: - other: Редактировать ответ другого пользователя без проверки - rank_question_audit_label: - other: Проверить изменения вопроса - rank_answer_audit_label: - other: Проверить изменения ответа - rank_tag_audit_label: - other: Проверить изменения тегов - rank_tag_edit_without_review_label: - other: Редактировать описание тега без проверки - rank_tag_synonym_label: - other: Управлять синонимами тегов - email: - other: Эл. почта - e_mail: - other: Почта - password: - other: Пароль - pass: - other: Пароль - old_pass: - other: Current password - original_text: - other: Это сообщение - email_or_password_wrong_error: - other: Неверное имя пользователя или пароль. - error: - common: - invalid_url: - other: Неверная URL. - status_invalid: - other: Неверный статус. - password: - space_invalid: - other: Пароль не должен содержать пробелы. - admin: - cannot_update_their_password: - other: Вы не можете изменить свой пароль. - cannot_edit_their_profile: - other: Вы не можете изменять свой профиль. - cannot_modify_self_status: - other: Вы не можете изменить свой статус. - email_or_password_wrong: - other: Неверное имя пользователя или пароль. - answer: - not_found: - other: Ответ не найден. - cannot_deleted: - other: Недостаточно прав для удаления. - cannot_update: - other: Нет прав для обновления. - question_closed_cannot_add: - other: Вопросы закрыты и не могут быть добавлены. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Комментарий не может редактироваться. - not_found: - other: Комментарий не найден. - cannot_edit_after_deadline: - other: Невозможно редактировать комментарий из-за того, что он был создан слишком давно. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: Адрес электронной почты уже существует. - need_to_be_verified: - other: Адрес электронной почты должен быть подтвержден. - verify_url_expired: - other: Срок действия подтверждённого адреса электронной почты истек, пожалуйста, отправьте письмо повторно. - illegal_email_domain_error: - other: Невозможно использовать email с этим доменом. Пожалуйста, используйте другой. - lang: - not_found: - other: Языковой файл не найден. - object: - captcha_verification_failed: - other: Captcha введена неверно. - disallow_follow: - other: Вы не можете подписаться. - disallow_vote: - other: Вы не можете голосовать. - disallow_vote_your_self: - other: Вы не можете голосовать за собственный отзыв. - not_found: - other: Объект не найден. - verification_failed: - other: Проверка не удалась. - email_or_password_incorrect: - other: Email или пароль не совпадают. - old_password_verification_failed: - other: Не удалось подтвердить старый пароль - new_password_same_as_previous_setting: - other: Пароль не может быть таким же как прежний. - already_deleted: - other: Этот пост был удален. - meta: - object_not_found: - other: Объект мета не найден - question: - already_deleted: - other: Этот пост был удалён. - under_review: - other: Ваш пост ожидает проверки. Он станет видимым после одобрения. - not_found: - other: Вопрос не найден. - cannot_deleted: - other: Недостаточно прав для удаления. - cannot_close: - other: Нет разрешения на закрытие. - cannot_update: - other: Нет разрешения на обновление. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Ранг репутации не соответствует условию. - vote_fail_to_meet_the_condition: - other: Спасибо за отзыв. Вам нужно как минимум {{.Rank}} репутация для голосования. - no_enough_rank_to_operate: - other: Для этого вам нужна репутация {{.Rank}}. - report: - handle_failed: - other: Не удалось обработать отчет. - not_found: - other: Отчет не найден. - tag: - already_exist: - other: Тег уже существует. - not_found: - other: Тег не найден. - recommend_tag_not_found: - other: Рекомендуемый тег не существует. - recommend_tag_enter: - other: Пожалуйста, введите хотя бы один тег. - not_contain_synonym_tags: - other: Не должно содержать теги синонимы. - cannot_update: - other: Нет прав для обновления. - is_used_cannot_delete: - other: Вы не можете удалить метку, которая используется. - cannot_set_synonym_as_itself: - other: Вы не можете установить синоним текущего тега. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: Поле отправителя не может содержать email адрес. - theme: - not_found: - other: Тема не найдена. - revision: - review_underway: - other: В настоящее время не удается редактировать версию, в очереди на проверку. - no_permission: - other: Разрешения на пересмотр нет. - user: - external_login_missing_user_id: - other: Сторонняя платформа не предоставляет уникальный идентификатор пользователя, поэтому вы не можете войти в систему, пожалуйста, свяжитесь с администратором веб-сайта. - external_login_unbinding_forbidden: - other: Пожалуйста, установите пароль для входа в свою учетную запись, прежде чем удалять этот логин. - email_or_password_wrong: - other: - other: Почта и пароль введены неправильно. - not_found: - other: Пользователь не найден. - suspended: - other: Пользователь был заблокирован. - username_invalid: - other: Недопустимое имя пользователя. - username_duplicate: - other: Имя пользователя уже используется. - set_avatar: - other: Не удалось установить аватар. - cannot_update_your_role: - other: Вы не можете изменить свою роль. - not_allowed_registration: - other: В данный момент регистрация на сайте выключена. - not_allowed_login_via_password: - other: В настоящее время вход на сайт по паролю отключен. - access_denied: - other: Доступ запрещен - page_access_denied: - other: У вас нет доступа к этой странице. - add_bulk_users_format_error: - other: "Ошибка формата {{.Field}} рядом с '{{.Content}}' в строке {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "Количество пользователей, которое Вы добавляете, должно быть в промежутке от 1 до {{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Не удалось прочитать конфигурацию - database: - connection_failed: - other: Ошибка подключения к базе данных - create_table_failed: - other: Не удалось создать таблицу - install: - create_config_failed: - other: Не удалось создать файл config.yaml. - upload: - unsupported_file_format: - other: Неподдерживаемый формат файла. - site_info: - config_not_found: - other: Конфигурация сайта не найдена. - badge: - object_not_found: - other: Объект бейджа не найден - reason: - spam: - name: - other: Спам - desc: - other: Этот пост является рекламой или вандализмом. Он не полезен и не имеет отношения к текущей теме. - rude_or_abusive: - name: - other: Грубость или оскорбления - desc: - other: "Человек может посчитать такое содержимое неподходящим для уважительной беседы." - a_duplicate: - name: - other: дубликат - desc: - other: Этот вопрос уже был задан, и на него уже был получен ответ. - placeholder: - other: Введите существующую ссылку на вопрос - not_a_answer: - name: - other: это не ответ - desc: - other: "Это сообщение было опубликовано в качестве ответа, но оно не пытается ответить на вопрос. Возможно, оно должно быть отредактировано, дополнено, быть другим вопросом или удалено навсегда." - no_longer_needed: - name: - other: Не актуально - desc: - other: Этот комментарий устарел, носит разговорный характер или не имеет отношения к данному сообщению. - something: - name: - other: Прочее - desc: - other: Этот пост требует внимания администрации по другой причине, не перечисленной выше. - placeholder: - other: Уточните, что именно Вас беспокоит - community_specific: - name: - other: специфическая для сообщества причина - desc: - other: Этот вопрос не соответствует рекомендациям сообщества. - not_clarity: - name: - other: нуждается в деталях или ясности - desc: - other: В настоящее время этот вопрос включает в себя несколько вопросов в одном. Он должен быть сосредоточен только на одной проблеме. - looks_ok: - name: - other: выглядит нормально - desc: - other: Этот пост хороший и достойного качества. - needs_edit: - name: - other: нуждается в редактировании, и я сделал это - desc: - other: Устраните проблемы с этим сообщением самостоятельно. - needs_close: - name: - other: требует закрытия - desc: - other: На закрытый вопрос нельзя ответить, но все равно можно редактировать, голосовать и комментировать. - needs_delete: - name: - other: требует удаления - desc: - other: Этот пост будет удален. - question: - close: - duplicate: - name: - other: спам - desc: - other: Этот вопрос был задан ранее и уже имеет ответ. - guideline: - name: - other: специфическая для сообщества причина - desc: - other: Этот вопрос не соответствует рекомендациям сообщества. - multiple: - name: - other: нуждается в деталях или ясности - desc: - other: В настоящее время этот вопрос включает в себя несколько вопросов в одном. Он должен быть сосредоточен только на одной проблеме. - other: - name: - other: прочее - desc: - other: Для этого поста требуется другая причина, не указанная выше. - operation_type: - asked: - other: вопросы - answered: - other: отвеченные - modified: - other: измененные - deleted_title: - other: Удаленные вопросы - questions_title: - other: Вопросы - tag: - tags_title: - other: Теги - no_description: - other: Тег не имеет описания. - notification: - action: - update_question: - other: обновленные вопросы - answer_the_question: - other: отвеченные вопросы - update_answer: - other: обновленные ответы - accept_answer: - other: принятые ответы - comment_question: - other: Прокомментированные ответы - comment_answer: - other: прокоментированные ответы - reply_to_you: - other: отвеченные вам - mention_you: - other: с упоминанием вас - your_question_is_closed: - other: Ваш вопрос был закрыт - your_question_was_deleted: - other: Ваш вопрос был удален - your_answer_was_deleted: - other: Ваш ответ был удален - your_comment_was_deleted: - other: Ваш комментарий был удален - up_voted_question: - other: поддержанный вопрос - down_voted_question: - other: неподдержанный вопрос - up_voted_answer: - other: ответ "за" - down_voted_answer: - other: ответ "против" - up_voted_comment: - other: поддержанный комментарий - invited_you_to_answer: - other: пригласил вас ответить - earned_badge: - other: Вы заработали значок "{{.BadgeName}}" - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Подтвердите новый адрес электронной почты" - body: - other: "Подтвердите свой новый адрес электронной почты для {{.SiteName}}, перейдя по следующей ссылке:
        {{.ChangeEmailUrl}}

        Если вы не запрашивали это изменение, пожалуйста, проигнорируйте это электронное письмо.

        -
        Примечание: Данное сообщение является автоматическим, отвечать на него не нужно." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} ответил на ваш вопрос" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nОткрыть {{.SiteName}}

        \n\n--
        \nПримечание: Данное сообщение является автоматическим, отвечать на него не нужно.

        \n\nОтписаться." - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} приглашает вас в Answer" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Я думаю, что вы можете знать ответ.

        \nОткрыть {{.SiteName}}

        \n\n--
        \nПримечание: Данное сообщение является автоматическим, отвечать на него не нужно.

        \n\nОтписаться" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} прокомментировал под вашей публикацией" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nОткрыть {{.SiteName}}

        \n\n--
        \nПримечание: Данное сообщение является автоматическим, отвечать на него не нужно.

        \n\nОтписаться" - new_question: - title: - other: "[{{.SiteName}}] Новый вопрос: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Пароль сброшен" - body: - other: "Кто-то попросил сбросить ваш пароль на {{.SiteName}}.

        \n\nЕсли это не вы, вы можете проигнорировать это письмо.

        \n\nПерейдите по следующей ссылке, чтобы выбрать новый пароль:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nПримечание: Данное сообщение является автоматическим, отвечать на него не нужно." - register: - title: - other: "[{{.SiteName}}] Подтвердите Ваш новый аккаунт" - body: - other: "Добро пожаловать в {{.SiteName}}!

        \n\nПерейдите по следующей ссылке для подтверждения и активации вашей новой учетной записи:
        \n{{.RegisterUrl}}

        \n\nЕсли ссылка выше не нажата, попробуйте скопировать и вставить её в адресную строку вашего браузера.\n

        \n\n--
        \nПримечание: Данное сообщение является автоматическим, отвечать на него не нужно." - test: - title: - other: "[{{.SiteName}}] Проверочное электронное письмо" - body: - other: "Это тестовое сообщение.\n

        \n\n--
        \nПримечание: Данное сообщение является автоматическим, отвечать на него не нужно." - action_activity_type: - upvote: - other: проголосовать за - upvoted: - other: проголосовано за - downvote: - other: бесполезный - downvoted: - other: проголосовано против - accept: - other: принять - accepted: - other: принято - edit: - other: редактировать - review: - queued_post: - other: Задан вопрос - flagged_post: - other: Отмеченный пост - suggested_post_edit: - other: Предложенные исправления - reaction: - tooltip: - other: "{{ .Names }} и {{ .Count }} еще..." - badge: - default_badges: - autobiographer: - name: - other: Автобиограф - desc: - other: Заполнена информация об профиле. - certified: - name: - other: Сертифицированный - desc: - other: Завершил наше новое руководство пользователя. - editor: - name: - other: Редактор - desc: - other: Впервые отредактировать сообщение - first_flag: - name: - other: Первый флаг - desc: - other: Впервые проставить флаг в сообщения - first_upvote: - name: - other: Первый голос - desc: - other: Впервые добавить голос в сообщении. - first_link: - name: - other: First Link - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: First Share - desc: - other: First shared a post. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Оставить 5 комментариев. - new_user_of_the_month: - name: - other: New User of the Month - desc: - other: Outstanding contributions in their first month. - read_guidelines: - name: - other: Read Guidelines - desc: - other: Прочтите [правила сообщества]. - reader: - name: - other: Читатель - desc: - other: Прочитать каждый ответ в разделе с более чем 10 ответами. - welcome: - name: - other: Добро пожаловать - desc: - other: Получен голос «за». - nice_share: - name: - other: Неплохо поделился - desc: - other: Shared a post with 25 unique visitors. - good_share: - name: - other: Good Share - desc: - other: Shared a post with 300 unique visitors. - great_share: - name: - other: Great Share - desc: - other: Shared a post with 1000 unique visitors. - out_of_love: - name: - other: Out of Love - desc: - other: Used 50 up votes in a day. - higher_love: - name: - other: Higher Love - desc: - other: Used 50 up votes in a day 5 times. - crazy_in_love: - name: - other: Crazy in Love - desc: - other: Used 50 up votes in a day 20 times. - promoter: - name: - other: Promoter - desc: - other: Invited a user. - campaigner: - name: - other: Campaigner - desc: - other: Invited 3 basic users. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: Спасибо - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Активный участник на год, опубликовал по крайней мере один раз. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: 'Форматирование:' - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Назад - next: Следующий - page_title: - question: Вопрос - questions: Вопросы - tag: Тэг - tags: Теги - tag_wiki: wiki тэг - create_tag: Создать тег - edit_tag: Изменить тег - ask_a_question: Create Question - edit_question: Редактировать вопрос - edit_answer: Редактировать ответ - search: Поиск - posts_containing: Посты содержащие - settings: Настройки - notifications: Уведомления - login: Вход - sign_up: Регистрация - account_recovery: Восстановление аккаунта - account_activation: Активация учётной записи - confirm_email: Подтвердить адрес электронной почты - account_suspended: Аккаунт заблокирован - admin: Управление - change_email: Изменить Email - install: Установка ответа - upgrade: Обновить ответ - maintenance: Обслуживание сайта - users: Пользователи - oauth_callback: Идет обработка - http_404: Ошибка HTTP 404 - http_50X: Ошибка HTTP 500 - http_403: Ошибка HTTP 403 - logout: Выйти - posts: Posts - notifications: - title: Уведомления - inbox: Входящие - achievement: Достижения - new_alerts: Новые оповещения - all_read: Отметить всё как прочитанное - show_more: Показать еще - someone: Кто-то - inbox_type: - all: Все - posts: Посты - invites: Приглашения - votes: Голоса - answer: Ответ - question: Вопрос - badge_award: Значок - suspended: - title: Ваш аккаунт заблокирован - until_time: "Ваша учетная запись была заблокирована до {{ time }}." - forever: Этот пользователь был навсегда заблокирован. - end: Вы не соответствуете правилам сообщества. - contact_us: Связаться с нами - editor: - blockquote: - text: Цитата - bold: - text: Сильный - chart: - text: Диаграмма - flow_chart: Блок-схема - sequence_diagram: Диаграмма последовательности - class_diagram: Диаграмма классов - state_diagram: Диаграмма состояний - entity_relationship_diagram: Диаграмма связей сущностей - user_defined_diagram: Пользовательская диаграмма - gantt_chart: Диаграмма Гантта - pie_chart: Круговая диаграмма - code: - text: Фрагмент кода - add_code: Добавить пример кода - form: - fields: - code: - label: Код - msg: - empty: Код не может быть пустым. - language: - label: Язык - placeholder: Автоматический выбор - btn_cancel: Отменить - btn_confirm: Добавить - formula: - text: Формула - options: - inline: Встроенная формула - block: Блочная формула - heading: - text: Заголовок - options: - h1: Заголовок 1 - h2: Заголовок 2 - h3: Заголовок 3 - h4: Заголовок 4 - h5: Заголовок 5 - h6: Заголовок 6 - help: - text: Помощь - hr: - text: Горизонтальная линия - image: - text: Изображение - add_image: Добавить изображение - tab_image: Загрузить изображение - form_image: - fields: - file: - label: Файл изображения - btn: Выбрать изображение - msg: - empty: Файл не может быть пустым. - only_image: Разрешены только изображения. - max_size: Размер файла не может превышать {{size}} МБ. - desc: - label: Описание - tab_url: URL изображения - form_url: - fields: - url: - label: URL изображения - msg: - empty: URL изображения не может быть пустым. - name: - label: Описание - btn_cancel: Отменить - btn_confirm: Добавь - uploading: Загрузка - indent: - text: Абзац - outdent: - text: Уменьшить отступ - italic: - text: Курсив - link: - text: Гиперссылка - add_link: Вставить гиперссылку - form: - fields: - url: - label: URL-адрес - msg: - empty: URL не может быть пустым. - name: - label: Описание - btn_cancel: Отменить - btn_confirm: Добавить - ordered_list: - text: Нумерованный список - unordered_list: - text: Маркированный список - table: - text: Таблица - heading: Заголовок - cell: Ячейка - file: - text: Прикрепить файлы - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: Я закрываю этот пост как... - btn_cancel: Отменить - btn_submit: Сохранить - remark: - empty: Не может быть пустым. - msg: - empty: Пожалуйста, выбери причину. - report_modal: - flag_title: 'Причина жалобы:' - close_title: Я закрываю этот пост как... - review_question_title: Проверить вопрос - review_answer_title: Проверить ответ - review_comment_title: Просмотр комментариев - btn_cancel: Отмена - btn_submit: Сохранить - remark: - empty: Не может быть пустым. - msg: - empty: Пожалуйста, выбери причину. - not_a_url: Недопустимый формат URL. - url_not_match: URL адрес не соответствует текущему веб-сайту. - tag_modal: - title: Новый тег - form: - fields: - display_name: - label: Отображаемое имя - msg: - empty: Отображаемое название не может быть пустым. - range: Отображаемое имя до 35 символов. - slug_name: - label: URL-адрес тега - desc: URL-адрес тега длиной до 35 символов. - msg: - empty: URL slug не может быть пустым. - range: URL slug до 35 символов. - character: URL slug содержит недопустимый набор символов. - desc: - label: Описание - revision: - label: Версия - edit_summary: - label: Отредактировать сводку - placeholder: >- - Коротко опишите изменения (орфография, грамматики, улучшение формата) - btn_cancel: Отмена - btn_submit: Сохрнаить - btn_post: Создать новый тег - tag_info: - created_at: Создано - edited_at: Отредактировано - history: История - synonyms: - title: Синонимы - text: Следующие теги будут переназначены на - empty: Синонимы не найдены. - btn_add: Добавить синоним - btn_edit: Редактировать - btn_save: Сохранить - synonyms_text: Следующие теги будут переназначены на - delete: - title: Удалить этот тег - tip_with_posts: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - tip_with_synonyms: >- -

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        - tip: Вы уверены, что хотите удалить? - close: Закрыть - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Изменить тег - default_reason: Правка тега - default_first_reason: Добавить метку - btn_save_edits: Сохранить изменения - btn_cancel: Отмена - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: сейчас - x_seconds_ago: "{{count}}с назад" - x_minutes_ago: "{{count}}м назад" - x_hours_ago: "{{count}}ч назад" - hour: часы - day: дней - hours: часов - days: дней - month: month - months: months - year: year - reaction: - heart: сердечко - smile: smile - frown: frown - btn_label: добавить или удалить реакции - undo_emoji: отменить реакцию {{ emoji }} - react_emoji: react with {{ emoji }} - unreact_emoji: unreact with {{ emoji }} - comment: - btn_add_comment: Добавить комментарий - reply_to: Ответить на - btn_reply: Ответить - btn_edit: Редактирование - btn_delete: Удалить - btn_flag: Пожаловаться - btn_save_edits: Сохранить изменения - btn_cancel: Отменить - show_more: "Еще {{count}} комментарий" - tip_question: >- - Воспользуйтесь комментариями, чтобы запросить больше информации или предложить улучшения. Не отвечайте на вопросы в комментариях. - tip_answer: >- - Используйте комментарии для ответа другим пользователям или уведомления об изменениях. Если вы добавляете новую информацию, редактируйте ваше сообщение вместо комментариев. - tip_vote: Это добавляет кое-что полезное к сообщению - edit_answer: - title: Редактировать ответ - default_reason: Редактировать ответ - default_first_reason: Добавить ответ - form: - fields: - revision: - label: Пересмотр - answer: - label: Ответ - feedback: - characters: длина пароля должна составлять не менее 6 символов. - edit_summary: - label: Изменить краткое описание - placeholder: >- - Кратко опишите вносимые изменения (исправлена орфография, исправлена грамматика, улучшено форматирование) - btn_save_edits: Сохранить изменения - btn_cancel: Отменить - tags: - title: Теги - sort_buttons: - popular: Популярное - name: Имя - newest: Последние - button_follow: Подписаться - button_following: Подписки - tag_label: вопросы - search_placeholder: Фильтр по названию тега - no_desc: Тег не имеет описания. - more: Подробнее - wiki: Wiki - ask: - title: Create Question - edit_title: Редактировать вопрос - default_reason: Редактировать вопрос - default_first_reason: Create question - similar_questions: Похожие вопросы - form: - fields: - revision: - label: Версия - title: - label: Заголовок - placeholder: What's your topic? Be specific. - msg: - empty: Заголовок не может быть пустым. - range: Заголовок должен быть меньше 150 символов - body: - label: 'Вопрос:' - msg: - empty: Вопрос не может быть пустым. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Теги - msg: - empty: Теги не могут быть пустыми. - answer: - label: Ответ - msg: - empty: Ответ не может быть пустым. - edit_summary: - label: Изменить краткое описание - placeholder: >- - Кратко опишите вносимые изменения (исправлена орфография, исправлена грамматика, улучшено форматирование) - btn_post_question: Задать вопрос - btn_save_edits: Сохранить изменения - answer_question: Ответить на свой собственный вопрос - post_question&answer: Опубликуйте свой вопрос и ответ - tag_selector: - add_btn: Тег - create_btn: новый тег - search_tag: Поиск тега - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: Нет соответствующих тэгов - tag_required_text: Обязательный тег (хотя бы один) - header: - nav: - question: Вопросы - tag: Теги - user: Пользователи - badges: Значки - profile: Профиль - setting: Настройки - logout: Выйти - admin: Управление - review: Рецензия - bookmark: Закладки - moderation: Модерирование - search: - placeholder: Поиск - footer: - build_on: >- - Работает на <1> Apache Answer - программном обеспечении с открытым исходным кодом, которое поддерживает сообщества вопросов и ответов.
        Сделано с любовью © {{cc}}. - upload_img: - name: Изменить - loading: загрузка... - pic_auth_code: - title: Капча - placeholder: Введите текст выше - msg: - empty: Капча не может быть пустой. - inactive: - first: >- - Вы почти закончили! Мы отправили письмо с активацией на адрес {{mail}}. Пожалуйста, следуйте инструкциям в письме, чтобы активировать свою учетную запись. - info: "Если оно не пришло, проверьте свою папку со спамом." - another: >- - Мы отправили вам еще одно электронное письмо с активацией по адресу {{mail}}. Его получение может занять несколько минут; обязательно проверьте папку со спамом. - btn_name: Повторно отправить письмо с активацией - change_btn_name: Изменить email - msg: - empty: Не может быть пустым. - resend_email: - url_label: Вы уверены, что хотите повторно отправить письмо с активацией? - url_text: Вы также можете предоставить пользователю ссылку для активации выше. - login: - login_to_continue: Войдите, чтобы продолжить - info_sign: У вас нет аккаунта? <1>Зарегистрируйтесь - info_login: Уже есть аккаунт? <1>Войти - agreements: Регистрируясь, вы соглашаетесь с <1>политикой конфиденциальности и <3>условиями обслуживания. - forgot_pass: Забыли пароль? - name: - label: Имя пользователя - msg: - empty: Имя пользователя не должно быть пустым. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: Email адрес - msg: - empty: Адрес электронной почты не может быть пустым. - password: - label: Пароль - msg: - empty: Пароль не может быть пустым. - different: Введенные пароли не совпадают - account_forgot: - page_title: Забыли свой пароль - btn_name: Отправить мне письмо для восстановления пароля - send_success: >- - Если учетная запись соответствует {{mail}}, вы должны в ближайшее время получить электронное письмо с инструкциями о том, как сбросить пароль. - email: - label: Email адрес - msg: - empty: Адрес электронной почты не может быть пустым. - change_email: - btn_cancel: Отмена - btn_update: Сменить адрес email - send_success: >- - Если учетная запись соответствует {{mail}}, вы должны в ближайшее время получить электронное письмо с инструкциями о том, как сбросить пароль. - email: - label: Новый email - msg: - empty: Email не может быть пустым. - oauth: - connect: Связаться с {{ auth_name }} - remove: Удалить {{ auth_name }} - oauth_bind_email: - subtitle: Добавьте адрес электронной почты для восстановления учетной записи. - btn_update: Сменить адрес email - email: - label: Электронная почта - msg: - empty: Адрес электронной почты не может быть пустым. - modal_title: Электронная почта уже существует. - modal_content: Этот адрес электронной почты уже зарегистрирован. Вы уверены, что хотите подключиться к существующей учетной записи? - modal_cancel: Изменить адрес электронной почты - modal_confirm: Подключение к существующей учетной записи - password_reset: - page_title: Сброс пароля - btn_name: Сбросить мой пароль - reset_success: >- - Вы успешно сменили свой пароль; вы будете перенаправлены на страницу входа в систему. - link_invalid: >- - Извините, эта ссылка для сброса пароля больше недействительна. Возможно, ваш пароль уже сброшен? - to_login: Перейдите на страницу входа в систему - password: - label: Пароль - msg: - empty: Пароль не может быть пустым. - length: Длина должна быть от 8 до 32 - different: Введенные пароли не совпадают - password_confirm: - label: Подтвердите новый пароль - settings: - page_title: Настройки - goto_modify: Перейдите к изменению - nav: - profile: Профиль - notification: Уведомления - account: Учетная запись - interface: Интерфейс - profile: - heading: Профиль - btn_name: Сохранить - display_name: - label: Отображаемое имя - msg: Отображаемое имя не может быть пустым. - msg_range: Display name must be 2-30 characters in length. - username: - label: Имя пользователя - caption: Люди могут упоминать вас как "@username". - msg: Имя пользователя не может быть пустым. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Изображение профиля - gravatar: Gravatar - gravatar_text: Вы можете изменить изображение на - custom: Другой - custom_text: Вы можете загрузить свое изображение. - default: Системные - msg: Пожалуйста, загрузите аватар - bio: - label: Обо мне - website: - label: Сайт - placeholder: "https://example.com" - msg: Неправильный формат веб-сайта - location: - label: Местоположение - placeholder: "Город, страна" - notification: - heading: Уведомления по эл. почте - turn_on: Вкл. - inbox: - label: Email уведомления - description: Ответы на ваши вопросы, комментарии, приглашения и многое другое. - all_new_question: - label: Все новые вопросы - description: Получайте уведомления обо всех новых вопросах. До 50 вопросов в неделю. - all_new_question_for_following_tags: - label: Все новые вопросы для тегов из подписок - description: Получайте уведомления о новых вопросах по следующим тегам. - account: - heading: Учетная запись - change_email_btn: Изменить e-mail - change_pass_btn: Изменить пароль - change_email_info: >- - Мы отправили электронное письмо на этот адрес. Пожалуйста, следуйте инструкциям из письма. - email: - label: Email - new_email: - label: Новый email - msg: Новый email не может быть пустым. - pass: - label: Текущий пароль - msg: Пароль не может быть пустым. - password_title: Пароль - current_pass: - label: Текущий пароль - msg: - empty: Текущий пароль не может быть пустым. - length: Длина должна быть от 8 до 32. - different: Введенные пароли не совпадают. - new_pass: - label: Новый пароль - pass_confirm: - label: Подтвердите новый пароль - interface: - heading: Интерфейс - lang: - label: Язык интерфейса - text: Язык пользовательского интерфейса. Он изменится при обновлении страницы. - my_logins: - title: Мои логины - label: Войдите в систему или зарегистрируйтесь на этом сайте, используя эти учетные записи. - modal_title: Удаление логина - modal_content: Вы уверены, что хотите удалить этот логин из своей учетной записи? - modal_confirm_btn: Удалить - remove_success: Успешно удалено - toast: - update: успешное обновление - update_password: Пароль успешно изменен. - flag_success: Благодарим за отметку. - forbidden_operate_self: Запрещено работать с собой - review: Ваша версия будет отображаться после проверки. - sent_success: Отправлено успешно - related_question: - title: Related - answers: ответы - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Позвать на помощь - desc: Выберите людей, которые, по вашему мнению, могут знать ответ. - invite: Пригласил вас ответить - add: Добавить пользователей - search: Поиск людей - question_detail: - action: Действия - created: Created - Asked: Спросил(а) - asked: спросил(а) - update: Изменён - Edited: Edited - edit: отредактировал - commented: commented - Views: Просмотрен - Follow: Подписаться - Following: Подписки - follow_tip: Подпишитесь на этот вопрос для получения уведомлений - answered: отвеченные - closed_in: Закрыто в - show_exist: Показать существующий вопрос. - useful: Полезный - question_useful: Это полезно и понятно - question_un_useful: Это непонятно или не полезно - question_bookmark: Добавьте этот вопрос в закладки - answer_useful: Это полезно - answer_un_useful: Это бесполезно - answers: - title: Ответы - score: Оценка - newest: Последние - oldest: Oldest - btn_accept: Принять - btn_accepted: Принято - write_answer: - title: Ваш ответ - edit_answer: Редактировать мой существующий ответ - btn_name: Ответить - add_another_answer: Добавить другой ответ - confirm_title: Перейти к ответу - continue: Продолжить - confirm_info: >- -

        Вы уверены, что хотите добавить другой ответ?

        Вы можете использовать ссылку редактирования для уточнения и улучшения существующего ответа.

        - empty: Ответ не может быть пустым. - characters: длина содержимого должна составлять не менее 6 символов. - tips: - header_1: Спасибо за ответ - li1_1: Пожалуйста, обязательно отвечайте на вопрос. Предоставьте подробности и поделитесь результатами своих исследований. - li1_2: Поддерживайте свои высказывания ссылками или личным опытом. - header_2: Но избегайте ... - li2_1: Просить о помощи, запрашивать уточнения или отвечать на другие ответы. - reopen: - confirm_btn: Снова открыть - title: Открыть повторно этот пост - content: Вы уверены, что хотите открыть заново? - list: - confirm_btn: Список - title: List this post - content: Are you sure you want to list? - unlist: - confirm_btn: Убрать из списка - title: Unlist this post - content: Are you sure you want to unlist? - pin: - title: Закрепить сообщение - content: Вы уверены, что хотите закрепить глобально? Это сообщение появится вверху всех списков сообщений. - confirm_btn: Закрепить - delete: - title: Удалить сообщение - question: >- - Мы не рекомендуем удалять вопросы с ответами, поскольку это лишает будущих читателей этих знаний.

        Повторное удаление вопросов с ответами может привести к блокировке вашей учетной записи. Вы уверены, что хотите удалить? - answer_accepted: >- - Мы не рекомендуем удалять вопросы с ответами, поскольку это лишает будущих читателей этих знаний.

        Повторное удаление вопросов с ответами может привести к блокировке вашей учетной записи. Вы уверены, что хотите удалить? - other: Вы уверены, что хотите удалить? - tip_answer_deleted: Этот ответ был удален - undelete_title: Восстановить сообщение - undelete_desc: Вы уверены, что хотите отменить удаление? - btns: - confirm: Подтвердить - cancel: Отменить - edit: Редактировать - save: Сохранить - delete: Удалить - undelete: Отменить удаление - list: List - unlist: Unlist - unlisted: Unlisted - login: Авторизоваться - signup: Регистрация - logout: Выйти - verify: Подтвердить - create: Create - approve: Одобрить - reject: Отклонить - skip: Пропустить - discard_draft: Удалить черновик - pinned: Закрепленный - all: Все - question: Вопрос - answer: Ответ - comment: Комментарий - refresh: Обновить - resend: Отправить повторно - deactivate: Отключить - active: Активные - suspend: Заблокировать - unsuspend: Разблокировать - close: Закрыть - reopen: Открыть повторно - ok: ОК - light: Светлая тема - dark: Темная тема - system_setting: Настройки системы - default: По умолчанию - reset: Сбросить - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignore - submit: Submit - normal: Normal - closed: Closed - deleted: Deleted - deleted_permanently: Deleted permanently - pending: Pending - more: More - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Результаты поиска - keywords: Ключевые слова - options: Настройки - follow: Подписаться - following: Подписка - counts: "Результатов: {{count}}" - counts_loading: "... Results" - more: Ещё - sort_btns: - relevance: По релевантности - newest: Последние - active: Активные - score: Оценки - more: Больше - tips: - title: Советы по расширенному поиску - tag: "<1>[tag] search with a tag" - user: "<1>user:username поиск по автору" - answer: "<1>ответов:0 вопросы без ответов" - score: "<1>score:3 записи с рейтингом 3+" - question: "<1>is:question поиск по вопросам" - is_answer: "<1>ответ поиск ответов" - empty: Мы ничего не смогли найти.
        Попробуйте другие или менее специфичные ключевые слова. - share: - name: Поделиться - copy: Скопировать ссылку - via: Поделитесь постом через... - copied: Скопировано - facebook: Поделиться на Facebook - twitter: Share to X - cannot_vote_for_self: Вы не можете проголосовать за свой собственный пост. - modal_confirm: - title: Ошибка... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Ваша новая учетная запись подтверждена; вы будете перенаправлены на главную страницу. - link: Перейти на главную - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: Ваш адрес электронной почты был обновлен. - confirm_new_email_invalid: >- - Извините, эта ссылка для подтверждения больше недействительна. Возможно, ваш адрес электронной почты уже был изменен? - unsubscribe: - page_title: Отписаться - success_title: Вы успешно отписались от рассылки - success_desc: Вы были успешно удалены из этого списка подписчиков и больше не будете получать от нас никаких электронных писем. - link: Изменить настройки - question: - following_tags: Подписка на теги - edit: Редактировать - save: Сохранить - follow_tag_tip: Подпишитесь на теги, чтобы следить за интересующими темами. - hot_questions: Популярные вопросы - all_questions: Все вопросы - x_questions: "{{ count }} вопросов" - x_answers: "{{ count }} ответов" - x_posts: "{{ count }} Posts" - questions: Вопросы - answers: Ответы - newest: Последние - active: Активные - hot: Hot - frequent: Frequent - recommend: Recommend - score: Оценка - unanswered: Без ответа - modified: изменён - answered: отвеченные - asked: спросил(а) - closed: закрытый - follow_a_tag: Следить за тегом - more: Подробнее - personal: - overview: Обзор - answers: Ответы - answer: ответ - questions: Вопросы - question: вопрос - bookmarks: Закладки - reputation: Репутация - comments: Комментарии - votes: Голоса - badges: Badges - newest: Последние - score: Оценки - edit_profile: Редактировать профиль - visited_x_days: "Посещено {{ count }} дней" - viewed: Просмотрен - joined: Присоединился - comma: "," - last_login: Просмотрен(-а) - about_me: О себе - about_me_empty: "// Привет, Мир!" - top_answers: Лучшие ответы - top_questions: Топ вопросов - stats: Статистика - list_empty: Сообщений не найдено.
        Возможно, вы хотели бы выбрать другую вкладку? - content_empty: No posts found. - accepted: Принято - answered: отвеченные - asked: спросил - downvoted: проголосовано против - mod_short: MOD - mod_long: Модераторы - x_reputation: репутация - x_votes: полученные голоса - x_answers: ответы - x_questions: вопросы - recent_badges: Recent Badges - install: - title: Installation - next: Следующий - done: Готово - config_yaml_error: Не удается создать файл config.yaml. - lang: - label: Пожалуйста, выберите язык - db_type: - label: База данных - db_username: - label: Имя пользователя - placeholder: root - msg: Имя пользователя не может быть пустым. - db_password: - label: Пароль - placeholder: root - msg: Пароль не может быть пустым. - db_host: - label: Сервер базы данных - placeholder: "db:3306" - msg: Сервер базы данных не может быть пустым. - db_name: - label: Название базы данных - placeholder: ответ - msg: Имя базы данных не может быть пустым. - db_file: - label: Файл базы данных - placeholder: /data/answer.db - msg: Файл базы данных не может быть пустым. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Создайте файл config.yaml - label: Файл config.yaml создан. - desc: >- - Вы можете создать файл <1>config.yaml вручную в каталоге <1>/var/wwww/xxx/ и вставить в него следующий текст. - info: После этого нажмите на кнопку "Далее". - site_information: Информация о сайте - admin_account: Администратор - site_name: - label: Название сайта - msg: Название сайта не может быть пустым. - msg_max_length: Длина названия сайта должна составлять не более 30 символов. - site_url: - label: Адрес сайта - text: Адрес вашего сайта. - msg: - empty: URL-адрес сайта не может быть пустым. - incorrect: Неверный формат URL-адреса сайта. - max_length: Длина URL-адреса сайта должна составлять не более 512 символов. - contact_email: - label: Контактный адрес электронной почты - text: Адрес электронной почты контактного лица, ответственного за этот сайт. - msg: - empty: Контактный адрес электронной почты не может быть пустым. - incorrect: Некорректный формат контактного адреса электронной почты. - login_required: - label: Приватный - switch: Требуется авторизация - text: Только зарегистрированные пользователи могут получить доступ к этому сообществу. - admin_name: - label: Имя - msg: Имя не может быть пустым. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Пароль - text: >- - Этот пароль понадобится вам для входа в систему. Пожалуйста, сохраните его в надежном месте. - msg: Пароль не может быть пустым. - msg_min_length: Длина пароля должна составлять не менее 8 символов. - msg_max_length: Длина пароля должна составлять не более 32 символов. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: Email - text: Вам понадобится этот адрес электронной почты для входа в систему. - msg: - empty: Адрес электронной почты не может быть пустым. - incorrect: Недопустимый формат e-mail адреса. - ready_title: Your site is ready - ready_desc: >- - Если вам когда-нибудь захочется изменить дополнительные настройки, посетите <1>раздел администратора; найдите его в меню сайта. - good_luck: "Получайте удовольствие и удачи!" - warn_title: Предупреждение - warn_desc: >- - Файл <1>config.yaml уже существует. Если вам нужно сбросить любой из элементов конфигурации в этом файле, пожалуйста, удалите его. - install_now: Вы можете попробовать <1>установить сейчас. - installed: Уже установлено - installed_desc: >- - Похоже, вы уже установили. Для переустановки, пожалуйста, сначала очистите ваши старые таблицы базы данных. - db_failed: Ошибка подключения к базе данных - db_failed_desc: >- - Это означает, что информация о базе данных в вашем файле <1>config.yaml неверна, либо не удалось установить контакт с сервером базы данных. Это может означать, что сервер базы данных вашего хоста недоступен. - counts: - views: просмотры - votes: голоса - answers: ответы - accepted: Принято - page_error: - http_error: Ошибка HTTP {{ code }} - desc_403: Нет прав доступа для просмотра этой страницы. - desc_404: К сожалению, эта страница не существует. - desc_50X: Сервер обнаружил ошибку и не смог выполнить ваш запрос. - back_home: Вернуться на главную страницу - page_maintenance: - desc: "Мы выполняем техническое обслуживание, скоро вернемся." - nav_menus: - dashboard: Панель управления - contents: Содержимое - questions: Вопросы - answers: Ответы - users: Пользователи - badges: Badges - flags: Отметить - settings: Настройки - general: Основные - interface: Интерфейс - smtp: SMTP - branding: Фирменное оформление - legal: Правовая информация - write: Написать - terms: Terms - tos: Пользовательское Соглашение - privacy: Конфиденциальность - seo: SEO - customize: Настройки интерфейса - themes: Темы - login: Вход - privileges: Привилегии - plugins: Плагины - installed_plugins: Установленные плагины - apperance: Appearance - website_welcome: Добро пожаловать на {{site_name}} - user_center: - login: Вход - qrcode_login_tip: Пожалуйста, используйте {{ agentName }} для сканирования QR-кода и входа в систему. - login_failed_email_tip: Не удалось войти в систему, пожалуйста, разрешите этому приложению получить доступ к вашей электронной почте, прежде чем повторять попытку. - badges: - modal: - title: Congratulations - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - admin: - admin_header: - title: Администратор - dashboard: - title: Панель управления - welcome: Welcome to Admin! - site_statistics: Статистика сайта - questions: "Вопросы:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "Ответы:" - comments: "Комментарии:" - votes: "Голоса:" - users: "Пользователи:" - flags: "Жалобы:" - reviews: "Reviews:" - site_health: Здоровье сайта - version: "Версия:" - https: "HTTPS:" - upload_folder: "Каталог загрузки:" - run_mode: "Режим приватности:" - private: Приватный - public: Публичные - smtp: "SMTP:" - timezone: "Часовой пояс:" - system_info: Информация о системе - go_version: "Версия GO:" - database: "База данных:" - database_size: "Размер базы данных:" - storage_used: "Использовано хранилища: " - uptime: "Время работы:" - links: Ссылки - plugins: Плагины - github: GitHub - blog: Блог - contact: Контакты - forum: Форум - documents: Документы - feedback: Обратная связь - support: Поддержка - review: Обзор - config: Конфигурация - update_to: Обновление до - latest: Последние - check_failed: Проверка не удалась - "yes": "Да" - "no": "Нет" - not_allowed: Запрещено - allowed: Разрешено - enabled: Включено - disabled: Отключено - writable: Доступен для записи - not_writable: Не доступен для записи - flags: - title: Жалобы - pending: Ожидают - completed: Рассмотрены - flagged: Жалобы - flagged_type: Жалоба {{ type }} - created: Создано - action: Действие - review: На проверку - user_role_modal: - title: Изменить роль пользователя на... - btn_cancel: Отмена - btn_submit: Отправить - new_password_modal: - title: Задать новый пароль - form: - fields: - password: - label: Пароль - text: Сессия пользователя будет завершена и ему придется повторить вход. - msg: Длина пароля должна составлять от 8 до 32 символов. - btn_cancel: Отменить - btn_submit: Отправить - edit_profile_modal: - title: Edit profile - form: - fields: - display_name: - label: Display name - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Invalid Email Address. - edit_success: Edited successfully - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Создание новых пользователей - form: - fields: - users: - label: Массовое добавление пользователей - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Разделите “name, email, password” запятыми. По одному пользователю в строке. - msg: "Пожалуйста, введите адрес электронной почты пользователя, по одному на строку." - display_name: - label: Отображаемое имя - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Некорректный email. - password: - label: Пароль - msg: Длина пароля должна составлять от 8 до 32 символов. - btn_cancel: Отменить - btn_submit: Отправить - users: - title: Пользователи - name: Имя - email: Email - reputation: Репутация - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Статус - role: Роль - action: Действия - change: Изменить - all: Все - staff: Сотрудники - more: Ещё - inactive: Неактивные - suspended: Заблокированные - deleted: Удаленные - normal: Обычный - Moderator: Модератор - Admin: Администратор - User: Пользователь - filter: - placeholder: "Фильтровать по имени, user:id" - set_new_password: Задать новый пароль - edit_profile: Edit profile - change_status: Изменить статус - change_role: Изменить роль - show_logs: Показать логи - add_user: Добавить пользователя - deactivate_user: - title: Деактивировать пользователя - content: Неактивный пользователь должен будет повторно подтвердить свою электронную почту. - delete_user: - title: Удалить этого пользователя - content: Вы уверены, что хотите удалить этого пользователя? Это действие необратимо! - remove: Удалить контент пользователя (опционально) - label: Удалить все вопросы, ответы, комментарии и т.д. - text: Не устанавливайте этот флажок, если вы хотите удалить только учетную запись пользователя. - suspend_user: - title: Заблокировать этого пользователя - content: Заблокированный пользователь не сможет войти. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Вопросы - unlisted: Unlisted - post: Публикация - votes: Голоса - answers: Ответы - created: Создан - status: Статус - action: Действие - change: Изменить - pending: Ожидают - filter: - placeholder: "Фильтровать по заголовку, question:id" - answers: - page_title: Ответы - post: Публикация - votes: Голоса - created: Создан - status: Статус - action: Действие - change: Изменить - filter: - placeholder: "Фильтровать по заголовку, answer:id" - general: - page_title: Основные - name: - label: Название сайта - msg: Название сайта не может быть пустым. - text: "Название сайта, используемое в теге title." - site_url: - label: URL-адрес сайта - msg: URL-адрес сайта не может быть пустым. - validate: Пожалуйста, введите корректный URL. - text: Адрес вашего сайта. - short_desc: - label: Краткое описание - msg: Краткое описание сайта не может быть пустым. - text: "Краткое описание, используемое в теге заголовка на домашней странице." - desc: - label: Описание сайта - msg: Описание сайта не может быть пустым. - text: "Опишите этот сайт одним предложением, как используется в теге meta description" - contact_email: - label: Контактный адрес электронной почты - msg: Контактный адрес электронной почты не может быть пустым. - validate: Контактный адрес электронной почты не может быть пустым. - text: Адрес электронной почты контактного лица, ответственного за данный сайт. - check_update: - label: Обновления программного обеспечения - text: Автоматически проверять наличие обновлений - interface: - page_title: Интерфейс - language: - label: Язык интерфейса - msg: Язык интерфейса не может быть пустым. - text: Язык пользовательского интерфейса. Он изменится при обновлении страницы. - time_zone: - label: Часовой пояс - msg: Часовой пояс не может быть пустым. - text: Выберите город в том же часовом поясе, что и вы. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: С эл. почты - msg: Адрес электронной почты отправителя не может быть пустым. - text: Адрес электронной почты, с которого отправляются письма. - from_name: - label: Имя отправителя - msg: Имя пользователя не может быть пустым. - text: Имя, с которого отправляются электронные письма. - smtp_host: - label: Сервер SMTP - msg: Сервер SMTP не может быть пустым. - text: Ваш почтовый сервер. - encryption: - label: Шифрование - msg: Шифрование не может быть пустым. - text: Для большинства серверов рекомендуется использовать протокол SSL. - ssl: SSL - tls: TLS - none: Нет - smtp_port: - label: Порт SMTP - msg: Порт SMTP должен быть числом 1 ~ 65535. - text: Порт для вашего почтового сервера. - smtp_username: - label: Имя пользователя SMTP - msg: Имя пользователя SMTP не может быть пустым. - smtp_password: - label: Пароль SMTP - msg: Пароль SMTP не может быть пустым. - test_email_recipient: - label: Тестовые получатели электронной почты - text: Укажите адрес электронной почты, на который будут отправляться тестовые сообщения. - msg: Некорректный тестовый адрес электронной почты - smtp_authentication: - label: Включить авторизацию - title: Аутентификация SMTP - msg: Аутентификационные данные для SMTP не могут быть пустыми. - "yes": "Да" - "no": "Нет" - branding: - page_title: Фирменное оформление - logo: - label: Логотип - msg: Логотип не может быть пустым. - text: Изображение логотипа в левом верхнем углу вашего сайта. Используйте широкое прямоугольное изображение высотой 56 см с соотношением сторон более 3:1. Если оставить поле пустым, будет показан текст заголовка сайта. - mobile_logo: - label: Мобильный логотип - text: Логотип, используемый в мобильной версии вашего сайта. Используйте широкое прямоугольное изображение высотой 56. Если оставить пустым, будет использоваться изображение из настройки "Логотип". - square_icon: - label: Квадратный значок - msg: Square icon не может быть пустым. - text: Изображение, используемое в качестве основы для значков метаданных. В идеале должно быть больше 512x512. - favicon: - label: Иконка - text: Значок для вашего сайта. Для корректной работы через CDN он должен быть в формате png. Размер будет изменен до 32x32. Если оставить пустым, будет использоваться "square icon". - legal: - page_title: Правовая информация - terms_of_service: - label: Условия использования - text: "Вы можете добавить содержимое условий предоставления услуг здесь. Если у вас уже есть документ, размещенный в другом месте, укажите полный URL-адрес здесь." - privacy_policy: - label: Условия конфиденциальности - text: "Вы можете добавить содержание политики конфиденциальности здесь. Если у вас уже есть документ, размещенный в другом месте, укажите полный URL-адрес здесь." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Написать - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Каждый пользователь может написать только один ответ на каждый вопрос - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Рекомендованные теги - text: "Recommend tags will show in the dropdown list by default." - msg: - contain_reserved: "recommended tags cannot contain reserved tags" - required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags - text: "Каждый новый вопрос должен иметь хотя бы один рекомендуемый тег." - reserved_tags: - label: Зарезервированные теги - text: "Reserved tags can only be used by moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: SEO - permalink: - label: Постоянная ссылка - text: Пользовательские структуры URL-адресов могут улучшить удобство использования и обратную совместимость ваших ссылок. - robots: - label: robots.txt - text: Это приведет к необратимому переопределению всех связанных настроек сайта. - themes: - page_title: Темы - themes: - label: Темы - text: Выберите существующую тему. - color_scheme: - label: Цветовая схема - navbar_style: - label: Navbar background style - primary_color: - label: Основной цвет - text: Измените цвета, используемые в ваших темах - css_and_html: - page_title: CSS и HTML - custom_css: - label: Пользовательский CSS - text: > - - head: - label: Head - text: > - - header: - label: Header - text: > - - footer: - label: Нижняя панель - text: Это будет вставлено перед </body>. - sidebar: - label: Боковая панель - text: Это будет вставлено в боковую панель. - login: - page_title: Авторизоваться - membership: - title: Участие в сообществах - label: Разрешить новые регистрации - text: Отключите, чтобы никто не мог создать новую учетную запись. - email_registration: - title: Регистрация по электронной почте - label: Разрешить регистрацию по электронной почте - text: Отключите, чтобы предотвратить создание новой учетной записи через электронную почту. - allowed_email_domains: - title: Разрешенные домены электронной почты - text: Домены электронной почты, с которыми пользователи должны регистрировать аккаунты. Один домен на каждой строке. Игнорируется, если пусто. - private: - title: Приватный - label: Требуется авторизация - text: Только зарегистрированные пользователи могут получить доступ к этому сообществу. - password_login: - title: Вход в пароль - label: Разрешить вход по паролю - text: "Предупреждение: При отключении, вы не сможете войти, если ранее не настроили другой способ входа." - installed_plugins: - title: Установленные плагины - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. - filter: - all: Все - active: Активные - inactive: Неактивные - outdated: Устаревшие - plugins: - label: Плагины - text: Выберите существующий плагин. - name: Название - version: Версия - status: Статус - action: Действие - deactivate: Деактивировать - activate: Активировать - settings: Настройки - settings_users: - title: Пользователи - avatar: - label: Аватар по умолчанию - text: Для пользователей, у которых нет собственного пользовательского аватара. - gravatar_base_url: - label: Базовый URL Gravatar - text: URL базы API провайдера Gravatar. Игнорируется, если пусто. - profile_editable: - title: Настройки профилей - allow_update_display_name: - label: Разрешить пользователям изменять отображаемое имя - allow_update_username: - label: Разрешить пользователям изменять свой username - allow_update_avatar: - label: Разрешить пользователям изменять изображение своего профиля - allow_update_bio: - label: Разрешить пользователям изменять свои сведения в поле "обо мне" - allow_update_website: - label: Разрешить пользователям изменять свой веб-сайт - allow_update_location: - label: Разрешить пользователям изменять свое местоположение - privilege: - title: Привилегии - level: - label: Необходимый уровень репутации - text: Выберите количество репутации, необходимое для получения привилегий - msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 - badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate - filter: - placeholder: Filter by name, badge:id - group: Group - inactive: Inactive - name: Name - show_logs: Show logs - status: Status - title: Badges - form: - optional: (опционально) - empty: не может быть пустым - invalid: недействителен - btn_submit: Сохранить - not_found_props: "Требуемое свойство {{ key }} не найдено." - select: Select - page_review: - review: На проверку - proposed: предложенный - question_edit: Редактировать вопрос - answer_edit: Редактирование ответа - tag_edit: Редактирование тега - edit_summary: Редактирование краткого описания - edit_question: Редактирование вопроса - edit_answer: Редактирование ответа - edit_tag: Редактирование тега - empty: Нет задач для проверки. - approve_revision_tip: Do you approve this revision? - approve_flag_tip: Do you approve this flag? - approve_post_tip: Do you approve this post? - approve_user_tip: Do you approve this user? - suggest_edits: Предложенные исправления - flag_post: Flag post - flag_user: Flag user - queued_post: Queued post - queued_user: Queued user - filter_label: Type - reputation: репутация - flag_post_type: Flagged this post as {{ type }}. - flag_user_type: Flagged this user as {{ type }}. - edit_post: Edit post - list_post: List post - unlist_post: Unlist post - timeline: - undeleted: Восстановлен - deleted: Удаленные - downvote: бесполезный - upvote: оценить - accept: принять - cancelled: отменен - commented: прокомментированный - rollback: откатить - edited: отредактированный - answered: отвеченные - asked: asked - closed: закрытый - reopened: Открыт повторно - created: созданный - pin: закрепленный - unpin: незакреплённые - show: listed - hide: unlisted - title: "History for" - tag_title: "Хронология" - show_votes: "Show votes" - n_or_a: Недоступно - title_for_question: "Хронология" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Дата и время - type: Тип - by: Автор - comment: Комментарий - no_data: "Ничего не найдено." - users: - title: Пользователи - users_with_the_most_reputation: Пользователи с самой высокой репутацией на этой неделе - users_with_the_most_vote: Пользователи, которые больше всего проголосовали на этой неделе - staffs: Сотрудники нашего сообщества - reputation: репутация - votes: голоса - prompt: - leave_page: Вы уверены, что хотите покинуть страницу? - changes_not_save: Ваши изменения могут не быть сохранены. - draft: - discard_confirm: Вы уверены, что хотите отказаться от своего черновика? - messages: - post_deleted: Этот пост был удалён. - post_cancel_deleted: This post has been undeleted. - post_pin: Этот пост был закреплен. - post_unpin: Этот пост был откреплен. - post_hide_list: Это сообщение было скрыто из списка. - post_show_list: Этот пост был показан в списке. - post_reopen: Этот пост был вновь открыт. - post_list: This post has been listed. - post_unlist: This post has been unlisted. - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/sk_SK.yaml b/data/i18n/sk_SK.yaml deleted file mode 100644 index 4daa2ab02..000000000 --- a/data/i18n/sk_SK.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Úspech. - unknown: - other: Neznáma chyba. - request_format_error: - other: Formát žiadosti nie je platný. - unauthorized_error: - other: Neoprávnené. - database_error: - other: Chyba dátového servera. - forbidden_error: - other: Forbidden. - duplicate_request_error: - other: Duplicate submission. - action: - report: - other: Flag - edit: - other: Edit - delete: - other: Delete - close: - other: Close - reopen: - other: Reopen - forbidden_error: - other: Forbidden. - pin: - other: Pin - hide: - other: Unlist - unpin: - other: Unpin - show: - other: List - invite_someone_to_answer: - other: Edit - undelete: - other: Undelete - merge: - other: Merge - role: - name: - user: - other: Užívateľ - admin: - other: Správca - moderator: - other: Moderátor - description: - user: - other: Predvolené bez špeciálneho prístupu. - admin: - other: Má plnú moc a prístup ku stránke. - moderator: - other: Má prístup ku všetkým príspevkom okrem nastavenia správcu. - privilege: - level_1: - description: - other: Level 1 (less reputation required for private team, group) - level_2: - description: - other: Level 2 (low reputation required for startup community) - level_3: - description: - other: Level 3 (high reputation required for mature community) - level_custom: - description: - other: Custom Level - rank_question_add_label: - other: Ask question - rank_answer_add_label: - other: Write answer - rank_comment_add_label: - other: Write comment - rank_report_add_label: - other: Flag - rank_comment_vote_up_label: - other: Upvote comment - rank_link_url_limit_label: - other: Post more than 2 links at a time - rank_question_vote_up_label: - other: Upvote question - rank_answer_vote_up_label: - other: Upvote answer - rank_question_vote_down_label: - other: Downvote question - rank_answer_vote_down_label: - other: Downvote answer - rank_invite_someone_to_answer_label: - other: Invite someone to answer - rank_tag_add_label: - other: Create new tag - rank_tag_edit_label: - other: Edit tag description (need to review) - rank_question_edit_label: - other: Edit other's question (need to review) - rank_answer_edit_label: - other: Edit other's answer (need to review) - rank_question_edit_without_review_label: - other: Edit other's question without review - rank_answer_edit_without_review_label: - other: Edit other's answer without review - rank_question_audit_label: - other: Review question edits - rank_answer_audit_label: - other: Review answer edits - rank_tag_audit_label: - other: Review tag edits - rank_tag_edit_without_review_label: - other: Edit tag description without review - rank_tag_synonym_label: - other: Manage tag synonyms - email: - other: E-mail - e_mail: - other: Email - password: - other: Heslo - pass: - other: Password - old_pass: - other: Current password - original_text: - other: This post - email_or_password_wrong_error: - other: E-mail a heslo sa nezhodujú. - error: - common: - invalid_url: - other: Invalid URL. - status_invalid: - other: Invalid status. - password: - space_invalid: - other: Password cannot contain spaces. - admin: - cannot_update_their_password: - other: Svoje heslo upraviť. - cannot_edit_their_profile: - other: You cannot modify your profile. - cannot_modify_self_status: - other: Nemôžete upraviť svoj stav. - email_or_password_wrong: - other: E-mail a heslo sa nezhodujú. - answer: - not_found: - other: Odpoveď sa nenašla. - cannot_deleted: - other: Žiadne povolenie na odstránenie. - cannot_update: - other: Žiadne povolenie na aktualizáciu. - question_closed_cannot_add: - other: Questions are closed and cannot be added. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Komentár nie je dovolené upravovať. - not_found: - other: Komentár sa nenašiel. - cannot_edit_after_deadline: - other: Čas na úpravu komentára bol príliš dlhý. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: E-mail už existuje. - need_to_be_verified: - other: E-mail by sa mal overiť. - verify_url_expired: - other: Platnosť overenej adresy URL e-mailu vypršala, pošlite e-mail znova. - illegal_email_domain_error: - other: Email is not allowed from that email domain. Please use another one. - lang: - not_found: - other: Jazykový súbor sa nenašiel. - object: - captcha_verification_failed: - other: Captcha zle. - disallow_follow: - other: Nemáte dovolené sledovať. - disallow_vote: - other: Nemáte povolené hlasovať. - disallow_vote_your_self: - other: Nemôžete hlasovať za svoj vlastný príspevok. - not_found: - other: Objekt sa nenašiel. - verification_failed: - other: Overenie zlyhalo. - email_or_password_incorrect: - other: E-mail a heslo sa nezhodujú. - old_password_verification_failed: - other: Overenie starého hesla zlyhalo - new_password_same_as_previous_setting: - other: Nové heslo je rovnaké ako predchádzajúce. - already_deleted: - other: This post has been deleted. - meta: - object_not_found: - other: Meta object not found - question: - already_deleted: - other: Tento príspevok bol odstránený. - under_review: - other: Your post is awaiting review. It will be visible after it has been approved. - not_found: - other: Otázka sa nenašla. - cannot_deleted: - other: Žiadne povolenie na odstránenie. - cannot_close: - other: Žiadne povolenie na uzavretie. - cannot_update: - other: Žiadne povolenie na aktualizáciu. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Reputation rank fail to meet the condition. - vote_fail_to_meet_the_condition: - other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. - no_enough_rank_to_operate: - other: You need at least {{.Rank}} reputation to do this. - report: - handle_failed: - other: Spracovanie prehľadu zlyhalo. - not_found: - other: Hlásenie sa nenašlo. - tag: - already_exist: - other: Značka už existuje. - not_found: - other: Značka sa nenašla. - recommend_tag_not_found: - other: Recommend tag is not exist. - recommend_tag_enter: - other: Zadajte aspoň jednu požadovanú značku. - not_contain_synonym_tags: - other: Nemal by obsahovať synonymické značky. - cannot_update: - other: Žiadne povolenie na aktualizáciu. - is_used_cannot_delete: - other: You cannot delete a tag that is in use. - cannot_set_synonym_as_itself: - other: Synonymum aktuálnej značky nemôžete nastaviť ako samotnú. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: The from name cannot be a email address. - theme: - not_found: - other: Téma sa nenašla. - revision: - review_underway: - other: Momentálne nie je možné upravovať, vo fronte na kontrolu je verzia. - no_permission: - other: No permission to revise. - user: - external_login_missing_user_id: - other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. - external_login_unbinding_forbidden: - other: Please set a login password for your account before you remove this login. - email_or_password_wrong: - other: - other: E-mail a heslo sa nezhodujú. - not_found: - other: Používateľ nenájdený. - suspended: - other: Používateľ bol pozastavený. - username_invalid: - other: Používateľské meno je neplatné. - username_duplicate: - other: Používateľské meno sa už používa. - set_avatar: - other: Nastavenie avatara zlyhalo. - cannot_update_your_role: - other: Svoju rolu nemôžete zmeniť. - not_allowed_registration: - other: Currently the site is not open for registration. - not_allowed_login_via_password: - other: Currently the site is not allowed to login via password. - access_denied: - other: Access denied - page_access_denied: - other: You do not have access to this page. - add_bulk_users_format_error: - other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Read Config zlyhal - database: - connection_failed: - other: Databázové pripojenie zlyhalo - create_table_failed: - other: Vytvorenie tabuľky zlyhalo - install: - create_config_failed: - other: Nie je možné vytvoriť súbor config.yaml. - upload: - unsupported_file_format: - other: Nepodporovaný formát súboru. - site_info: - config_not_found: - other: Site config not found. - badge: - object_not_found: - other: Badge object not found - reason: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude_or_abusive: - name: - other: rude or abusive - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - a_duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - placeholder: - other: Enter the existing question link - not_a_answer: - name: - other: not an answer - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." - no_longer_needed: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - something: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - placeholder: - other: Let us know specifically what you are concerned about - community_specific: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - not_clarity: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - looks_ok: - name: - other: looks OK - desc: - other: This post is good as-is and not low quality. - needs_edit: - name: - other: needs edit, and I did it - desc: - other: Improve and correct problems with this post yourself. - needs_close: - name: - other: needs close - desc: - other: A closed question can't answer, but still can edit, vote and comment. - needs_delete: - name: - other: needs delete - desc: - other: This post will be deleted. - question: - close: - duplicate: - name: - other: nevyžiadaná pošta - desc: - other: Táto otázka už bola položená a už má odpoveď. - guideline: - name: - other: dôvod špecifický pre komunitu - desc: - other: Táto otázka nespĺňa pokyny pre komunitu. - multiple: - name: - other: potrebuje podrobnosti alebo jasnosť - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: niečo iné - desc: - other: Tento príspevok vyžaduje iný dôvod, ktorý nie je uvedený vyššie. - operation_type: - asked: - other: požiadaný - answered: - other: zodpovedaný - modified: - other: upravený - deleted_title: - other: Deleted question - questions_title: - other: Questions - tag: - tags_title: - other: Tags - no_description: - other: The tag has no description. - notification: - action: - update_question: - other: aktualizovaná otázka - answer_the_question: - other: zodpovedaná otázka - update_answer: - other: aktualizovaná odpoveď - accept_answer: - other: prijatá odpoveď - comment_question: - other: komentovaná otázka - comment_answer: - other: komentovaná odpoveď - reply_to_you: - other: odpovedal vám - mention_you: - other: spomenul vás - your_question_is_closed: - other: Vaša otázka bola uzavretá - your_question_was_deleted: - other: Vaša otázka bola odstránená - your_answer_was_deleted: - other: Vaša odpoveď bola odstránená - your_comment_was_deleted: - other: Váš komentár bol odstránený - up_voted_question: - other: upvoted question - down_voted_question: - other: downvoted question - up_voted_answer: - other: upvoted answer - down_voted_answer: - other: downvoted answer - up_voted_comment: - other: upvoted comment - invited_you_to_answer: - other: invited you to answer - earned_badge: - other: You've earned the "{{.BadgeName}}" badge - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Confirm your new email address" - body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} answered your question" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n

        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_question: - title: - other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Password reset" - body: - other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - register: - title: - other: "[{{.SiteName}}] Confirm your new account" - body: - other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - test: - title: - other: "[{{.SiteName}}] Test Email" - body: - other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: - upvote: - other: upvote - upvoted: - other: upvoted - downvote: - other: downvote - downvoted: - other: downvoted - accept: - other: accept - accepted: - other: accepted - edit: - other: edit - review: - queued_post: - other: Queued post - flagged_post: - other: Flagged post - suggested_post_edit: - other: Suggested edits - reaction: - tooltip: - other: "{{ .Names }} and {{ .Count }} more..." - badge: - default_badges: - autobiographer: - name: - other: Autobiographer - desc: - other: Filled out profile information. - certified: - name: - other: Certified - desc: - other: Completed our new user tutorial. - editor: - name: - other: Editor - desc: - other: First post edit. - first_flag: - name: - other: First Flag - desc: - other: First flagged a post. - first_upvote: - name: - other: First Upvote - desc: - other: First up voted a post. - first_link: - name: - other: First Link - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: First Share - desc: - other: First shared a post. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Leave 5 comments. - new_user_of_the_month: - name: - other: New User of the Month - desc: - other: Outstanding contributions in their first month. - read_guidelines: - name: - other: Read Guidelines - desc: - other: Read the [community guidelines]. - reader: - name: - other: Reader - desc: - other: Read every answers in a topic with more than 10 answers. - welcome: - name: - other: Welcome - desc: - other: Received a up vote. - nice_share: - name: - other: Nice Share - desc: - other: Shared a post with 25 unique visitors. - good_share: - name: - other: Good Share - desc: - other: Shared a post with 300 unique visitors. - great_share: - name: - other: Great Share - desc: - other: Shared a post with 1000 unique visitors. - out_of_love: - name: - other: Out of Love - desc: - other: Used 50 up votes in a day. - higher_love: - name: - other: Higher Love - desc: - other: Used 50 up votes in a day 5 times. - crazy_in_love: - name: - other: Crazy in Love - desc: - other: Used 50 up votes in a day 20 times. - promoter: - name: - other: Promoter - desc: - other: Invited a user. - campaigner: - name: - other: Campaigner - desc: - other: Invited 3 basic users. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: Thank You - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Active member for a year, posted at least once. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Ako formátovať - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Predch - next: Ďalšie - page_title: - question: Otázka - questions: Otázky - tag: Značka - tags: Značky - tag_wiki: značka wiki - create_tag: Vytvoriť štítok - edit_tag: Upraviť značku - ask_a_question: Create Question - edit_question: Úpraviť otázku - edit_answer: Úpraviť odpoveť - search: Vyhľadávanie - posts_containing: Príspevky obsahujúce - settings: Nastavenie - notifications: Oznámenia - login: Prihlásiť sa - sign_up: Prihlásiť Se - account_recovery: Obnovenie účtu - account_activation: Aktivácia účtu - confirm_email: Potvrď e-mail - account_suspended: Účet pozastavený - admin: Administrátor - change_email: Upraviť e-mail - install: Odpoveď Inštalácia - upgrade: Answer Upgrade - maintenance: Údržba webových stránok - users: Užívatelia - oauth_callback: Processing - http_404: HTTP chyba 404 - http_50X: HTTP chyba 403 - http_403: HTTP Error 403 - logout: Log Out - posts: Posts - notifications: - title: Oznámenia - inbox: Doručená pošta - achievement: Úspechy - new_alerts: New alerts - all_read: Označiť všetko ako prečítané - show_more: Zobraziť viac - someone: Someone - inbox_type: - all: All - posts: Posts - invites: Invites - votes: Votes - answer: Answer - question: Question - badge_award: Badge - suspended: - title: Váš účet bol pozastavený - until_time: "Váš účet bol pozastavený do {{ time }}." - forever: Tento používateľ bol navždy pozastavený. - end: Nespĺňate pokyny pre komunitu. - contact_us: Contact us - editor: - blockquote: - text: Blockquote - bold: - text: Silný - chart: - text: Rebríček - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Ganttov diagram - pie_chart: Koláčový graf - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Kód - msg: - empty: Code cannot be empty. - language: - label: Jazyk - placeholder: Automatic detection - btn_cancel: Zrušiť - btn_confirm: Pridať - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Pomoc - hr: - text: Horizontal rule - image: - text: Obrázok - add_image: Pridať obrázok - tab_image: Nahrať obrázok - form_image: - fields: - file: - label: Image file - btn: Vyberte obrázok - msg: - empty: Názov súboru nemôže byť prázdny. - only_image: Povolené sú iba obrázkové súbory. - max_size: File size cannot exceed {{size}} MB. - desc: - label: Popis - tab_url: URL obrázka - form_url: - fields: - url: - label: URL obrázka - msg: - empty: URL obrázka nemôže byť prázdna. - name: - label: Description - btn_cancel: Zrušiť - btn_confirm: Pridať - uploading: Nahráva sa - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hypertextový odkaz - add_link: Pridať hypertextový odkaz - form: - fields: - url: - label: URL - msg: - empty: URL adresa nemôže byť prázdna. - name: - label: Popis - btn_cancel: Zrušiť - btn_confirm: Pridať - ordered_list: - text: Numbered list - unordered_list: - text: Bulleted list - table: - text: Table - heading: Heading - cell: Bunka - file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: Tento príspevok uzatváram ako... - btn_cancel: Zrušiť - btn_submit: Potvrdiť - remark: - empty: Nemôže byť prázdny. - msg: - empty: Vyberte dôvod. - report_modal: - flag_title: Nahlasujem nahlásenie tohto príspevku ako... - close_title: Tento príspevok zatváram ako ... - review_question_title: Kontrola otázky - review_answer_title: Kontrola odpovede - review_comment_title: Kontrola komentára - btn_cancel: Zrušiť - btn_submit: Potvrdiť - remark: - empty: Nemôže byť prázdny. - msg: - empty: Vyberte dôvod. - not_a_url: URL format is incorrect. - url_not_match: URL origin does not match the current website. - tag_modal: - title: Vytvorte novú značku - form: - fields: - display_name: - label: Display name - msg: - empty: Zobrazovaný názov nemôže byť prázdny. - range: Zobrazovaný názov do 35 znakov. - slug_name: - label: URL slug - desc: URL slug do 35 znakov. - msg: - empty: URL slug nemôže byť prázdny. - range: URL slug do 35 znakov. - character: URL slug obsahuje nepovolenú znakovú sadu. - desc: - label: Opis - revision: - label: Revision - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_cancel: Zrušiť - btn_submit: Potvrdiť - btn_post: Post new tag - tag_info: - created_at: Vytvorená - edited_at: Upravená - history: História - synonyms: - title: Synonymá - text: Nasledujúce značky budú premapované na - empty: Nenašli sa žiadne synonymá. - btn_add: Pridajte synonymum - btn_edit: Upraviť - btn_save: Uložiť - synonyms_text: Nasledujúce značky budú premapované na - delete: - title: Odstrániť túto značku - tip_with_posts: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - tip_with_synonyms: >- -

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        - tip: Naozaj chcete odstrániť? - close: Zavrieť - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Upraviť značku - default_reason: Upraviť značku - default_first_reason: Add tag - btn_save_edits: Uložiť úpravy - btn_cancel: Zrušiť - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [o] HH:mm" - now: teraz - x_seconds_ago: "pred {{count}}s" - x_minutes_ago: "pred {{count}}m" - x_hours_ago: "pred {{count}}h" - hour: hodina - day: deň - hours: hours - days: days - month: month - months: months - year: year - reaction: - heart: heart - smile: smile - frown: frown - btn_label: add or remove reactions - undo_emoji: undo {{ emoji }} reaction - react_emoji: react with {{ emoji }} - unreact_emoji: unreact with {{ emoji }} - comment: - btn_add_comment: Pridať komentár - reply_to: Odpovedať - btn_reply: Odpovedať - btn_edit: Upraviť - btn_delete: Zmazať - btn_flag: Vlajka - btn_save_edits: Uložiť zmeny - btn_cancel: Zrušiť - show_more: "{{count}} more comments" - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - tip_vote: It adds something useful to the post - edit_answer: - title: Uprav odpoveď - default_reason: Uprav odpoveď - default_first_reason: Add answer - form: - fields: - revision: - label: Revízia - answer: - label: Odpoveď - feedback: - characters: Obsah musí mať dĺžku najmenej 6 znakov. - edit_summary: - label: Edit summary - placeholder: >- - Stručne vysvetlite svoje zmeny (opravený pravopis, opravená gramatika, vylepšené formátovanie) - btn_save_edits: Uložiť úpravy - btn_cancel: Zrušiť - tags: - title: Značky - sort_buttons: - popular: Populárne - name: názov - newest: Newest - button_follow: Sledovať - button_following: Sledované - tag_label: otázky - search_placeholder: Filtrujte podľa názvu značky - no_desc: Značka nemá popis. - more: Viac - wiki: Wiki - ask: - title: Create Question - edit_title: Upraviť otázku - default_reason: Upraviť otázku - default_first_reason: Create question - similar_questions: Podobné otázky - form: - fields: - revision: - label: Revízia - title: - label: Názov - placeholder: What's your topic? Be specific. - msg: - empty: Názov nemôže byť prázdny. - range: Názov do 150 znakov - body: - label: Telo - msg: - empty: Telo nemôže byť prázdne. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Značky -- - msg: - empty: Štítky nemôžu byť prázdne. - answer: - label: Odpoveď - msg: - empty: Odpoveď nemôže byť prázdna. - edit_summary: - label: Edit summary - placeholder: >- - Stručne vysvetlite svoje zmeny (opravený pravopis, opravená gramatika, vylepšené formátovanie) - btn_post_question: Uverejnite svoju otázku - btn_save_edits: Uložiť úpravy - answer_question: Odpovedzte na svoju vlastnú otázku - post_question&answer: Uverejnite svoju otázku a odpoveď - tag_selector: - add_btn: Pridať značku - create_btn: Vytvoriť novú značku - search_tag: Vyhľadať značku -- - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: Nezodpovedajú žiadne značky - tag_required_text: Povinný štítok (aspoň jeden) - header: - nav: - question: Otázky - tag: Značky - user: Užívatelia - badges: Badges - profile: Profil - setting: Nastavenia - logout: Odhlásiť sa - admin: Správca - review: Preskúmanie - bookmark: Bookmarks - moderation: Moderation - search: - placeholder: Vyhľadávanie - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Zmena - loading: načítavanie... - pic_auth_code: - title: captcha - placeholder: Zadajte vyššie uvedený text - msg: - empty: Captcha nemôže byť prázdna. - inactive: - first: >- - Ste takmer na konci! Poslali sme Vám aktivačný mail na adresu {{mail}}. K aktivácií účtu postupujte prosím podľa pokynov v e-maily. - info: "Ak neprichádza, skontrolujte priečinok spamu." - another: >- - Poslali sme vám ďalší aktivačný e-mail na adresu {{mail}}. Môže to trvať niekoľko minút; Nezabudnite skontrolovať priečinok spamu. - btn_name: Opätovne odoslať aktivačný e-mail - change_btn_name: Zmeniť e-mail - msg: - empty: Nemôže byť prázdny. - resend_email: - url_label: Are you sure you want to resend the activation email? - url_text: You can also give the activation link above to the user. - login: - login_to_continue: Pre pokračovanie sa prihláste - info_sign: Nemáte účet? <1>Sign up - info_login: Máte už účet? <1>Log in - agreements: Registráciou súhlasíte s <1>zásadami ochrany osobných údajov a <3>podmienkami služby. - forgot_pass: Zabudli ste heslo? - name: - label: Prihlasovacie meno - msg: - empty: Prihlasovacie meno nemôže byť prázdne. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: E-mail - msg: - empty: E-mail nemôže byť prázdny. - password: - label: Heslo - msg: - empty: Heslo nemôže byť prázdne. - different: Heslá zadané na oboch stranách sú nekonzistentné - account_forgot: - page_title: Zabudli ste heslo - btn_name: Pošlite mi e-mail na obnovenie - send_success: >- - Ak sa účet zhoduje s {{mail}}, tak by ste mali čoskoro dostať e-mail s pokynmi, ako resetovať svoje heslo. - email: - label: E-mail - msg: - empty: E-mail nemôže byť prázdny. - change_email: - btn_cancel: Zrušiť - btn_update: Aktualizovať e-mailovú adresu - send_success: >- - Ak sa účet zhoduje s {{mail}}, tak by ste mali čoskoro dostať e-mail s pokynmi, ako resetovať svoje heslo. - email: - label: New email - msg: - empty: E-mail nemôže byť prázdny. - oauth: - connect: Connect with {{ auth_name }} - remove: Remove {{ auth_name }} - oauth_bind_email: - subtitle: Add a recovery email to your account. - btn_update: Update email address - email: - label: Email - msg: - empty: Email cannot be empty. - modal_title: Email already existes. - modal_content: This email address already registered. Are you sure you want to connect to the existing account? - modal_cancel: Change email - modal_confirm: Connect to the existing account - password_reset: - page_title: Resetovanie hesla - btn_name: Obnoviť heslo - reset_success: >- - Úspešne ste zmenili svoje heslo; Budete presmerovaný na prihlásenie. - link_invalid: >- - Ospravedlňujeme sa, tento odkaz na obnovenie hesla už nie je platný. Možno už došlo k resetovaniu vašho hesla? - to_login: Continue to log in page - password: - label: Heslo - msg: - empty: Heslo nemôže byť prázdne. - length: Dĺžka musí byť medzi 8 a 32 - different: Heslá zadané na oboch stranách sú nekonzistentné - password_confirm: - label: Confirm new password - settings: - page_title: Nastavenia - goto_modify: Go to modify - nav: - profile: Profil - notification: Oznámenia - account: Účet - interface: Rozhranie - profile: - heading: Profil - btn_name: Uložiť - display_name: - label: Display name - msg: Zobrazované meno nemôže byť prázdne. - msg_range: Display name must be 2-30 characters in length. - username: - label: Užívateľské meno - caption: Ľudia vás môžu spomenúť ako „@používateľské meno“. - msg: Užívateľské meno nemôže byť prázdne. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile image - gravatar: Gravatar - gravatar_text: You can change image on - custom: Vlastný - custom_text: Môžete nahrať svoj obrázok. - default: Systém - msg: Nahrajte avatara prosím - bio: - label: About me - website: - label: Webová stránka - placeholder: "https://priklad.com" - msg: Nesprávny formát webovej stránky - location: - label: Poloha - placeholder: "Mesto, Krajina" - notification: - heading: Email Notifications - turn_on: Turn on - inbox: - label: Inbox notifications - description: Answers to your questions, comments, invites, and more. - all_new_question: - label: All new questions - description: Get notified of all new questions. Up to 50 questions per week. - all_new_question_for_following_tags: - label: All new questions for following tags - description: Get notified of new questions for following tags. - account: - heading: Účet - change_email_btn: Zmeniť e-mail - change_pass_btn: Zmeniť heslo - change_email_info: >- - Na túto adresu sme poslali e-mail. Postupujte podľa pokynov na potvrdenie. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - pass: - label: Current password - msg: Password cannot be empty. - password_title: Heslo - current_pass: - label: Current password - msg: - empty: Current password cannot be empty. - length: Dĺžka musí byť medzi 8 a 32. - different: Dve zadané heslá sa nezhodujú. - new_pass: - label: New password - pass_confirm: - label: Confirm new password - interface: - heading: Rozhranie - lang: - label: Interface language - text: Jazyk používateľského rozhrania. Zmení sa pri obnove stránky. - my_logins: - title: My logins - label: Log in or sign up on this site using these accounts. - modal_title: Remove login - modal_content: Are you sure you want to remove this login from your account? - modal_confirm_btn: Remove - remove_success: Removed successfully - toast: - update: aktualizácia úspešna - update_password: Heslo bolo úspešne zmenené. - flag_success: Ďakujeme za nahlásenie. - forbidden_operate_self: Zakázané operovať seba - review: Vaša revízia sa zobrazí po preskúmaní. - sent_success: Sent successfully - related_question: - title: Related - answers: odpovede - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: People Asked - desc: Select people who you think might know the answer. - invite: Invite to answer - add: Add people - search: Search people - question_detail: - action: Action - created: Created - Asked: Opýtané - asked: opýtané - update: Aktualizované - Edited: Edited - edit: upravené - commented: commented - Views: Videné - Follow: Sledovať - Following: Sledované - follow_tip: Follow this question to receive notifications - answered: zodpovedaný - closed_in: Uzatvorené - show_exist: Ukázať existujúcu otázku. - useful: Useful - question_useful: It is useful and clear - question_un_useful: It is unclear or not useful - question_bookmark: Bookmark this question - answer_useful: It is useful - answer_un_useful: It is not useful - answers: - title: Odpovede - score: Skóre - newest: Najnovšie - oldest: Oldest - btn_accept: Súhlasiť - btn_accepted: Prijaté - write_answer: - title: Vaša odpoveď - edit_answer: Edit my existing answer - btn_name: Pošlite svoju odpoveď - add_another_answer: Pridajte ďalšiu odpoveď - confirm_title: Pokračovať v odpovedi - continue: Pokračovať - confirm_info: >- -

        Ste si istí, že chcete pridať ďalšiu odpoveď?

        Mohli by ste namiesto toho použiť úpravu na vylepšenie svojej už existujúcej odpovede.

        - empty: Odpoveď nemôže byť prázdna. - characters: Minimálna dĺžka obsahu musí byť 6 znakov. - tips: - header_1: Thanks for your answer - li1_1: Please be sure to answer the question. Provide details and share your research. - li1_2: Back up any statements you make with references or personal experience. - header_2: But avoid ... - li2_1: Asking for help, seeking clarification, or responding to other answers. - reopen: - confirm_btn: Reopen - title: Znovu otvoriť tento príspevok - content: Ste si istý, že ho chcete znovu otvoriť? - list: - confirm_btn: List - title: List this post - content: Are you sure you want to list? - unlist: - confirm_btn: Unlist - title: Unlist this post - content: Are you sure you want to unlist? - pin: - title: Pin this post - content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. - confirm_btn: Pin - delete: - title: Odstrániť tento príspevok - question: >- - Neodporúčame mazanie otázok s odpoveďmi pretože týmto oberáte budúcich čitateľov o tieto vedomostí.

        Opakované mazanie zodpovedaných otázok môže mať za následok zablokovanie možnosti kladenia otázok z vášho účtu. Ste si istí, že chcete otázku odstrániť? - answer_accepted: >- -

        Neodporúčame odstránenie akceptovanej odpovede pretože týmto oberáte budúcich čitateľov o tieto vedomostí.

        Opakované mazanie akceptovaných odpovedí môže mať za následok zablokovanie možnosti odpovedať z vášho účtu. Ste si istí, že chcete odstrániť odpoveď? - other: Ste si istí, že ju chcete odstrániť? - tip_answer_deleted: Táto odpoveď bola odstránená - undelete_title: Undelete this post - undelete_desc: Are you sure you wish to undelete? - btns: - confirm: Potvrdiť - cancel: Zrušiť - edit: Edit - save: Uložiť - delete: Vymazať - undelete: Undelete - list: List - unlist: Unlist - unlisted: Unlisted - login: Prihlásiť sa - signup: Registrovať sa - logout: Odhlásiť sa - verify: Preveriť - create: Create - approve: Schváliť - reject: Odmietnuť - skip: Preskočiť - discard_draft: Zahodiť koncept - pinned: Pinned - all: All - question: Question - answer: Answer - comment: Comment - refresh: Refresh - resend: Resend - deactivate: Deactivate - active: Active - suspend: Suspend - unsuspend: Unsuspend - close: Close - reopen: Reopen - ok: OK - light: Light - dark: Dark - system_setting: System setting - default: Default - reset: Reset - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignore - submit: Submit - normal: Normal - closed: Closed - deleted: Deleted - deleted_permanently: Deleted permanently - pending: Pending - more: More - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Výsledky vyhľadávania - keywords: Kľúčové slová - options: možnosti - follow: Sledovať - following: Sledované - counts: "{{count}} výsledky" - counts_loading: "... Results" - more: Viac - sort_btns: - relevance: Relevantnosť - newest: Najnovšie - active: Aktívne - score: Skóre - more: Viac - tips: - title: Tipy na pokročilé vyhľadávanie - tag: "<1>[tag] hľadať v rámci značky" - user: "<1>user:username hľadať podľa autora" - answer: "<1>answers:0 nezodpovedané otázky" - score: "<1>score:3 Príspevky so skóre 3+" - question: "<1>is:question hľadať otázky" - is_answer: "<1>is:answer hľadať odpovede" - empty: Nemohli sme nič nájsť.
        Vyskúšajte iné alebo menej špecifické kľúčové slová. - share: - name: Zdieľať - copy: Skopírovať odkaz - via: Zdieľajte príspevok cez... - copied: Skopírované - facebook: Zdieľať na Facebooku - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post. - modal_confirm: - title: Chyba... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Váš nový účet je potvrdený; Budete presmerovaný na domovskú stránku. - link: Pokračovať na domovskú stránku - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: Váš e-mail bol aktualizovaný. - confirm_new_email_invalid: >- - Ospravedlňujeme sa, tento potvrdzovací odkaz už nie je platný. Váš e-mail je už môžno zmenený. - unsubscribe: - page_title: Zrušiť odber - success_title: Úspešne zrušenie odberu - success_desc: Boli ste úspešne odstránený zo zoznamu odoberateľov a nebudete od nás dostávať žiadne ďalšie e-maily. - link: Zmeniť nastavenia - question: - following_tags: Nasledujúce značky - edit: Upraviť - save: Uložiť - follow_tag_tip: Postupujte podľa značiek a upravte si zoznam otázok. - hot_questions: Najlepšie otázky - all_questions: Všetky otázky - x_questions: "{{ count }} otázky/otázok" - x_answers: "{{ count }} odpovede/odpovedí" - x_posts: "{{ count }} Posts" - questions: Otázky - answers: Odpovede - newest: Najnovšie - active: Aktívne - hot: Hot - frequent: Frequent - recommend: Recommend - score: Skóre - unanswered: Nezodpovedané - modified: upravené - answered: zodpovedané - asked: opýtané - closed: uzatvorené - follow_a_tag: Postupujte podľa značky - more: Viac - personal: - overview: Prehľad - answers: Odpovede - answer: odpoveď - questions: Otázky - question: otázka - bookmarks: Záložky - reputation: Reputácia - comments: Komentáre - votes: Hlasovanie - badges: Badges - newest: Najnovšie - score: Skóre - edit_profile: Edit profile - visited_x_days: "Navštívené {{ count }} dni" - viewed: Videné - joined: Pripojené - comma: "," - last_login: Videné - about_me: O mne - about_me_empty: "// Dobrý deň, svet!" - top_answers: Najlepšie odpovede - top_questions: Najlepšie otázky - stats: Štatistiky - list_empty: Nenašli sa žiadne príspevky.
        Možno by ste chceli vybrať inú kartu? - content_empty: No posts found. - accepted: Prijaté - answered: zodpovedané - asked: opýtané - downvoted: downvoted - mod_short: MOD - mod_long: Moderátori - x_reputation: reputácia - x_votes: prijatých hlasov - x_answers: odpovede - x_questions: otázky - recent_badges: Recent Badges - install: - title: Installation - next: Ďalšie - done: Hotový - config_yaml_error: Nie je možné vytvoriť súbor config.yaml. - lang: - label: Please choose a language - db_type: - label: Database engine - db_username: - label: Užívateľské meno - placeholder: super užívateľ - msg: Užívateľské meno nemôže byť prázdne. - db_password: - label: Heslo - placeholder: super užívateľ - msg: Heslo nemôže byť prázdne. - db_host: - label: Database host - placeholder: "db:3306" - msg: Database host cannot be empty. - db_name: - label: Database name - placeholder: odpoveď - msg: Database name cannot be empty. - db_file: - label: Database file - placeholder: /data/answer.db - msg: Database file cannot be empty. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Vytvoriť config.yaml - label: Vytvorený súbor Config.yaml. - desc: >- - Súbor <1>config.yaml môžete vytvoriť manuálne v adresári <1>/var/www/xxx/ a vložiť doň nasledujúci text. - info: Potom, čo ste to urobili, kliknite na tlačidlo „Ďalej“. - site_information: Informácie o stránke - admin_account: Správca - site_name: - label: Site name - msg: Site name cannot be empty. - msg_max_length: Site name must be at maximum 30 characters in length. - site_url: - label: URL stránky - text: Adresa vašej stránky. - msg: - empty: URL stránky nemôže byť prázdny. - incorrect: Nesprávny formát adresy URL. - max_length: Site URL must be at maximum 512 characters in length. - contact_email: - label: Contact email - text: E-mailová adresa kontaktu zodpovedného za túto stránku. - msg: - empty: Contact email cannot be empty. - incorrect: Contact email incorrect format. - login_required: - label: Private - switch: Login required - text: Only logged in users can access this community. - admin_name: - label: Meno - msg: Meno nemôže byť prázdne. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Heslo - text: >- - Na prihlásenie budete potrebovať toto heslo. Uložte si ho na bezpečné miesto. - msg: Heslo nemôže byť prázdne. - msg_min_length: Password must be at least 8 characters in length. - msg_max_length: Password must be at maximum 32 characters in length. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: E-mail - text: Na prihlásenie budete potrebovať tento e-mail. - msg: - empty: E-mail nemôže byť prázdny. - incorrect: Nesprávny formát e-mailu - ready_title: Your site is ready - ready_desc: >- - Ak niekedy budete chcieť zmeniť viac nastavení, navštívte stránku <1>admin section; Nájdete ju v ponuke stránok. - good_luck: "„Bavte sa a veľa šťastia!“" - warn_title: Upozornenie - warn_desc: >- - Súbor <1>config.yaml už existuje. Ak potrebujete resetovať niektorú z konfiguračných položiek v tomto súbore, najskôr ju odstráňte. - install_now: Môžete skúsiť <1>installing now. - installed: Už nainštalované - installed_desc: >- - Zdá sa, že ste už aplikáciu answer nainštalovali. Ak chcete aplikáciu preinštalovať, najprv vymažte staré tabuľky z databázy. - db_failed: Databázové pripojenie zlyhalo - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: názory - votes: hlasy - answers: odpovede - accepted: prijaté - page_error: - http_error: HTTP Error {{ code }} - desc_403: You don't have permission to access this page. - desc_404: Unfortunately, this page doesn't exist. - desc_50X: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "Prebieha údržba, čoskoro sa vrátime." - nav_menus: - dashboard: Nástenka - contents: Obsah - questions: Otázky - answers: Odpovede - users: Užívatelia - badges: Badges - flags: Vlajky - settings: Nastavenia - general: Všeobecné - interface: Rozhranie - smtp: SMTP - branding: Budovanie značky - legal: legálne - write: písať - terms: Terms - tos: Podmienky služby - privacy: Súkromie - seo: SEO - customize: Prispôsobiť - themes: Témy - login: Prihlásiť sa - privileges: Privileges - plugins: Plugins - installed_plugins: Installed Plugins - apperance: Appearance - website_welcome: Welcome to {{site_name}} - user_center: - login: Login - qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. - login_failed_email_tip: Login failed, please allow this app to access your email information before try again. - badges: - modal: - title: Congratulations - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - admin: - admin_header: - title: Administrátor - dashboard: - title: Nástenka - welcome: Welcome to Admin! - site_statistics: Site statistics - questions: "Otázky:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "Odpovede:" - comments: "Komentáre:" - votes: "Hlasy:" - users: "Users:" - flags: "Vlajky:" - reviews: "Reviews:" - site_health: Site health - version: "Verzia:" - https: "HTTPS:" - upload_folder: "Upload folder:" - run_mode: "Running mode:" - private: Private - public: Public - smtp: "SMTP:" - timezone: "Časové pásmo:" - system_info: System info - go_version: "Go version:" - database: "Database:" - database_size: "Database size:" - storage_used: "Použité úložisko:" - uptime: "Doba prevádzky:" - links: Links - plugins: Plugins - github: GitHub - blog: Blog - contact: Contact - forum: Forum - documents: Dokumenty - feedback: Spätná väzba - support: Podpora - review: Preskúmanie - config: Konfigurácia - update_to: Aktualizovať na - latest: Posledné - check_failed: Skontrolovať zlyhanie - "yes": "Áno" - "no": "Nie" - not_allowed: Nepovolené - allowed: Povolené - enabled: Povolené - disabled: Zablokované - writable: Writable - not_writable: Not writable - flags: - title: Vlajky - pending: Prebiehajúce - completed: Dokončené - flagged: Označené - flagged_type: Flagged {{ type }} - created: Vytvorené - action: Akcia - review: Preskúmanie - user_role_modal: - title: Zmeňte rolu používateľa na... - btn_cancel: Zrušiť - btn_submit: Odovzdať - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - edit_profile_modal: - title: Edit profile - form: - fields: - display_name: - label: Display name - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Invalid Email Address. - edit_success: Edited successfully - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - users: - label: Bulk add user - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separate “name, email, password” with commas. One user per line. - msg: "Please enter the user's email, one per line." - display_name: - label: Display name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - users: - title: Používatelia - name: Meno - email: E-mail - reputation: Reputácia - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Stav - role: Rola - action: Akcia - change: Zmena - all: Všetko - staff: Personál - more: More - inactive: Neaktívne - suspended: Pozastavené - deleted: Vymazané - normal: Normálné - Moderator: Moderátor - Admin: Správca - User: Používateľ - filter: - placeholder: "Filter podľa mena, používateľ: ID" - set_new_password: Nastaviť nové heslo - edit_profile: Edit profile - change_status: Zmentiť stavu - change_role: Zmeniť rolu - show_logs: Zobraziť protokoly - add_user: Pridať používateľa - deactivate_user: - title: Deactivate user - content: An inactive user must re-validate their email. - delete_user: - title: Delete this user - content: Are you sure you want to delete this user? This is permanent! - remove: Remove their content - label: Remove all questions, answers, comments, etc. - text: Don’t check this if you wish to only delete the user’s account. - suspend_user: - title: Suspend this user - content: A suspended user can't log in. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Otázky - unlisted: Unlisted - post: poslané - votes: Hlasy - answers: Odpovede - created: Vytvorené - status: Stav - action: Akcia - change: Zmena - pending: Pending - filter: - placeholder: "Filter podľa názvu, otázka:id" - answers: - page_title: Odpovede - post: Poslané - votes: Hlasy - created: Vytvorené - status: Stav - action: Akcia - change: Zmena - filter: - placeholder: "Filter podľa názvu, odpoveď:id" - general: - page_title: Všeobecné - name: - label: Site name - msg: Názov stránky nemôže byť prázdny. - text: "Názov tejto lokality, ako sa používa v značke názvu." - site_url: - label: URL stránky - msg: Adresa Url stránky nemôže byť prázdna. - validate: Prosím uveďte platnú webovú adresu. - text: Adresa vašej stránky. - short_desc: - label: Short site description - msg: Krátky popis stránky nemôže byť prázdny. - text: "Krátky popis, ako sa používa v značke názvu na domovskej stránke." - desc: - label: Site description - msg: Popis stránky nemôže byť prázdny. - text: "Opíšte túto stránku jednou vetou, ako sa používa v značke meta description." - contact_email: - label: Contact email - msg: Kontaktný e-mail nemôže byť prázdny. - validate: Kontaktný e-mail je neplatný. - text: E-mailová adresa kontaktu zodpovedného za túto stránku. - check_update: - label: Software updates - text: Automatically check for updates - interface: - page_title: Rozhranie - language: - label: Interface language - msg: Jazyk rozhrania nemôže byť prázdny. - text: Jazyk používateľského rozhrania. Zmení sa, keď stránku obnovíte. - time_zone: - label: Časové pásmo - msg: Časové pásmo nemôže byť prázdne. - text: Vyberte si mesto v rovnakom časovom pásme ako vy. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: From email - msg: Z e-mailu nemôže byť prázdne. - text: E-mailová adresa, z ktorej sa odosielajú e-maily. - from_name: - label: From name - msg: Názov od nemôže byť prázdny. - text: Meno, z ktorého sa odosielajú e-maily. - smtp_host: - label: SMTP host - msg: Hostiteľ SMTP nemôže byť prázdny. - text: Váš mailový server. - encryption: - label: Šifrovanie - msg: Šifrovanie nemôže byť prázdne. - text: Pre väčšinu serverov je SSL odporúčaná možnosť. - ssl: SSL - tls: TLS - none: Žiadne - smtp_port: - label: SMTP port - msg: Port SMTP musí byť číslo 1 ~ 65535. - text: Port na váš poštový server. - smtp_username: - label: SMTP username - msg: Používateľské meno SMTP nemôže byť prázdne. - smtp_password: - label: SMTP password - msg: Heslo SMTP nemôže byť prázdne. - test_email_recipient: - label: Test email recipients - text: Zadajte e-mailovú adresu, na ktorú sa budú odosielať testy. - msg: Príjemcovia testovacieho e-mailu sú neplatní - smtp_authentication: - label: Povoliť autentifikáciu - title: SMTP authentication - msg: Overenie SMTP nemôže byť prázdne. - "yes": "Áno" - "no": "Nie" - branding: - page_title: Budovanie značky - logo: - label: Logo - msg: Logo nemôže byť prázdne. - text: Obrázok loga v ľavej hornej časti vašej stránky. Použite široký obdĺžnikový obrázok s výškou 56 a pomerom strán väčším ako 3:1. Ak ho ponecháte prázdne, zobrazí sa text názvu stránky. - mobile_logo: - label: Mobile logo - text: Logo použité na mobilnej verzii vášho webu. Použite široký obdĺžnikový obrázok s výškou 56. Ak pole ponecháte prázdne, použije sa obrázok z nastavenia „logo“. - square_icon: - label: Square icon - msg: Ikona štvorca nemôže byť prázdna. - text: Obrázok použitý ako základ pre ikony metadát. V ideálnom prípade by mal byť väčšií ako 512 x 512. - favicon: - label: favicon - text: Favicon pre váš web. Ak chcete správne fungovať cez CDN, musí to byť png. Veľkosť sa zmení na 32 x 32. Ak zostane prázdne, použije sa „štvorcová ikona“. - legal: - page_title: Legálne - terms_of_service: - label: Terms of service - text: "Tu môžete pridať obsah zmluvných podmienok. Ak už máte dokument umiestnený inde, uveďte tu celú URL adresu." - privacy_policy: - label: Privacy policy - text: "Tu môžete pridať obsah zásad ochrany osobných údajov. Ak už máte dokument umiestnený inde, uveďte tu celú URL adresu." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Písať - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Each user can only write one answer for each question - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Recommend tags - text: "Recommend tags will show in the dropdown list by default." - msg: - contain_reserved: "recommended tags cannot contain reserved tags" - required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags - text: "Každá nová otázka musí mať aspoň jedenu odporúčaciu značku." - reserved_tags: - label: Reserved tags - text: "Reserved tags can only be used by moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: SEO - permalink: - label: trvalý odkaz - text: Vlastné štruktúry URL môžu zlepšiť použiteľnosť a doprednú kompatibilitu vašich odkazov. - robots: - label: robots.txt - text: Toto natrvalo prepíše všetky nastavenia súvisiace so stránkou. - themes: - page_title: Témy - themes: - label: Témy - text: Vyberte existujúcu tému. - color_scheme: - label: Color scheme - navbar_style: - label: Navbar background style - primary_color: - label: Primary color - text: Upraviť farby používané vašími motívmi - css_and_html: - page_title: CSS a HTML - custom_css: - label: Vlastné CSS - text: > - - head: - label: Head - text: > - - header: - label: Hlavička - text: > - - footer: - label: Päta - text: This will insert before </body>. - sidebar: - label: Sidebar - text: This will insert in sidebar. - login: - page_title: Prihlásenie - membership: - title: Členstvo - label: Povoliť nové registrácie - text: Vypnúť, aby sa zabránilo vytvorenie nového účtu hocikým. - email_registration: - title: Email registration - label: Allow email registration - text: Turn off to prevent anyone creating new account through email. - allowed_email_domains: - title: Allowed email domains - text: Email domains that users must register accounts with. One domain per line. Ignored when empty. - private: - title: Súkromné - label: Vyžaduje sa prihlásenie - text: Do tejto komunity majú prístup iba prihlásení používatelia - password_login: - title: Password login - label: Allow email and password login - text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." - installed_plugins: - title: Installed Plugins - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. - filter: - all: All - active: Active - inactive: Inactive - outdated: Outdated - plugins: - label: Plugins - text: Select an existing plugin. - name: Name - version: Version - status: Status - action: Action - deactivate: Deactivate - activate: Activate - settings: Settings - settings_users: - title: Users - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar Base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - profile_editable: - title: Profile editable - allow_update_display_name: - label: Allow users to change their display name - allow_update_username: - label: Allow users to change their username - allow_update_avatar: - label: Allow users to change their profile image - allow_update_bio: - label: Allow users to change their about me - allow_update_website: - label: Allow users to change their website - allow_update_location: - label: Allow users to change their location - privilege: - title: Privileges - level: - label: Reputation required level - text: Choose the reputation required for the privileges - msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 - badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate - filter: - placeholder: Filter by name, badge:id - group: Group - inactive: Inactive - name: Name - show_logs: Show logs - status: Status - title: Badges - form: - optional: (voliteľné) - empty: nemôže byť prázdne - invalid: je neplatné - btn_submit: Uložiť - not_found_props: "Požadovaná vlastnosť {{ key }} nebola nájdená." - select: Select - page_review: - review: Preskúmanie - proposed: navrhované - question_edit: Úprava otázky - answer_edit: Úprava odpovede - tag_edit: Úprava značky - edit_summary: Upraviť súhrn - edit_question: Upraviť otázku - edit_answer: Upraviť odpoveď - edit_tag: Upraviť značku - empty: Nezostali žiadne úlohy kontroly. - approve_revision_tip: Do you approve this revision? - approve_flag_tip: Do you approve this flag? - approve_post_tip: Do you approve this post? - approve_user_tip: Do you approve this user? - suggest_edits: Suggested edits - flag_post: Flag post - flag_user: Flag user - queued_post: Queued post - queued_user: Queued user - filter_label: Type - reputation: reputation - flag_post_type: Flagged this post as {{ type }}. - flag_user_type: Flagged this user as {{ type }}. - edit_post: Edit post - list_post: List post - unlist_post: Unlist post - timeline: - undeleted: zrušené zmazanie - deleted: vymazané - downvote: hlasovať proti - upvote: hlasovať za - accept: akceptované - cancelled: zrušené - commented: komentované - rollback: Návrat - edited: zmenené - answered: odpovedané - asked: spýtané - closed: uzavreté - reopened: znovu otvorené - created: vytvorené - pin: pinned - unpin: unpinned - show: listed - hide: unlisted - title: "História pre" - tag_title: "Časová os pre" - show_votes: "Zobraziť hlasy" - n_or_a: N/A - title_for_question: "Časová os pre" - title_for_answer: "Časová os odpovede na {{ title }} od {{ author }}" - title_for_tag: "Časová os pre značku" - datetime: Dátum a čas - type: Typ - by: Od - comment: Komentár - no_data: "Nič sa nám nepodarilo nájsť." - users: - title: Použivatelia - users_with_the_most_reputation: Users with the highest reputation scores this week - users_with_the_most_vote: Users who voted the most this week - staffs: Zamestnanci našej komunity - reputation: reputácia - votes: hlasy - prompt: - leave_page: Ste si istý, že chcete opustiť stránku? - changes_not_save: Vaše zmeny nemusia byť uložené. - draft: - discard_confirm: Naozaj chcete zahodiť svoj koncept? - messages: - post_deleted: Tento príspevok bol odstránený. - post_cancel_deleted: This post has been undeleted. - post_pin: This post has been pinned. - post_unpin: This post has been unpinned. - post_hide_list: This post has been hidden from list. - post_show_list: This post has been shown to list. - post_reopen: This post has been reopened. - post_list: This post has been listed. - post_unlist: This post has been unlisted. - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/sq_AL.yaml b/data/i18n/sq_AL.yaml deleted file mode 100644 index 4249c5f03..000000000 --- a/data/i18n/sq_AL.yaml +++ /dev/null @@ -1,1371 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: "Success." - unknown: - other: "Unknown error." - request_format_error: - other: "Request format is not valid." - unauthorized_error: - other: "Unauthorized." - database_error: - other: "Data server error." - role: - name: - user: - other: "User" - admin: - other: "Admin" - moderator: - other: "Moderator" - description: - user: - other: "Default with no special access." - admin: - other: "Have the full power to access the site." - moderator: - other: "Has access to all posts except admin settings." - email: - other: "Email" - password: - other: "Password" - email_or_password_wrong_error: - other: "Email and password do not match." - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: "Answer do not found." - cannot_deleted: - other: "No permission to delete." - cannot_update: - other: "No permission to update." - comment: - edit_without_permission: - other: "Comment are not allowed to edit." - not_found: - other: "Comment not found." - email: - duplicate: - other: "Email already exists." - need_to_be_verified: - other: "Email should be verified." - verify_url_expired: - other: "Email verified URL has expired, please resend the email." - lang: - not_found: - other: "Language file not found." - object: - captcha_verification_failed: - other: "Captcha wrong." - disallow_follow: - other: "You are not allowed to follow." - disallow_vote: - other: "You are not allowed to vote." - disallow_vote_your_self: - other: "You can't vote for your own post." - not_found: - other: "Object not found." - verification_failed: - other: "Verification failed." - email_or_password_incorrect: - other: "Email and password do not match." - old_password_verification_failed: - other: "The old password verification failed" - new_password_same_as_previous_setting: - other: "The new password is the same as the previous one." - question: - not_found: - other: "Question not found." - cannot_deleted: - other: "No permission to delete." - cannot_close: - other: "No permission to close." - cannot_update: - other: "No permission to update." - rank: - fail_to_meet_the_condition: - other: "Rank fail to meet the condition." - report: - handle_failed: - other: "Report handle failed." - not_found: - other: "Report not found." - tag: - not_found: - other: "Tag not found." - recommend_tag_not_found: - other: "Recommend Tag is not exist." - recommend_tag_enter: - other: "Please enter at least one required tag." - not_contain_synonym_tags: - other: "Should not contain synonym tags." - cannot_update: - other: "No permission to update." - cannot_set_synonym_as_itself: - other: "You cannot set the synonym of the current tag as itself." - smtp: - config_from_name_cannot_be_email: - other: "The From Name cannot be a email address." - theme: - not_found: - other: "Theme not found." - revision: - review_underway: - other: "Can't edit currently, there is a version in the review queue." - no_permission: - other: "No permission to Revision." - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: "User not found." - suspended: - other: "User has been suspended." - username_invalid: - other: "Username is invalid." - username_duplicate: - other: "Username is already in use." - set_avatar: - other: "Avatar set failed." - cannot_update_your_role: - other: "You cannot modify your role." - not_allowed_registration: - other: "Currently the site is not open for registration" - config: - read_config_failed: - other: "Read config failed" - database: - connection_failed: - other: "Database connection failed" - create_table_failed: - other: "Create table failed" - install: - create_config_failed: - other: "Can't create the config.yaml file." - report: - spam: - name: - other: "spam" - desc: - other: "This post is an advertisement, or vandalism. It is not useful or relevant to the current topic." - rude: - name: - other: "rude or abusive" - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - duplicate: - name: - other: "a duplicate" - desc: - other: "This question has been asked before and already has an answer." - not_answer: - name: - other: "not an answer" - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether." - not_need: - name: - other: "no longer needed" - desc: - other: "This comment is outdated, conversational or not relevant to this post." - other: - name: - other: "something else" - desc: - other: "This post requires staff attention for another reason not listed above." - question: - close: - duplicate: - name: - other: "spam" - desc: - other: "This question has been asked before and already has an answer." - guideline: - name: - other: "a community-specific reason" - desc: - other: "This question doesn't meet a community guideline." - multiple: - name: - other: "needs details or clarity" - desc: - other: "This question currently includes multiple questions in one. It should focus on one problem only." - other: - name: - other: "something else" - desc: - other: "This post requires another reason not listed above." - operation_type: - asked: - other: "asked" - answered: - other: "answered" - modified: - other: "modified" - notification: - action: - update_question: - other: "updated question" - answer_the_question: - other: "answered question" - update_answer: - other: "updated answer" - accept_answer: - other: "accepted answer" - comment_question: - other: "commented question" - comment_answer: - other: "commented answer" - reply_to_you: - other: "replied to you" - mention_you: - other: "mentioned you" - your_question_is_closed: - other: "Your question has been closed" - your_question_was_deleted: - other: "Your question has been deleted" - your_answer_was_deleted: - other: "Your answer has been deleted" - your_comment_was_deleted: - other: "Your comment has been deleted" -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comment - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to Answer - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name up to 30 characters - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username up to 30 characters - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to Answer - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: "After you've done that, click “Next” button." - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: display_name must be at 2 - 30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8 - 32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/sr_SP.yaml b/data/i18n/sr_SP.yaml deleted file mode 100644 index 25c086f11..000000000 --- a/data/i18n/sr_SP.yaml +++ /dev/null @@ -1,1384 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -#The following fields are used for back-end -backend: - base: - success: - other: Success. - unknown: - other: Unknown error. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - email: - other: Email - password: - other: Password - email_or_password_wrong_error: - other: Email and password do not match. - error: - admin: - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - question: - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - rank: - fail_to_meet_the_condition: - other: Rank fail to meet the condition. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend Tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - smtp: - config_from_name_cannot_be_email: - other: The From Name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to Revision. - user: - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - report: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude: - name: - other: rude or abusive - desc: - other: A reasonable person would find this content inappropriate for respectful discourse. - duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - not_answer: - name: - other: not an answer - desc: - other: This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question, or deleted altogether. - not_need: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - other: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted -#The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Next - page_title: - question: Question - questions: Questions - tag: Tag - tags: Tags - tag_wiki: tag wiki - edit_tag: Edit Tag - ask_a_question: Add Question - edit_question: Edit Question - edit_answer: Edit Answer - search: Search - posts_containing: Posts containing - settings: Settings - notifications: Notifications - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - notifications: - title: Notifications - inbox: Inbox - achievement: Achievements - all_read: Mark all as read - show_more: Show more - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language (optional) - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal Rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image File - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed 4 MB. - desc: - label: Description (optional) - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description (optional) - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered List - unordered_list: - text: Bulleted List - table: - text: Table - heading: Heading - cell: Cell - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display Name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL Slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description (optional) - btn_cancel: Cancel - btn_submit: Submit - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - content: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - content2: Are you sure you wish to delete? - close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - form: - fields: - revision: - label: Revision - display_name: - label: Display Name - slug_name: - label: URL Slug - info: URL slug up to 35 characters. - desc: - label: Description - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: Show more comments - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - edit_answer: - title: Edit Answer - default_reason: Edit answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - ask: - title: Add Question - edit_title: Edit Question - default_reason: Edit question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: Be specific and imagine you're asking a question to another person - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit Summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: "Describe what your question is about, at least one tag is required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - search: - placeholder: Search - footer: - build_on: >- - Built on <1> Answer - the open-source software that powers Q&A communities.
        Made with love © {{cc}}. - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - login: - page_title: Welcome to {{site_name}} - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "A-Z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - page_title: Welcome to {{site_name}} - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New Email - msg: - empty: Email cannot be empty. - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm New Password - settings: - page_title: Settings - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display Name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile Image - gravatar: Gravatar - gravatar_text: You can change image on <1>gravatar.com - custom: Custom - btn_refresh: Refresh - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About Me (optional) - website: - label: Website (optional) - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location (optional) - placeholder: "City, Country" - notification: - heading: Notifications - email: - label: Email Notifications - radio: "Answers to your questions, comments, and more" - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - password_title: Password - current_pass: - label: Current Password - msg: - empty: Current Password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New Password - pass_confirm: - label: Confirm New Password - interface: - heading: Interface - lang: - label: Interface Language - text: User interface language. It will change when you refresh the page. - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - related_question: - title: Related Questions - btn: Add question - answers: answers - question_detail: - Asked: Asked - asked: asked - update: Modified - edit: edited - Views: Viewed - Follow: Follow - Following: Following - answered: answered - closed_in: Closed in - show_exist: Show existing question. - answers: - title: Answers - score: Score - newest: Newest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - reopen: - title: Reopen this post - content: Are you sure you want to reopen? - success: This post has been reopened - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_question_deleted: This post has been deleted - tip_answer_deleted: This answer has been deleted - btns: - confirm: Confirm - cancel: Cancel - save: Save - delete: Delete - login: Log in - signup: Sign up - logout: Log out - verify: Verify - add_question: Add question - approve: Approve - reject: Reject - skip: Skip - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post - modal_confirm: - title: Error... - account_result: - page_title: Welcome to {{site_name}} - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - invalid: >- - Sorry, this account confirmation link is no longer valid. Perhaps your account is already active? - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - newest: Newest - score: Score - edit_profile: Edit Profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - accepted: Accepted - answered: answered - asked: asked - upvote: upvote - downvote: downvote - mod_short: Mod - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please Choose a Language - db_type: - label: Database Engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database Host - placeholder: "db:3306" - msg: Database Host cannot be empty. - db_name: - label: Database Name - placeholder: answer - msg: Database Name cannot be empty. - db_file: - label: Database File - placeholder: /data/answer.db - msg: Database File cannot be empty. - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site Name - msg: Site Name cannot be empty. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - contact_email: - label: Contact Email - text: Email address of key contact responsible for this site. - msg: - empty: Contact Email cannot be empty. - incorrect: Contact Email incorrect format. - admin_name: - label: Name - msg: Name cannot be empty. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_404: - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - desc: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - css-html: CSS/HTML - login: Login - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site Statistics - questions: "Questions:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - active_users: "Active users:" - flags: "Flags:" - site_health_status: Site Health Status - version: "Version:" - https: "HTTPS:" - uploading_files: "Uploading files:" - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System Info - storage_used: "Storage used:" - uptime: "Uptime:" - answer_links: Answer Links - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - created: Created - action: Action - review: Review - change_modal: - title: Change user status to... - btn_cancel: Cancel - btn_submit: Submit - normal_name: normal - normal_desc: A normal user can ask and answer questions. - suspended_name: suspended - suspended_desc: A suspended user can't log in. - deleted_name: deleted - deleted_desc: "Delete profile, authentication associations." - inactive_name: inactive - inactive_desc: An inactive user must re-validate their email. - confirm_title: Delete this user - confirm_content: Are you sure you want to delete this user? This is permanent! - confirm_btn: Delete - msg: - empty: Please select a reason. - status_modal: - title: "Change {{ type }} status to..." - normal_name: normal - normal_desc: A normal post available to everyone. - closed_name: closed - closed_desc: "A closed question can't answer, but still can edit, vote and comment." - deleted_name: deleted - deleted_desc: All reputation gained and lost will be restored. - btn_cancel: Cancel - btn_submit: Submit - btn_next: Next - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created Time - delete_at: Deleted Time - suspend_at: Suspended Time - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - display_name: - label: Display Name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - questions: - page_title: Questions - normal: Normal - closed: Closed - deleted: Deleted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - normal: Normal - deleted: Deleted - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site Name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short Site Description (optional) - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site Description (optional) - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact Email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - interface: - page_title: Interface - logo: - label: Logo (optional) - msg: Site logo cannot be empty. - text: You can upload your image or <1>reset it to the site title text. - theme: - label: Theme - msg: Theme cannot be empty. - text: Select an existing theme. - language: - label: Interface Language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - smtp: - page_title: SMTP - from_email: - label: From Email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From Name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP Host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - none: None - smtp_port: - label: SMTP Port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP Username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP Password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test Email Recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP Authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo (optional) - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square Icon (optional) - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of Service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy Policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - write: - page_title: Write - recommend_tags: - label: Recommend Tags - text: "Please input tag slug above, one tag per line." - required_tag: - title: Required Tag - label: Set recommend tag as required - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved Tags - text: "Reserved tags can only be added to a post by moderator." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - navbar_style: - label: Navbar Style - text: Select an existing theme. - primary_color: - label: Primary Color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: This will insert as - head: - label: Head - text: This will insert before - header: - label: Header - text: This will insert after - footer: - label: Footer - text: This will insert before . - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - form: - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores - users_with_the_most_vote: Users who voted the most - staffs: Our community staff - reputation: reputation - votes: votes diff --git a/data/i18n/sv_SE.yaml b/data/i18n/sv_SE.yaml deleted file mode 100644 index 9690e1c66..000000000 --- a/data/i18n/sv_SE.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Åtgärden lyckades - unknown: - other: Okänt fel. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Access saknas - database_error: - other: Data server error. - forbidden_error: - other: Förbjudet. - duplicate_request_error: - other: Dubblett inlämning. - action: - report: - other: Flagga - edit: - other: Redigera - delete: - other: Radera - close: - other: Stäng - reopen: - other: Öppna igen - forbidden_error: - other: Förbjudet. - pin: - other: Fäst - hide: - other: Göm - unpin: - other: Lossa - show: - other: Lista - invite_someone_to_answer: - other: Redigera - undelete: - other: Återskapa - merge: - other: Sammanfoga - role: - name: - user: - other: Användare - admin: - other: Administratör - moderator: - other: Moderator - description: - user: - other: Normal tillgång - admin: - other: Full kontroll över webbplatsen - moderator: - other: Tillgång till allt utom administratörsinställningar - privilege: - level_1: - description: - other: Nivå 1 - level_2: - description: - other: Nivå 2 - level_3: - description: - other: Nivå 3 - level_custom: - description: - other: Anpassad nivå - rank_question_add_label: - other: Ställ en fråga - rank_answer_add_label: - other: Skriv ett svar - rank_comment_add_label: - other: Skriv en kommentar - rank_report_add_label: - other: Flagga - rank_comment_vote_up_label: - other: Bra kommentar - rank_link_url_limit_label: - other: Mer än 2 länkar samtidigt - rank_question_vote_up_label: - other: Bra fråga - rank_answer_vote_up_label: - other: Bra svar - rank_question_vote_down_label: - other: Dålig fråga - rank_answer_vote_down_label: - other: Dåligt svar - rank_invite_someone_to_answer_label: - other: Bjud in någon att svara - rank_tag_add_label: - other: Skapa ny tagg - rank_tag_edit_label: - other: Beskriv etiketten (behöver granskas) - rank_question_edit_label: - other: Editera annans fråga (behöver granskas) - rank_answer_edit_label: - other: Editera annans svar (behöver granskas) - rank_question_edit_without_review_label: - other: Editera annans fråga utan granskning - rank_answer_edit_without_review_label: - other: Editera annans svar utan granskning - rank_question_audit_label: - other: Granska ändringar av fråga - rank_answer_audit_label: - other: Granska ändringar av svar - rank_tag_audit_label: - other: Granska ändringar av etikett - rank_tag_edit_without_review_label: - other: Ändra etikett-beskrivningen utan granskning - rank_tag_synonym_label: - other: Hantera etikett-synonymer - email: - other: E-post - e_mail: - other: E-post - password: - other: Lösenord - pass: - other: Lösenord - old_pass: - other: Nuvarande lösenord - original_text: - other: Detta inlägg - email_or_password_wrong_error: - other: Fel e-post eller lösenord - error: - common: - invalid_url: - other: Ogiltig URL. - status_invalid: - other: Ogiltig status. - password: - space_invalid: - other: Lösenordet får inte innehålla mellanslag. - admin: - cannot_update_their_password: - other: Du får inte ändra ditt lösenord. - cannot_edit_their_profile: - other: Du får inte ändra din profil. - cannot_modify_self_status: - other: Du får inte ändra din status. - email_or_password_wrong: - other: Fel e-post eller lösenord. - answer: - not_found: - other: Svar hittades inte. - cannot_deleted: - other: Radering tillåts inte. - cannot_update: - other: No permission to update. - question_closed_cannot_add: - other: Questions are closed and cannot be added. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - content_cannot_empty: - other: Kommentarsfältet får inte vara tomt. - email: - duplicate: - other: E-postadressen finns redan. - need_to_be_verified: - other: E-postadressen ska vara verifierad. - verify_url_expired: - other: Länken för att verifiera e-postadressen har gått ut. Vänligen skicka igen. - illegal_email_domain_error: - other: E-post från den domänen tillåts inte. Vänligen använt en annan. - lang: - not_found: - other: Språkfilen hittas inte. - object: - captcha_verification_failed: - other: Fel Captcha. - disallow_follow: - other: Du tillåts inte följa. - disallow_vote: - other: Du tillåts inte rösta. - disallow_vote_your_self: - other: Du får inte rösta på ditt eget inlägg. - not_found: - other: Objektet hittas inte. - verification_failed: - other: Verifiering misslyckades. - email_or_password_incorrect: - other: Fel e-postadress eller lösenord. - old_password_verification_failed: - other: Den gamla verifieringen av lösenordet misslyckades. - new_password_same_as_previous_setting: - other: Det nya lösenordet är samma som det förra. - already_deleted: - other: Det här inlägget har raderats. - meta: - object_not_found: - other: Meta-objekt hittas inte. - question: - already_deleted: - other: Det här inlägget har raderats. - under_review: - other: Ditt inlägg väntar på granskning. Det kommer att publiceras så snart det har blivit godkänt. - not_found: - other: . - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Reputation rank fail to meet the condition. - vote_fail_to_meet_the_condition: - other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. - no_enough_rank_to_operate: - other: You need at least {{.Rank}} reputation to do this. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - already_exist: - other: Tag already exists. - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - is_used_cannot_delete: - other: You cannot delete a tag that is in use. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: The from name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to revise. - user: - external_login_missing_user_id: - other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. - external_login_unbinding_forbidden: - other: Please set a login password for your account before you remove this login. - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration. - not_allowed_login_via_password: - other: Currently the site is not allowed to login via password. - access_denied: - other: Access denied - page_access_denied: - other: You do not have access to this page. - add_bulk_users_format_error: - other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Tabellen kunde inte skapas. - install: - create_config_failed: - other: Filen config.yaml kan inte skapas. - upload: - unsupported_file_format: - other: Filformatet tillåts inte. - site_info: - config_not_found: - other: Webbplats inställningarna hittar inte. - badge: - object_not_found: - other: Badge object not found - reason: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude_or_abusive: - name: - other: rude or abusive - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - a_duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - placeholder: - other: Enter the existing question link - not_a_answer: - name: - other: not an answer - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." - no_longer_needed: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - something: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - placeholder: - other: Let us know specifically what you are concerned about - community_specific: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - not_clarity: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - looks_ok: - name: - other: looks OK - desc: - other: This post is good as-is and not low quality. - needs_edit: - name: - other: needs edit, and I did it - desc: - other: Improve and correct problems with this post yourself. - needs_close: - name: - other: needs close - desc: - other: A closed question can't answer, but still can edit, vote and comment. - needs_delete: - name: - other: needs delete - desc: - other: This post will be deleted. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - deleted_title: - other: Deleted question - questions_title: - other: Questions - tag: - tags_title: - other: Tags - no_description: - other: The tag has no description. - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Din fråga har raderats - your_answer_was_deleted: - other: Ditt svar har raderats - your_comment_was_deleted: - other: Din kommentar har raderats - up_voted_question: - other: upvoted question - down_voted_question: - other: downvoted question - up_voted_answer: - other: upvoted answer - down_voted_answer: - other: downvoted answer - up_voted_comment: - other: upvoted comment - invited_you_to_answer: - other: invited you to answer - earned_badge: - other: You've earned the "{{.BadgeName}}" badge - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Bekräfta din nya e-postadress" - body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} answered your question" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_question: - title: - other: "[{{.SiteName}}] Ny fråga: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Password reset" - body: - other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - register: - title: - other: "[{{.SiteName}}] Bekräfta ditt nya konto" - body: - other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - test: - title: - other: "[{{.SiteName}}] Test Email" - body: - other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: - upvote: - other: upvote - upvoted: - other: upvoted - downvote: - other: downvote - downvoted: - other: downvoted - accept: - other: accept - accepted: - other: accepted - edit: - other: edit - review: - queued_post: - other: Queued post - flagged_post: - other: Flagged post - suggested_post_edit: - other: Suggested edits - reaction: - tooltip: - other: "{{ .Names }} and {{ .Count }} more..." - badge: - default_badges: - autobiographer: - name: - other: Autobiographer - desc: - other: Filled out profile information. - certified: - name: - other: Certified - desc: - other: Completed our new user tutorial. - editor: - name: - other: Editor - desc: - other: First post edit. - first_flag: - name: - other: First Flag - desc: - other: First flagged a post. - first_upvote: - name: - other: First Upvote - desc: - other: First up voted a post. - first_link: - name: - other: First Link - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: First Share - desc: - other: First shared a post. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Leave 5 comments. - new_user_of_the_month: - name: - other: New User of the Month - desc: - other: Outstanding contributions in their first month. - read_guidelines: - name: - other: Read Guidelines - desc: - other: Read the [community guidelines]. - reader: - name: - other: Reader - desc: - other: Read every answers in a topic with more than 10 answers. - welcome: - name: - other: Welcome - desc: - other: Received a up vote. - nice_share: - name: - other: Nice Share - desc: - other: Shared a post with 25 unique visitors. - good_share: - name: - other: Good Share - desc: - other: Shared a post with 300 unique visitors. - great_share: - name: - other: Great Share - desc: - other: Shared a post with 1000 unique visitors. - out_of_love: - name: - other: Out of Love - desc: - other: Used 50 up votes in a day. - higher_love: - name: - other: Higher Love - desc: - other: Used 50 up votes in a day 5 times. - crazy_in_love: - name: - other: Crazy in Love - desc: - other: Used 50 up votes in a day 20 times. - promoter: - name: - other: Promoter - desc: - other: Invited a user. - campaigner: - name: - other: Campaigner - desc: - other: Invited 3 basic users. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: Thank You - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Active member for a year, posted at least once. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Prev - next: Nästa - page_title: - question: Fråga - questions: Frågor - tag: Tagg - tags: Taggar - tag_wiki: tag wiki - create_tag: Create Tag - edit_tag: Edit Tag - ask_a_question: Create Question - edit_question: Redigera fråga - edit_answer: Redigera svar - search: Sök - posts_containing: Posts containing - settings: Inställningar - notifications: Notifications - login: Logga in - sign_up: Registrera dig - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: Account Suspended - admin: Admin - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Användare - oauth_callback: Processing - http_404: HTTP Error 404 - http_50X: HTTP Error 500 - http_403: HTTP Error 403 - logout: Logga ut - posts: Posts - notifications: - title: Notifications - inbox: Inkorg - achievement: Achievements - new_alerts: New alerts - all_read: Markera alla som lästa - show_more: Visa mer - someone: Someone - inbox_type: - all: Alla - posts: Inlägg - invites: Inbjudningar - votes: Röster - answer: Answer - question: Question - badge_award: Badge - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - contact_us: Kontakta oss - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Kod - msg: - empty: Code cannot be empty. - language: - label: Språk - placeholder: Automatic detection - btn_cancel: Avbryt - btn_confirm: Lägg till - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Hjälp - hr: - text: Horizontal rule - image: - text: Bild - add_image: Lägg till bild - tab_image: Ladda upp bild - form_image: - fields: - file: - label: Image file - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed {{size}} MB. - desc: - label: Beskrivning - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Beskrivning - btn_cancel: Avbryt - btn_confirm: Lägg till - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Beskrivning - btn_cancel: Avbryt - btn_confirm: Lägg till - ordered_list: - text: Numbered list - unordered_list: - text: Bulleted list - table: - text: Tabell - heading: Heading - cell: Cell - file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: I am closing this post as... - btn_cancel: Avbryt - btn_submit: Skicka - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Avbryt - btn_submit: Skicka - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - not_a_url: URL format is incorrect. - url_not_match: URL origin does not match the current website. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Visningsnamn - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Beskrivning - revision: - label: Revision - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_cancel: Avbryt - btn_submit: Skicka - btn_post: Post new tag - tag_info: - created_at: Skapad - edited_at: Edited - history: Historik - synonyms: - title: Synonymer - text: The following tags will be remapped to - empty: Inga synonymer hittades. - btn_add: Lägg till en synonym - btn_edit: Redigera - btn_save: Spara - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - tip_with_posts: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - tip_with_synonyms: >- -

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        - tip: Are you sure you wish to delete? - close: Stäng - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - default_first_reason: Lägg till tagg - btn_save_edits: Save edits - btn_cancel: Avbryt - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: nu - x_seconds_ago: "{{count}} s sedan" - x_minutes_ago: "{{count}} m sedan" - x_hours_ago: "{{count}} t sedan" - hour: timme - day: dag - hours: timmar - days: dagar - month: month - months: months - year: year - reaction: - heart: heart - smile: smile - frown: frown - btn_label: add or remove reactions - undo_emoji: undo {{ emoji }} reaction - react_emoji: react with {{ emoji }} - unreact_emoji: unreact with {{ emoji }} - comment: - btn_add_comment: Lägg till kommentar - reply_to: Reply to - btn_reply: Svara - btn_edit: Redigera - btn_delete: Radera - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Avbryt - show_more: "{{count}} more comments" - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - tip_vote: It adds something useful to the post - edit_answer: - title: Edit Answer - default_reason: Edit answer - default_first_reason: Add answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Avbryt - tags: - title: Tags - sort_buttons: - popular: Popular - name: Namn - newest: Newest - button_follow: Följ - button_following: Följer - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - wiki: Wiki - ask: - title: Create Question - edit_title: Edit Question - default_reason: Edit question - default_first_reason: Create question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: What's your topic? Be specific. - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Användare - badges: Badges - profile: Profil - setting: Inställningar - logout: Logga ut - admin: Admin - review: Review - bookmark: Bokmärken - moderation: Moderation - search: - placeholder: Sök - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Ändra - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - resend_email: - url_label: Are you sure you want to resend the activation email? - url_text: You can also give the activation link above to the user. - login: - login_to_continue: Logga in för att fortsätta - info_sign: Har du inget konto? <1>Registrera dig - info_login: Har du redan ett konto? <1>Logga in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Glömt lösenord? - name: - label: Namn - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: E-postadress - msg: - empty: Email cannot be empty. - password: - label: Lösenord - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Glömt ditt lösenord - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: E-postadress - msg: - empty: Email cannot be empty. - change_email: - btn_cancel: Avbryt - btn_update: Uppdatera e-postadress - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Ny e-postadress - msg: - empty: Email cannot be empty. - oauth: - connect: Connect with {{ auth_name }} - remove: Remove {{ auth_name }} - oauth_bind_email: - subtitle: Add a recovery email to your account. - btn_update: Uppdatera e-postadress - email: - label: Email - msg: - empty: Email cannot be empty. - modal_title: Email already existes. - modal_content: This email address already registered. Are you sure you want to connect to the existing account? - modal_cancel: Change email - modal_confirm: Connect to the existing account - password_reset: - page_title: Password Reset - btn_name: Återställ mitt lösenord - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Lösenord - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Bekräfta nytt lösenord - settings: - page_title: Inställningar - goto_modify: Go to modify - nav: - profile: Profil - notification: Notifications - account: Konto - interface: Interface - profile: - heading: Profil - btn_name: Spara - display_name: - label: Visningsnamn - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Användarnamn - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profilbild - gravatar: Gravatar - gravatar_text: You can change image on - custom: Custom - custom_text: Du kan ladda upp din bild. - default: System - msg: Please upload an avatar - bio: - label: Om mig - website: - label: Webbplats - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location - placeholder: "Stad, Land" - notification: - heading: Email Notifications - turn_on: Turn on - inbox: - label: Inbox notifications - description: Answers to your questions, comments, invites, and more. - all_new_question: - label: All new questions - description: Get notified of all new questions. Up to 50 questions per week. - all_new_question_for_following_tags: - label: All new questions for following tags - description: Get notified of new questions for following tags. - account: - heading: Konto - change_email_btn: Change email - change_pass_btn: Ändra lösenord - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Ny e-postadress - new_email: - label: New email - msg: New email cannot be empty. - pass: - label: Nuvarande lösenord - msg: Password cannot be empty. - password_title: Lösenord - current_pass: - label: Nuvarande lösenord - msg: - empty: Current password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: Nytt lösenord - pass_confirm: - label: Bekräfta nytt lösenord - interface: - heading: Interface - lang: - label: Interface language - text: User interface language. It will change when you refresh the page. - my_logins: - title: My logins - label: Log in or sign up on this site using these accounts. - modal_title: Remove login - modal_content: Are you sure you want to remove this login from your account? - modal_confirm_btn: Remove - remove_success: Removed successfully - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - sent_success: Sent successfully - related_question: - title: Related - answers: answers - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: People Asked - desc: Bjud in personer som du tror kan svara. - invite: Invite to answer - add: Add people - search: Search people - question_detail: - action: Action - created: Created - Asked: Asked - asked: asked - update: Modified - Edited: Edited - edit: edited - commented: commented - Views: Viewed - Follow: Follow - Following: Following - follow_tip: Follow this question to receive notifications - answered: answered - closed_in: Closed in - show_exist: Show existing question. - useful: Useful - question_useful: It is useful and clear - question_un_useful: It is unclear or not useful - question_bookmark: Bookmark this question - answer_useful: It is useful - answer_un_useful: It is not useful - answers: - title: Answers - score: Score - newest: Newest - oldest: Oldest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Ditt svar - edit_answer: Edit my existing answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Fortsätt - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - tips: - header_1: Thanks for your answer - li1_1: Please be sure to answer the question. Provide details and share your research. - li1_2: Back up any statements you make with references or personal experience. - header_2: But avoid ... - li2_1: Asking for help, seeking clarification, or responding to other answers. - reopen: - confirm_btn: Reopen - title: Reopen this post - content: Are you sure you want to reopen? - list: - confirm_btn: List - title: List this post - content: Are you sure you want to list? - unlist: - confirm_btn: Unlist - title: Unlist this post - content: Are you sure you want to unlist? - pin: - title: Pin this post - content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. - confirm_btn: Fäst - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Är du säker på att du vill radera? - tip_answer_deleted: This answer has been deleted - undelete_title: Undelete this post - undelete_desc: Are you sure you wish to undelete? - btns: - confirm: Bekräfta - cancel: Avbryt - edit: Redigera - save: Spara - delete: Radera - undelete: Undelete - list: List - unlist: Unlist - unlisted: Unlisted - login: Logga in - signup: Registrera dig - logout: Logga ut - verify: Verify - create: Create - approve: Approve - reject: Reject - skip: Hoppa över - discard_draft: Discard draft - pinned: Pinned - all: All - question: Question - answer: Answer - comment: Comment - refresh: Uppdatera - resend: Resend - deactivate: Deactivate - active: Active - suspend: Suspend - unsuspend: Unsuspend - close: Stäng - reopen: Reopen - ok: OK - light: Ljust - dark: Mörkt - system_setting: System setting - default: Standard - reset: Återställ - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignorera - submit: Skicka - normal: Normal - closed: Closed - deleted: Deleted - deleted_permanently: Deleted permanently - pending: Pending - more: More - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Sökresultat - keywords: Keywords - options: Alternativ - follow: Follow - following: Following - counts: "{{count}} resultat" - counts_loading: "... Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Dela - copy: Kopiera länk - via: Dela inlägg via... - copied: Copied - facebook: Dela på Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post. - modal_confirm: - title: Error... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: Din e-postadress har uppdaterats. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Redigera - save: Spara - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} frågor" - x_answers: "{{ count }} svar" - x_posts: "{{ count }} Posts" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - frequent: Frequent - recommend: Recommend - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bokmärken - reputation: Reputation - comments: Kommentarer - votes: Röster - badges: Badges - newest: Newest - score: Score - edit_profile: Redigera profil - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - comma: "," - last_login: Seen - about_me: Om mig - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - content_empty: No posts found. - accepted: Accepted - answered: answered - asked: asked - downvoted: downvoted - mod_short: MOD - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - recent_badges: Recent Badges - install: - title: Installation - next: Nästa - done: Klar - config_yaml_error: Can't create the config.yaml file. - lang: - label: Välj ett språk - db_type: - label: Database engine - db_username: - label: Användarnamn - placeholder: root - msg: Username cannot be empty. - db_password: - label: Lösenord - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database host - placeholder: "db:3306" - msg: Database host cannot be empty. - db_name: - label: Databasnamn - placeholder: answer - msg: Database name cannot be empty. - db_file: - label: Database file - placeholder: /data/answer.db - msg: Database file cannot be empty. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Skapa config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site name - msg: Site name cannot be empty. - msg_max_length: Site name must be at maximum 30 characters in length. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - max_length: Site URL must be at maximum 512 characters in length. - contact_email: - label: Contact email - text: Email address of key contact responsible for this site. - msg: - empty: Contact email cannot be empty. - incorrect: Contact email incorrect format. - login_required: - label: Privat - switch: Login required - text: Only logged in users can access this community. - admin_name: - label: Namn - msg: Name cannot be empty. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Lösenord - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - msg_min_length: Password must be at least 8 characters in length. - msg_max_length: Password must be at maximum 32 characters in length. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Varning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_error: - http_error: HTTP Error {{ code }} - desc_403: You don't have permission to access this page. - desc_404: Unfortunately, this page doesn't exist. - desc_50X: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Användare - badges: Badges - flags: Flags - settings: Inställningar - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - terms: Terms - tos: Användarvillkor - privacy: Privacy - seo: SEO - customize: Anpassa - themes: Teman - login: Logga in - privileges: Privileges - plugins: Plugins - installed_plugins: Installed Plugins - apperance: Appearance - website_welcome: Välkommen till {{site_name}} - user_center: - login: Login - qrcode_login_tip: Använd {{ agentName }} för att skanna QR-koden och logga in. - login_failed_email_tip: Login failed, please allow this app to access your email information before try again. - badges: - modal: - title: Grattis - content: You've earned a new badge. - close: Stäng - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site statistics - questions: "Frågor:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "Svar:" - comments: "Kommentarer:" - votes: "Röster:" - users: "Användare:" - flags: "Flags:" - reviews: "Reviews:" - site_health: Site health - version: "Version:" - https: "HTTPS:" - upload_folder: "Upload folder:" - run_mode: "Running mode:" - private: Privat - public: Public - smtp: "SMTP:" - timezone: "Tidszon:" - system_info: System info - go_version: "Go version:" - database: "Databas:" - database_size: "Database size:" - storage_used: "Storage used:" - uptime: "Uptime:" - links: Länkar - plugins: Plugins - github: GitHub - blog: Blogg - contact: Kontakt - forum: Forum - documents: Dokument - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Ja" - "no": "Nej" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - writable: Writable - not_writable: Not writable - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - flagged_type: Flagged {{ type }} - created: Created - action: Action - review: Review - user_role_modal: - title: Ändra användarroll till... - btn_cancel: Avbryt - btn_submit: Skicka - new_password_modal: - title: Set new password - form: - fields: - password: - label: Lösenord - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Avbryt - btn_submit: Skicka - edit_profile_modal: - title: Redigera profil - form: - fields: - display_name: - label: Visningsnamn - msg_range: Display name must be 2-30 characters in length. - username: - label: Användarnamn - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Ogiltig e-postadress. - edit_success: Edited successfully - btn_cancel: Avbryt - btn_submit: Skicka - user_modal: - title: Lägg till ny användare - form: - fields: - users: - label: Bulk add user - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separera "namn, e-postadress, lösenord" med kommatecken. En användare per rad. - msg: "Please enter the user's email, one per line." - display_name: - label: Visningsnamn - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Lösenord - msg: Password must be at 8-32 characters in length. - btn_cancel: Avbryt - btn_submit: Skicka - users: - title: Användare - name: Namn - email: Email - reputation: Reputation - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Status - role: Roll - action: Action - change: Ändra - all: Alla - staff: Staff - more: More - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: Användare - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - edit_profile: Edit profile - change_status: Ändra status - change_role: Ändra roll - show_logs: Visa loggar - add_user: Lägg till användare - deactivate_user: - title: Deactivate user - content: An inactive user must re-validate their email. - delete_user: - title: Delete this user - content: Are you sure you want to delete this user? This is permanent! - remove: Remove their content - label: Remove all questions, answers, comments, etc. - text: Don’t check this if you wish to only delete the user’s account. - suspend_user: - title: Suspend this user - content: A suspended user can't log in. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Questions - unlisted: Unlisted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Ändra - pending: Pending - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Ändra - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Ange en giltig URL. - text: The address of your site. - short_desc: - label: Short site description - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site description - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - check_update: - label: Software updates - text: Automatically check for updates - interface: - page_title: Interface - language: - label: Interface language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Tidszon - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: From email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Kryptering - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - tls: TLS - none: Ingen - smtp_port: - label: SMTP port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test email recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Aktivera autentisering - title: SMTP authentication - msg: SMTP authentication cannot be empty. - "yes": "Ja" - "no": "Nej" - branding: - page_title: Branding - logo: - label: Logo - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile logo - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square icon - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Användarvillkor - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Integritetspolicy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Write - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Each user can only write one answer for each question - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Recommend tags - text: "Recommend tags will show in the dropdown list by default." - msg: - contain_reserved: "recommended tags cannot contain reserved tags" - required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved tags - text: "Reserved tags can only be used by moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: SEO - permalink: - label: Permalänk - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Teman - themes: - label: Teman - text: Select an existing theme. - color_scheme: - label: Färgschema - navbar_style: - label: Navbar background style - primary_color: - label: Primary color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS och HTML - custom_css: - label: Anpassad CSS - text: > - - head: - label: Head - text: > - - header: - label: Header - text: > - - footer: - label: Footer - text: This will insert before </body>. - sidebar: - label: Sidebar - text: This will insert in sidebar. - login: - page_title: Login - membership: - title: Medlemskap - label: Tillåt nya registreringar - text: Turn off to prevent anyone from creating a new account. - email_registration: - title: Email registration - label: Allow email registration - text: Turn off to prevent anyone creating new account through email. - allowed_email_domains: - title: Allowed email domains - text: Email domains that users must register accounts with. One domain per line. Ignored when empty. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - password_login: - title: Password login - label: Allow email and password login - text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." - installed_plugins: - title: Installed Plugins - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. - filter: - all: Alla - active: Aktiv - inactive: Inaktiv - outdated: Outdated - plugins: - label: Plugins - text: Select an existing plugin. - name: Namn - version: Version - status: Status - action: Action - deactivate: Deactivate - activate: Aktivera - settings: Inställningar - settings_users: - title: Användare - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - profile_editable: - title: Profile editable - allow_update_display_name: - label: Tillåt användare att ändra sitt visningsnamn - allow_update_username: - label: Tillåt användare att ändra sitt användarnamn - allow_update_avatar: - label: Tillåt användare att ändra sin profilbild - allow_update_bio: - label: Allow users to change their about me - allow_update_website: - label: Allow users to change their website - allow_update_location: - label: Allow users to change their location - privilege: - title: Privileges - level: - label: Reputation required level - text: Choose the reputation required for the privileges - msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 - badges: - action: Action - active: Aktiv - activate: Aktivera - all: Alla - awards: Awards - deactivate: Inaktivera - filter: - placeholder: Filter by name, badge:id - group: Grupp - inactive: Inaktiv - name: Namn - show_logs: Visa loggar - status: Status - title: Badges - form: - optional: (optional) - empty: cannot be empty - invalid: is invalid - btn_submit: Spara - not_found_props: "Required property {{ key }} not found." - select: Select - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Redigera tagg - empty: No review tasks left. - approve_revision_tip: Do you approve this revision? - approve_flag_tip: Do you approve this flag? - approve_post_tip: Do you approve this post? - approve_user_tip: Do you approve this user? - suggest_edits: Suggested edits - flag_post: Flag post - flag_user: Flag user - queued_post: Queued post - queued_user: Queued user - filter_label: Type - reputation: reputation - flag_post_type: Flagged this post as {{ type }}. - flag_user_type: Flagged this user as {{ type }}. - edit_post: Edit post - list_post: List post - unlist_post: Unlist post - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - pin: pinned - unpin: unpinned - show: listed - hide: unlisted - title: "History for" - tag_title: "Timeline for" - show_votes: "Visa röster" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Användare - users_with_the_most_reputation: Users with the highest reputation scores this week - users_with_the_most_vote: Users who voted the most this week - staffs: Our community staff - reputation: reputation - votes: röster - prompt: - leave_page: Are you sure you want to leave the page? - changes_not_save: Dina ändringar kanske inte sparas. - draft: - discard_confirm: Are you sure you want to discard your draft? - messages: - post_deleted: This post has been deleted. - post_cancel_deleted: This post has been undeleted. - post_pin: This post has been pinned. - post_unpin: This post has been unpinned. - post_hide_list: This post has been hidden from list. - post_show_list: This post has been shown to list. - post_reopen: This post has been reopened. - post_list: This post has been listed. - post_unlist: This post has been unlisted. - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/te_IN.yaml b/data/i18n/te_IN.yaml deleted file mode 100644 index 22c24a93c..000000000 --- a/data/i18n/te_IN.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: విజయవంతమైంది. - unknown: - other: తెలియని సమస్య. - request_format_error: - other: Request format is not valid. - unauthorized_error: - other: Unauthorized. - database_error: - other: Data server error. - forbidden_error: - other: Forbidden. - duplicate_request_error: - other: Duplicate submission. - action: - report: - other: Flag - edit: - other: Edit - delete: - other: Delete - close: - other: Close - reopen: - other: Reopen - forbidden_error: - other: Forbidden. - pin: - other: Pin - hide: - other: Unlist - unpin: - other: Unpin - show: - other: List - invite_someone_to_answer: - other: Edit - undelete: - other: Undelete - merge: - other: Merge - role: - name: - user: - other: User - admin: - other: Admin - moderator: - other: Moderator - description: - user: - other: Default with no special access. - admin: - other: Have the full power to access the site. - moderator: - other: Has access to all posts except admin settings. - privilege: - level_1: - description: - other: Level 1 (less reputation required for private team, group) - level_2: - description: - other: Level 2 (low reputation required for startup community) - level_3: - description: - other: Level 3 (high reputation required for mature community) - level_custom: - description: - other: Custom Level - rank_question_add_label: - other: Ask question - rank_answer_add_label: - other: Write answer - rank_comment_add_label: - other: Write comment - rank_report_add_label: - other: Flag - rank_comment_vote_up_label: - other: Upvote comment - rank_link_url_limit_label: - other: Post more than 2 links at a time - rank_question_vote_up_label: - other: Upvote question - rank_answer_vote_up_label: - other: Upvote answer - rank_question_vote_down_label: - other: Downvote question - rank_answer_vote_down_label: - other: Downvote answer - rank_invite_someone_to_answer_label: - other: Invite someone to answer - rank_tag_add_label: - other: Create new tag - rank_tag_edit_label: - other: Edit tag description (need to review) - rank_question_edit_label: - other: Edit other's question (need to review) - rank_answer_edit_label: - other: Edit other's answer (need to review) - rank_question_edit_without_review_label: - other: Edit other's question without review - rank_answer_edit_without_review_label: - other: Edit other's answer without review - rank_question_audit_label: - other: Review question edits - rank_answer_audit_label: - other: Review answer edits - rank_tag_audit_label: - other: Review tag edits - rank_tag_edit_without_review_label: - other: Edit tag description without review - rank_tag_synonym_label: - other: Manage tag synonyms - email: - other: Email - e_mail: - other: Email - password: - other: Password - pass: - other: Password - old_pass: - other: Current password - original_text: - other: This post - email_or_password_wrong_error: - other: Email and password do not match. - error: - common: - invalid_url: - other: Invalid URL. - status_invalid: - other: Invalid status. - password: - space_invalid: - other: Password cannot contain spaces. - admin: - cannot_update_their_password: - other: You cannot modify your password. - cannot_edit_their_profile: - other: You cannot modify your profile. - cannot_modify_self_status: - other: You cannot modify your status. - email_or_password_wrong: - other: Email and password do not match. - answer: - not_found: - other: Answer do not found. - cannot_deleted: - other: No permission to delete. - cannot_update: - other: No permission to update. - question_closed_cannot_add: - other: Questions are closed and cannot be added. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Comment are not allowed to edit. - not_found: - other: Comment not found. - cannot_edit_after_deadline: - other: The comment time has been too long to modify. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: Email already exists. - need_to_be_verified: - other: Email should be verified. - verify_url_expired: - other: Email verified URL has expired, please resend the email. - illegal_email_domain_error: - other: Email is not allowed from that email domain. Please use another one. - lang: - not_found: - other: Language file not found. - object: - captcha_verification_failed: - other: Captcha wrong. - disallow_follow: - other: You are not allowed to follow. - disallow_vote: - other: You are not allowed to vote. - disallow_vote_your_self: - other: You can't vote for your own post. - not_found: - other: Object not found. - verification_failed: - other: Verification failed. - email_or_password_incorrect: - other: Email and password do not match. - old_password_verification_failed: - other: The old password verification failed - new_password_same_as_previous_setting: - other: The new password is the same as the previous one. - already_deleted: - other: This post has been deleted. - meta: - object_not_found: - other: Meta object not found - question: - already_deleted: - other: This post has been deleted. - under_review: - other: Your post is awaiting review. It will be visible after it has been approved. - not_found: - other: Question not found. - cannot_deleted: - other: No permission to delete. - cannot_close: - other: No permission to close. - cannot_update: - other: No permission to update. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Reputation rank fail to meet the condition. - vote_fail_to_meet_the_condition: - other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. - no_enough_rank_to_operate: - other: You need at least {{.Rank}} reputation to do this. - report: - handle_failed: - other: Report handle failed. - not_found: - other: Report not found. - tag: - already_exist: - other: Tag already exists. - not_found: - other: Tag not found. - recommend_tag_not_found: - other: Recommend tag is not exist. - recommend_tag_enter: - other: Please enter at least one required tag. - not_contain_synonym_tags: - other: Should not contain synonym tags. - cannot_update: - other: No permission to update. - is_used_cannot_delete: - other: You cannot delete a tag that is in use. - cannot_set_synonym_as_itself: - other: You cannot set the synonym of the current tag as itself. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: The from name cannot be a email address. - theme: - not_found: - other: Theme not found. - revision: - review_underway: - other: Can't edit currently, there is a version in the review queue. - no_permission: - other: No permission to revise. - user: - external_login_missing_user_id: - other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. - external_login_unbinding_forbidden: - other: Please set a login password for your account before you remove this login. - email_or_password_wrong: - other: - other: Email and password do not match. - not_found: - other: User not found. - suspended: - other: User has been suspended. - username_invalid: - other: Username is invalid. - username_duplicate: - other: Username is already in use. - set_avatar: - other: Avatar set failed. - cannot_update_your_role: - other: You cannot modify your role. - not_allowed_registration: - other: Currently the site is not open for registration. - not_allowed_login_via_password: - other: Currently the site is not allowed to login via password. - access_denied: - other: Access denied - page_access_denied: - other: You do not have access to this page. - add_bulk_users_format_error: - other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Read config failed - database: - connection_failed: - other: Database connection failed - create_table_failed: - other: Create table failed - install: - create_config_failed: - other: Can't create the config.yaml file. - upload: - unsupported_file_format: - other: Unsupported file format. - site_info: - config_not_found: - other: Site config not found. - badge: - object_not_found: - other: Badge object not found - reason: - spam: - name: - other: spam - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude_or_abusive: - name: - other: rude or abusive - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - a_duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - placeholder: - other: Enter the existing question link - not_a_answer: - name: - other: not an answer - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." - no_longer_needed: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - something: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - placeholder: - other: Let us know specifically what you are concerned about - community_specific: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - not_clarity: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - looks_ok: - name: - other: looks OK - desc: - other: This post is good as-is and not low quality. - needs_edit: - name: - other: needs edit, and I did it - desc: - other: Improve and correct problems with this post yourself. - needs_close: - name: - other: needs close - desc: - other: A closed question can't answer, but still can edit, vote and comment. - needs_delete: - name: - other: needs delete - desc: - other: This post will be deleted. - question: - close: - duplicate: - name: - other: spam - desc: - other: This question has been asked before and already has an answer. - guideline: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - multiple: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: something else - desc: - other: This post requires another reason not listed above. - operation_type: - asked: - other: asked - answered: - other: answered - modified: - other: modified - deleted_title: - other: Deleted question - questions_title: - other: Questions - tag: - tags_title: - other: Tags - no_description: - other: The tag has no description. - notification: - action: - update_question: - other: updated question - answer_the_question: - other: answered question - update_answer: - other: updated answer - accept_answer: - other: accepted answer - comment_question: - other: commented question - comment_answer: - other: commented answer - reply_to_you: - other: replied to you - mention_you: - other: mentioned you - your_question_is_closed: - other: Your question has been closed - your_question_was_deleted: - other: Your question has been deleted - your_answer_was_deleted: - other: Your answer has been deleted - your_comment_was_deleted: - other: Your comment has been deleted - up_voted_question: - other: upvoted question - down_voted_question: - other: downvoted question - up_voted_answer: - other: upvoted answer - down_voted_answer: - other: downvoted answer - up_voted_comment: - other: upvoted comment - invited_you_to_answer: - other: invited you to answer - earned_badge: - other: You've earned the "{{.BadgeName}}" badge - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Confirm your new email address" - body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} answered your question" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_question: - title: - other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Password reset" - body: - other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - register: - title: - other: "[{{.SiteName}}] Confirm your new account" - body: - other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - test: - title: - other: "[{{.SiteName}}] Test Email" - body: - other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: - upvote: - other: upvote - upvoted: - other: upvoted - downvote: - other: downvote - downvoted: - other: downvoted - accept: - other: accept - accepted: - other: accepted - edit: - other: edit - review: - queued_post: - other: Queued post - flagged_post: - other: Flagged post - suggested_post_edit: - other: Suggested edits - reaction: - tooltip: - other: "{{ .Names }} and {{ .Count }} more..." - badge: - default_badges: - autobiographer: - name: - other: Autobiographer - desc: - other: Filled out profile information. - certified: - name: - other: Certified - desc: - other: Completed our new user tutorial. - editor: - name: - other: Editor - desc: - other: First post edit. - first_flag: - name: - other: First Flag - desc: - other: First flagged a post. - first_upvote: - name: - other: First Upvote - desc: - other: First up voted a post. - first_link: - name: - other: First Link - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: First Share - desc: - other: First shared a post. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Leave 5 comments. - new_user_of_the_month: - name: - other: New User of the Month - desc: - other: Outstanding contributions in their first month. - read_guidelines: - name: - other: Read Guidelines - desc: - other: Read the [community guidelines]. - reader: - name: - other: Reader - desc: - other: Read every answers in a topic with more than 10 answers. - welcome: - name: - other: Welcome - desc: - other: Received a up vote. - nice_share: - name: - other: Nice Share - desc: - other: Shared a post with 25 unique visitors. - good_share: - name: - other: Good Share - desc: - other: Shared a post with 300 unique visitors. - great_share: - name: - other: Great Share - desc: - other: Shared a post with 1000 unique visitors. - out_of_love: - name: - other: Out of Love - desc: - other: Used 50 up votes in a day. - higher_love: - name: - other: Higher Love - desc: - other: Used 50 up votes in a day 5 times. - crazy_in_love: - name: - other: Crazy in Love - desc: - other: Used 50 up votes in a day 20 times. - promoter: - name: - other: Promoter - desc: - other: Invited a user. - campaigner: - name: - other: Campaigner - desc: - other: Invited 3 basic users. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: Thank You - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Active member for a year, posted at least once. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: How to Format - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: మునుపటి - next: Next - page_title: - question: ప్రశ్న - questions: ప్రశ్నలు - tag: ట్యాగ్ - tags: టాగ్లు - tag_wiki: tag wiki - create_tag: ట్యాగ్‌ని సృష్టించండి - edit_tag: ట్యాగ్‌ని సవరించండి - ask_a_question: Create Question - edit_question: ప్రశ్నను సవరించండి - edit_answer: సమాధానాన్ని సవరించండి - search: Search - posts_containing: కలిగి ఉన్న పోస్ట్‌లు - settings: Settings - notifications: నోటిఫికేషన్‌లు - login: Log In - sign_up: Sign Up - account_recovery: Account Recovery - account_activation: Account Activation - confirm_email: Confirm Email - account_suspended: ఖాతా నిలిపివేయబడింది - admin: అడ్మిన్ - change_email: Modify Email - install: Answer Installation - upgrade: Answer Upgrade - maintenance: Website Maintenance - users: Users - oauth_callback: Processing - http_404: HTTP Error 404 - http_50X: HTTP Error 500 - http_403: HTTP Error 403 - logout: Log Out - posts: Posts - notifications: - title: నోటిఫికేషన్లు - inbox: ఇన్‌బాక్స్ - achievement: విజయాలు - new_alerts: New alerts - all_read: Mark all as read - show_more: Show more - someone: Someone - inbox_type: - all: All - posts: Posts - invites: Invites - votes: Votes - answer: Answer - question: Question - badge_award: Badge - suspended: - title: Your Account has been Suspended - until_time: "Your account was suspended until {{ time }}." - forever: This user was suspended forever. - end: You don't meet a community guideline. - contact_us: Contact us - editor: - blockquote: - text: Blockquote - bold: - text: Strong - chart: - text: Chart - flow_chart: Flow chart - sequence_diagram: Sequence diagram - class_diagram: Class diagram - state_diagram: State diagram - entity_relationship_diagram: Entity relationship diagram - user_defined_diagram: User defined diagram - gantt_chart: Gantt chart - pie_chart: Pie chart - code: - text: Code Sample - add_code: Add code sample - form: - fields: - code: - label: Code - msg: - empty: Code cannot be empty. - language: - label: Language - placeholder: Automatic detection - btn_cancel: Cancel - btn_confirm: Add - formula: - text: Formula - options: - inline: Inline formula - block: Block formula - heading: - text: Heading - options: - h1: Heading 1 - h2: Heading 2 - h3: Heading 3 - h4: Heading 4 - h5: Heading 5 - h6: Heading 6 - help: - text: Help - hr: - text: Horizontal rule - image: - text: Image - add_image: Add image - tab_image: Upload image - form_image: - fields: - file: - label: Image file - btn: Select image - msg: - empty: File cannot be empty. - only_image: Only image files are allowed. - max_size: File size cannot exceed {{size}} MB. - desc: - label: Description - tab_url: Image URL - form_url: - fields: - url: - label: Image URL - msg: - empty: Image URL cannot be empty. - name: - label: Description - btn_cancel: Cancel - btn_confirm: Add - uploading: Uploading - indent: - text: Indent - outdent: - text: Outdent - italic: - text: Emphasis - link: - text: Hyperlink - add_link: Add hyperlink - form: - fields: - url: - label: URL - msg: - empty: URL cannot be empty. - name: - label: Description - btn_cancel: Cancel - btn_confirm: Add - ordered_list: - text: Numbered list - unordered_list: - text: Bulleted list - table: - text: Table - heading: Heading - cell: Cell - file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: I am closing this post as... - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - report_modal: - flag_title: I am flagging to report this post as... - close_title: I am closing this post as... - review_question_title: Review question - review_answer_title: Review answer - review_comment_title: Review comment - btn_cancel: Cancel - btn_submit: Submit - remark: - empty: Cannot be empty. - msg: - empty: Please select a reason. - not_a_url: URL format is incorrect. - url_not_match: URL origin does not match the current website. - tag_modal: - title: Create new tag - form: - fields: - display_name: - label: Display name - msg: - empty: Display name cannot be empty. - range: Display name up to 35 characters. - slug_name: - label: URL slug - desc: URL slug up to 35 characters. - msg: - empty: URL slug cannot be empty. - range: URL slug up to 35 characters. - character: URL slug contains unallowed character set. - desc: - label: Description - revision: - label: Revision - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_cancel: Cancel - btn_submit: Submit - btn_post: Post new tag - tag_info: - created_at: Created - edited_at: Edited - history: History - synonyms: - title: Synonyms - text: The following tags will be remapped to - empty: No synonyms found. - btn_add: Add a synonym - btn_edit: Edit - btn_save: Save - synonyms_text: The following tags will be remapped to - delete: - title: Delete this tag - tip_with_posts: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - tip_with_synonyms: >- -

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        - tip: Are you sure you wish to delete? - close: Close - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Edit Tag - default_reason: Edit tag - default_first_reason: Add tag - btn_save_edits: Save edits - btn_cancel: Cancel - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: now - x_seconds_ago: "{{count}}s ago" - x_minutes_ago: "{{count}}m ago" - x_hours_ago: "{{count}}h ago" - hour: hour - day: day - hours: hours - days: days - month: month - months: months - year: year - reaction: - heart: heart - smile: smile - frown: frown - btn_label: add or remove reactions - undo_emoji: undo {{ emoji }} reaction - react_emoji: react with {{ emoji }} - unreact_emoji: unreact with {{ emoji }} - comment: - btn_add_comment: Add comment - reply_to: Reply to - btn_reply: Reply - btn_edit: Edit - btn_delete: Delete - btn_flag: Flag - btn_save_edits: Save edits - btn_cancel: Cancel - show_more: "{{count}} more comments" - tip_question: >- - Use comments to ask for more information or suggest improvements. Avoid answering questions in comments. - tip_answer: >- - Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. - tip_vote: It adds something useful to the post - edit_answer: - title: Edit Answer - default_reason: Edit answer - default_first_reason: Add answer - form: - fields: - revision: - label: Revision - answer: - label: Answer - feedback: - characters: content must be at least 6 characters in length. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_save_edits: Save edits - btn_cancel: Cancel - tags: - title: Tags - sort_buttons: - popular: Popular - name: Name - newest: Newest - button_follow: Follow - button_following: Following - tag_label: questions - search_placeholder: Filter by tag name - no_desc: The tag has no description. - more: More - wiki: Wiki - ask: - title: Create Question - edit_title: Edit Question - default_reason: Edit question - default_first_reason: Create question - similar_questions: Similar questions - form: - fields: - revision: - label: Revision - title: - label: Title - placeholder: What's your topic? Be specific. - msg: - empty: Title cannot be empty. - range: Title up to 150 characters - body: - label: Body - msg: - empty: Body cannot be empty. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Tags - msg: - empty: Tags cannot be empty. - answer: - label: Answer - msg: - empty: Answer cannot be empty. - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_post_question: Post your question - btn_save_edits: Save edits - answer_question: Answer your own question - post_question&answer: Post your question and answer - tag_selector: - add_btn: Add tag - create_btn: Create new tag - search_tag: Search tag - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: No tags matched - tag_required_text: Required tag (at least one) - header: - nav: - question: Questions - tag: Tags - user: Users - badges: Badges - profile: Profile - setting: Settings - logout: Log out - admin: Admin - review: Review - bookmark: Bookmarks - moderation: Moderation - search: - placeholder: Search - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Change - loading: loading... - pic_auth_code: - title: Captcha - placeholder: Type the text above - msg: - empty: Captcha cannot be empty. - inactive: - first: >- - You're almost done! We sent an activation mail to {{mail}}. Please follow the instructions in the mail to activate your account. - info: "If it doesn't arrive, check your spam folder." - another: >- - We sent another activation email to you at {{mail}}. It might take a few minutes for it to arrive; be sure to check your spam folder. - btn_name: Resend activation email - change_btn_name: Change email - msg: - empty: Cannot be empty. - resend_email: - url_label: Are you sure you want to resend the activation email? - url_text: You can also give the activation link above to the user. - login: - login_to_continue: Log in to continue - info_sign: Don't have an account? <1>Sign up - info_login: Already have an account? <1>Log in - agreements: By registering, you agree to the <1>privacy policy and <3>terms of service. - forgot_pass: Forgot password? - name: - label: Name - msg: - empty: Name cannot be empty. - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email cannot be empty. - password: - label: Password - msg: - empty: Password cannot be empty. - different: The passwords entered on both sides are inconsistent - account_forgot: - page_title: Forgot Your Password - btn_name: Send me recovery email - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: Email - msg: - empty: Email cannot be empty. - change_email: - btn_cancel: Cancel - btn_update: Update email address - send_success: >- - If an account matches {{mail}}, you should receive an email with instructions on how to reset your password shortly. - email: - label: New email - msg: - empty: Email cannot be empty. - oauth: - connect: Connect with {{ auth_name }} - remove: Remove {{ auth_name }} - oauth_bind_email: - subtitle: Add a recovery email to your account. - btn_update: Update email address - email: - label: Email - msg: - empty: Email cannot be empty. - modal_title: Email already existes. - modal_content: This email address already registered. Are you sure you want to connect to the existing account? - modal_cancel: Change email - modal_confirm: Connect to the existing account - password_reset: - page_title: Password Reset - btn_name: Reset my password - reset_success: >- - You successfully changed your password; you will be redirected to the log in page. - link_invalid: >- - Sorry, this password reset link is no longer valid. Perhaps your password is already reset? - to_login: Continue to log in page - password: - label: Password - msg: - empty: Password cannot be empty. - length: The length needs to be between 8 and 32 - different: The passwords entered on both sides are inconsistent - password_confirm: - label: Confirm new password - settings: - page_title: Settings - goto_modify: Go to modify - nav: - profile: Profile - notification: Notifications - account: Account - interface: Interface - profile: - heading: Profile - btn_name: Save - display_name: - label: Display name - msg: Display name cannot be empty. - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - caption: People can mention you as "@username". - msg: Username cannot be empty. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile image - gravatar: Gravatar - gravatar_text: You can change image on - custom: Custom - custom_text: You can upload your image. - default: System - msg: Please upload an avatar - bio: - label: About me - website: - label: Website - placeholder: "https://example.com" - msg: Website incorrect format - location: - label: Location - placeholder: "City, Country" - notification: - heading: Email Notifications - turn_on: Turn on - inbox: - label: Inbox notifications - description: Answers to your questions, comments, invites, and more. - all_new_question: - label: All new questions - description: Get notified of all new questions. Up to 50 questions per week. - all_new_question_for_following_tags: - label: All new questions for following tags - description: Get notified of new questions for following tags. - account: - heading: Account - change_email_btn: Change email - change_pass_btn: Change password - change_email_info: >- - We've sent an email to that address. Please follow the confirmation instructions. - email: - label: Email - new_email: - label: New email - msg: New email cannot be empty. - pass: - label: Current password - msg: Password cannot be empty. - password_title: Password - current_pass: - label: Current password - msg: - empty: Current password cannot be empty. - length: The length needs to be between 8 and 32. - different: The two entered passwords do not match. - new_pass: - label: New password - pass_confirm: - label: Confirm new password - interface: - heading: Interface - lang: - label: Interface language - text: User interface language. It will change when you refresh the page. - my_logins: - title: My logins - label: Log in or sign up on this site using these accounts. - modal_title: Remove login - modal_content: Are you sure you want to remove this login from your account? - modal_confirm_btn: Remove - remove_success: Removed successfully - toast: - update: update success - update_password: Password changed successfully. - flag_success: Thanks for flagging. - forbidden_operate_self: Forbidden to operate on yourself - review: Your revision will show after review. - sent_success: Sent successfully - related_question: - title: Related - answers: answers - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: People Asked - desc: Select people who you think might know the answer. - invite: Invite to answer - add: Add people - search: Search people - question_detail: - action: Action - created: Created - Asked: Asked - asked: asked - update: Modified - Edited: Edited - edit: edited - commented: commented - Views: Viewed - Follow: Follow - Following: Following - follow_tip: Follow this question to receive notifications - answered: answered - closed_in: Closed in - show_exist: Show existing question. - useful: Useful - question_useful: It is useful and clear - question_un_useful: It is unclear or not useful - question_bookmark: Bookmark this question - answer_useful: It is useful - answer_un_useful: It is not useful - answers: - title: Answers - score: Score - newest: Newest - oldest: Oldest - btn_accept: Accept - btn_accepted: Accepted - write_answer: - title: Your Answer - edit_answer: Edit my existing answer - btn_name: Post your answer - add_another_answer: Add another answer - confirm_title: Continue to answer - continue: Continue - confirm_info: >- -

        Are you sure you want to add another answer?

        You could use the edit link to refine and improve your existing answer, instead.

        - empty: Answer cannot be empty. - characters: content must be at least 6 characters in length. - tips: - header_1: Thanks for your answer - li1_1: Please be sure to answer the question. Provide details and share your research. - li1_2: Back up any statements you make with references or personal experience. - header_2: But avoid ... - li2_1: Asking for help, seeking clarification, or responding to other answers. - reopen: - confirm_btn: Reopen - title: Reopen this post - content: Are you sure you want to reopen? - list: - confirm_btn: List - title: List this post - content: Are you sure you want to list? - unlist: - confirm_btn: Unlist - title: Unlist this post - content: Are you sure you want to unlist? - pin: - title: Pin this post - content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. - confirm_btn: Pin - delete: - title: Delete this post - question: >- - We do not recommend deleting questions with answers because doing so deprives future readers of this knowledge.

        Repeated deletion of answered questions can result in your account being blocked from asking. Are you sure you wish to delete? - answer_accepted: >- -

        We do not recommend deleting accepted answer because doing so deprives future readers of this knowledge.

        Repeated deletion of accepted answers can result in your account being blocked from answering. Are you sure you wish to delete? - other: Are you sure you wish to delete? - tip_answer_deleted: This answer has been deleted - undelete_title: Undelete this post - undelete_desc: Are you sure you wish to undelete? - btns: - confirm: Confirm - cancel: Cancel - edit: Edit - save: Save - delete: Delete - undelete: Undelete - list: List - unlist: Unlist - unlisted: Unlisted - login: Log in - signup: Sign up - logout: Log out - verify: Verify - create: Create - approve: Approve - reject: Reject - skip: Skip - discard_draft: Discard draft - pinned: Pinned - all: All - question: Question - answer: Answer - comment: Comment - refresh: Refresh - resend: Resend - deactivate: Deactivate - active: Active - suspend: Suspend - unsuspend: Unsuspend - close: Close - reopen: Reopen - ok: OK - light: Light - dark: Dark - system_setting: System setting - default: Default - reset: Reset - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignore - submit: Submit - normal: Normal - closed: Closed - deleted: Deleted - deleted_permanently: Deleted permanently - pending: Pending - more: More - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Search Results - keywords: Keywords - options: Options - follow: Follow - following: Following - counts: "{{count}} Results" - counts_loading: "... Results" - more: More - sort_btns: - relevance: Relevance - newest: Newest - active: Active - score: Score - more: More - tips: - title: Advanced Search Tips - tag: "<1>[tag] search with a tag" - user: "<1>user:username search by author" - answer: "<1>answers:0 unanswered questions" - score: "<1>score:3 posts with a 3+ score" - question: "<1>is:question search questions" - is_answer: "<1>is:answer search answers" - empty: We couldn't find anything.
        Try different or less specific keywords. - share: - name: Share - copy: Copy link - via: Share post via... - copied: Copied - facebook: Share to Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post. - modal_confirm: - title: Error... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Your new account is confirmed; you will be redirected to the home page. - link: Continue to homepage - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: Your email has been updated. - confirm_new_email_invalid: >- - Sorry, this confirmation link is no longer valid. Perhaps your email was already changed? - unsubscribe: - page_title: Unsubscribe - success_title: Unsubscribe Successful - success_desc: You have been successfully removed from this subscriber list and won't receive any further emails from us. - link: Change settings - question: - following_tags: Following Tags - edit: Edit - save: Save - follow_tag_tip: Follow tags to curate your list of questions. - hot_questions: Hot Questions - all_questions: All Questions - x_questions: "{{ count }} Questions" - x_answers: "{{ count }} answers" - x_posts: "{{ count }} Posts" - questions: Questions - answers: Answers - newest: Newest - active: Active - hot: Hot - frequent: Frequent - recommend: Recommend - score: Score - unanswered: Unanswered - modified: modified - answered: answered - asked: asked - closed: closed - follow_a_tag: Follow a tag - more: More - personal: - overview: Overview - answers: Answers - answer: answer - questions: Questions - question: question - bookmarks: Bookmarks - reputation: Reputation - comments: Comments - votes: Votes - badges: Badges - newest: Newest - score: Score - edit_profile: Edit profile - visited_x_days: "Visited {{ count }} days" - viewed: Viewed - joined: Joined - comma: "," - last_login: Seen - about_me: About Me - about_me_empty: "// Hello, World !" - top_answers: Top Answers - top_questions: Top Questions - stats: Stats - list_empty: No posts found.
        Perhaps you'd like to select a different tab? - content_empty: No posts found. - accepted: Accepted - answered: answered - asked: asked - downvoted: downvoted - mod_short: MOD - mod_long: Moderators - x_reputation: reputation - x_votes: votes received - x_answers: answers - x_questions: questions - recent_badges: Recent Badges - install: - title: Installation - next: Next - done: Done - config_yaml_error: Can't create the config.yaml file. - lang: - label: Please choose a language - db_type: - label: Database engine - db_username: - label: Username - placeholder: root - msg: Username cannot be empty. - db_password: - label: Password - placeholder: root - msg: Password cannot be empty. - db_host: - label: Database host - placeholder: "db:3306" - msg: Database host cannot be empty. - db_name: - label: Database name - placeholder: answer - msg: Database name cannot be empty. - db_file: - label: Database file - placeholder: /data/answer.db - msg: Database file cannot be empty. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Create config.yaml - label: The config.yaml file created. - desc: >- - You can create the <1>config.yaml file manually in the <1>/var/wwww/xxx/ directory and paste the following text into it. - info: After you've done that, click "Next" button. - site_information: Site Information - admin_account: Admin Account - site_name: - label: Site name - msg: Site name cannot be empty. - msg_max_length: Site name must be at maximum 30 characters in length. - site_url: - label: Site URL - text: The address of your site. - msg: - empty: Site URL cannot be empty. - incorrect: Site URL incorrect format. - max_length: Site URL must be at maximum 512 characters in length. - contact_email: - label: Contact email - text: Email address of key contact responsible for this site. - msg: - empty: Contact email cannot be empty. - incorrect: Contact email incorrect format. - login_required: - label: Private - switch: Login required - text: Only logged in users can access this community. - admin_name: - label: Name - msg: Name cannot be empty. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Password - text: >- - You will need this password to log in. Please store it in a secure location. - msg: Password cannot be empty. - msg_min_length: Password must be at least 8 characters in length. - msg_max_length: Password must be at maximum 32 characters in length. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: Email - text: You will need this email to log in. - msg: - empty: Email cannot be empty. - incorrect: Email incorrect format. - ready_title: Your site is ready - ready_desc: >- - If you ever feel like changing more settings, visit <1>admin section; find it in the site menu. - good_luck: "Have fun, and good luck!" - warn_title: Warning - warn_desc: >- - The file <1>config.yaml already exists. If you need to reset any of the configuration items in this file, please delete it first. - install_now: You may try <1>installing now. - installed: Already installed - installed_desc: >- - You appear to have already installed. To reinstall please clear your old database tables first. - db_failed: Database connection failed - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: views - votes: votes - answers: answers - accepted: Accepted - page_error: - http_error: HTTP Error {{ code }} - desc_403: You don't have permission to access this page. - desc_404: Unfortunately, this page doesn't exist. - desc_50X: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "We are under maintenance, we'll be back soon." - nav_menus: - dashboard: Dashboard - contents: Contents - questions: Questions - answers: Answers - users: Users - badges: Badges - flags: Flags - settings: Settings - general: General - interface: Interface - smtp: SMTP - branding: Branding - legal: Legal - write: Write - terms: Terms - tos: Terms of Service - privacy: Privacy - seo: SEO - customize: Customize - themes: Themes - login: Login - privileges: Privileges - plugins: Plugins - installed_plugins: Installed Plugins - apperance: Appearance - website_welcome: Welcome to {{site_name}} - user_center: - login: Login - qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. - login_failed_email_tip: Login failed, please allow this app to access your email information before try again. - badges: - modal: - title: Congratulations - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - admin: - admin_header: - title: Admin - dashboard: - title: Dashboard - welcome: Welcome to Admin! - site_statistics: Site statistics - questions: "Questions:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "Answers:" - comments: "Comments:" - votes: "Votes:" - users: "Users:" - flags: "Flags:" - reviews: "Reviews:" - site_health: Site health - version: "Version:" - https: "HTTPS:" - upload_folder: "Upload folder:" - run_mode: "Running mode:" - private: Private - public: Public - smtp: "SMTP:" - timezone: "Timezone:" - system_info: System info - go_version: "Go version:" - database: "Database:" - database_size: "Database size:" - storage_used: "Storage used:" - uptime: "Uptime:" - links: Links - plugins: Plugins - github: GitHub - blog: Blog - contact: Contact - forum: Forum - documents: Documents - feedback: Feedback - support: Support - review: Review - config: Config - update_to: Update to - latest: Latest - check_failed: Check failed - "yes": "Yes" - "no": "No" - not_allowed: Not allowed - allowed: Allowed - enabled: Enabled - disabled: Disabled - writable: Writable - not_writable: Not writable - flags: - title: Flags - pending: Pending - completed: Completed - flagged: Flagged - flagged_type: Flagged {{ type }} - created: Created - action: Action - review: Review - user_role_modal: - title: Change user role to... - btn_cancel: Cancel - btn_submit: Submit - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - edit_profile_modal: - title: Edit profile - form: - fields: - display_name: - label: Display name - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Invalid Email Address. - edit_success: Edited successfully - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - users: - label: Bulk add user - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separate “name, email, password” with commas. One user per line. - msg: "Please enter the user's email, one per line." - display_name: - label: Display name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - users: - title: Users - name: Name - email: Email - reputation: Reputation - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Status - role: Role - action: Action - change: Change - all: All - staff: Staff - more: More - inactive: Inactive - suspended: Suspended - deleted: Deleted - normal: Normal - Moderator: Moderator - Admin: Admin - User: User - filter: - placeholder: "Filter by name, user:id" - set_new_password: Set new password - edit_profile: Edit profile - change_status: Change status - change_role: Change role - show_logs: Show logs - add_user: Add user - deactivate_user: - title: Deactivate user - content: An inactive user must re-validate their email. - delete_user: - title: Delete this user - content: Are you sure you want to delete this user? This is permanent! - remove: Remove their content - label: Remove all questions, answers, comments, etc. - text: Don’t check this if you wish to only delete the user’s account. - suspend_user: - title: Suspend this user - content: A suspended user can't log in. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Questions - unlisted: Unlisted - post: Post - votes: Votes - answers: Answers - created: Created - status: Status - action: Action - change: Change - pending: Pending - filter: - placeholder: "Filter by title, question:id" - answers: - page_title: Answers - post: Post - votes: Votes - created: Created - status: Status - action: Action - change: Change - filter: - placeholder: "Filter by title, answer:id" - general: - page_title: General - name: - label: Site name - msg: Site name cannot be empty. - text: "The name of this site, as used in the title tag." - site_url: - label: Site URL - msg: Site url cannot be empty. - validate: Please enter a valid URL. - text: The address of your site. - short_desc: - label: Short site description - msg: Short site description cannot be empty. - text: "Short description, as used in the title tag on homepage." - desc: - label: Site description - msg: Site description cannot be empty. - text: "Describe this site in one sentence, as used in the meta description tag." - contact_email: - label: Contact email - msg: Contact email cannot be empty. - validate: Contact email is not valid. - text: Email address of key contact responsible for this site. - check_update: - label: Software updates - text: Automatically check for updates - interface: - page_title: Interface - language: - label: Interface language - msg: Interface language cannot be empty. - text: User interface language. It will change when you refresh the page. - time_zone: - label: Timezone - msg: Timezone cannot be empty. - text: Choose a city in the same timezone as you. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: From email - msg: From email cannot be empty. - text: The email address which emails are sent from. - from_name: - label: From name - msg: From name cannot be empty. - text: The name which emails are sent from. - smtp_host: - label: SMTP host - msg: SMTP host cannot be empty. - text: Your mail server. - encryption: - label: Encryption - msg: Encryption cannot be empty. - text: For most servers SSL is the recommended option. - ssl: SSL - tls: TLS - none: None - smtp_port: - label: SMTP port - msg: SMTP port must be number 1 ~ 65535. - text: The port to your mail server. - smtp_username: - label: SMTP username - msg: SMTP username cannot be empty. - smtp_password: - label: SMTP password - msg: SMTP password cannot be empty. - test_email_recipient: - label: Test email recipients - text: Provide email address that will receive test sends. - msg: Test email recipients is invalid - smtp_authentication: - label: Enable authentication - title: SMTP authentication - msg: SMTP authentication cannot be empty. - "yes": "Yes" - "no": "No" - branding: - page_title: Branding - logo: - label: Logo - msg: Logo cannot be empty. - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile logo - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the "logo" setting will be used. - square_icon: - label: Square icon - msg: Square icon cannot be empty. - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, "square icon" will be used. - legal: - page_title: Legal - terms_of_service: - label: Terms of service - text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." - privacy_policy: - label: Privacy policy - text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Write - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Each user can only write one answer for each question - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Recommend tags - text: "Recommend tags will show in the dropdown list by default." - msg: - contain_reserved: "recommended tags cannot contain reserved tags" - required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags - text: "Every new question must have at least one recommend tag." - reserved_tags: - label: Reserved tags - text: "Reserved tags can only be used by moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: SEO - permalink: - label: Permalink - text: Custom URL structures can improve the usability, and forward-compatibility of your links. - robots: - label: robots.txt - text: This will permanently override any related site settings. - themes: - page_title: Themes - themes: - label: Themes - text: Select an existing theme. - color_scheme: - label: Color scheme - navbar_style: - label: Navbar background style - primary_color: - label: Primary color - text: Modify the colors used by your themes - css_and_html: - page_title: CSS and HTML - custom_css: - label: Custom CSS - text: > - - head: - label: Head - text: > - - header: - label: Header - text: > - - footer: - label: Footer - text: This will insert before </body>. - sidebar: - label: Sidebar - text: This will insert in sidebar. - login: - page_title: Login - membership: - title: Membership - label: Allow new registrations - text: Turn off to prevent anyone from creating a new account. - email_registration: - title: Email registration - label: Allow email registration - text: Turn off to prevent anyone creating new account through email. - allowed_email_domains: - title: Allowed email domains - text: Email domains that users must register accounts with. One domain per line. Ignored when empty. - private: - title: Private - label: Login required - text: Only logged in users can access this community. - password_login: - title: Password login - label: Allow email and password login - text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." - installed_plugins: - title: Installed Plugins - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. - filter: - all: All - active: Active - inactive: Inactive - outdated: Outdated - plugins: - label: Plugins - text: Select an existing plugin. - name: Name - version: Version - status: Status - action: Action - deactivate: Deactivate - activate: Activate - settings: Settings - settings_users: - title: Users - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - profile_editable: - title: Profile editable - allow_update_display_name: - label: Allow users to change their display name - allow_update_username: - label: Allow users to change their username - allow_update_avatar: - label: Allow users to change their profile image - allow_update_bio: - label: Allow users to change their about me - allow_update_website: - label: Allow users to change their website - allow_update_location: - label: Allow users to change their location - privilege: - title: Privileges - level: - label: Reputation required level - text: Choose the reputation required for the privileges - msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 - badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate - filter: - placeholder: Filter by name, badge:id - group: Group - inactive: Inactive - name: Name - show_logs: Show logs - status: Status - title: Badges - form: - optional: (optional) - empty: cannot be empty - invalid: is invalid - btn_submit: Save - not_found_props: "Required property {{ key }} not found." - select: Select - page_review: - review: Review - proposed: proposed - question_edit: Question edit - answer_edit: Answer edit - tag_edit: Tag edit - edit_summary: Edit summary - edit_question: Edit question - edit_answer: Edit answer - edit_tag: Edit tag - empty: No review tasks left. - approve_revision_tip: Do you approve this revision? - approve_flag_tip: Do you approve this flag? - approve_post_tip: Do you approve this post? - approve_user_tip: Do you approve this user? - suggest_edits: Suggested edits - flag_post: Flag post - flag_user: Flag user - queued_post: Queued post - queued_user: Queued user - filter_label: Type - reputation: reputation - flag_post_type: Flagged this post as {{ type }}. - flag_user_type: Flagged this user as {{ type }}. - edit_post: Edit post - list_post: List post - unlist_post: Unlist post - timeline: - undeleted: undeleted - deleted: deleted - downvote: downvote - upvote: upvote - accept: accept - cancelled: cancelled - commented: commented - rollback: rollback - edited: edited - answered: answered - asked: asked - closed: closed - reopened: reopened - created: created - pin: pinned - unpin: unpinned - show: listed - hide: unlisted - title: "History for" - tag_title: "Timeline for" - show_votes: "Show votes" - n_or_a: N/A - title_for_question: "Timeline for" - title_for_answer: "Timeline for answer to {{ title }} by {{ author }}" - title_for_tag: "Timeline for tag" - datetime: Datetime - type: Type - by: By - comment: Comment - no_data: "We couldn't find anything." - users: - title: Users - users_with_the_most_reputation: Users with the highest reputation scores this week - users_with_the_most_vote: Users who voted the most this week - staffs: Our community staff - reputation: reputation - votes: votes - prompt: - leave_page: Are you sure you want to leave the page? - changes_not_save: Your changes may not be saved. - draft: - discard_confirm: Are you sure you want to discard your draft? - messages: - post_deleted: This post has been deleted. - post_cancel_deleted: This post has been undeleted. - post_pin: This post has been pinned. - post_unpin: This post has been unpinned. - post_hide_list: This post has been hidden from list. - post_show_list: This post has been shown to list. - post_reopen: This post has been reopened. - post_list: This post has been listed. - post_unlist: This post has been unlisted. - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/tr_TR.yaml b/data/i18n/tr_TR.yaml deleted file mode 100644 index 802a81f69..000000000 --- a/data/i18n/tr_TR.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Başarılı. - unknown: - other: Bilinmeyen hata. - request_format_error: - other: İstek formatı geçerli değil. - unauthorized_error: - other: Yetkisiz erişim. - database_error: - other: Veri tabanı sunucu hatası. - forbidden_error: - other: Erişim engellendi. - duplicate_request_error: - other: Yinelenen gönderim. - action: - report: - other: Bildir - edit: - other: Düzenle - delete: - other: Sil - close: - other: Kapat - reopen: - other: Yeniden Aç - forbidden_error: - other: Erişim engellendi. - pin: - other: Sabitle - hide: - other: Listeden Kaldır - unpin: - other: Sabitlemeyi Kaldır - show: - other: Listele - invite_someone_to_answer: - other: Cevaplamaya Davet Et - undelete: - other: Silmeyi Geri Al - merge: - other: Birleştir - role: - name: - user: - other: Kullanıcı - admin: - other: Yönetici - moderator: - other: Moderatör - description: - user: - other: Özel erişimi olmayan varsayılan kullanıcı. - admin: - other: Siteye tam erişim gücüne sahiptir. - moderator: - other: Yönetici ayarları dışında tüm gönderilere erişebilir. - privilege: - level_1: - description: - other: Seviye 1 (özel takım, grup için daha az itibar gerektirir) - level_2: - description: - other: Seviye 2 (başlangıç topluluğu için düşük itibar gerektirir) - level_3: - description: - other: Seviye 3 (gelişmiş topluluk için yüksek itibar gerektirir) - level_custom: - description: - other: Özel Seviye - rank_question_add_label: - other: Soru sor - rank_answer_add_label: - other: Cevap yaz - rank_comment_add_label: - other: Yorum yaz - rank_report_add_label: - other: Bildir - rank_comment_vote_up_label: - other: Yorumu yukarı oyla - rank_link_url_limit_label: - other: Bir seferde 2'den fazla bağlantı paylaş - rank_question_vote_up_label: - other: Soruyu yukarı oyla - rank_answer_vote_up_label: - other: Cevabı yukarı oyla - rank_question_vote_down_label: - other: Soruyu aşağı oyla - rank_answer_vote_down_label: - other: Cevabı aşağı oyla - rank_invite_someone_to_answer_label: - other: Birini cevaplamaya davet et - rank_tag_add_label: - other: Yeni etiket oluştur - rank_tag_edit_label: - other: Etiket açıklamasını düzenle (inceleme gerekli) - rank_question_edit_label: - other: Başkasının sorusunu düzenle (inceleme gerekli) - rank_answer_edit_label: - other: Başkasının cevabını düzenle (inceleme gerekli) - rank_question_edit_without_review_label: - other: Başkasının sorusunu inceleme olmadan düzenle - rank_answer_edit_without_review_label: - other: Başkasının cevabını inceleme olmadan düzenle - rank_question_audit_label: - other: Soru düzenlemelerini incele - rank_answer_audit_label: - other: Cevap düzenlemelerini incele - rank_tag_audit_label: - other: Etiket düzenlemelerini incele - rank_tag_edit_without_review_label: - other: Etiket açıklamasını inceleme olmadan düzenle - rank_tag_synonym_label: - other: Etiket eş anlamlılarını yönet - email: - other: E-posta - e_mail: - other: E-posta - password: - other: Parola - pass: - other: Parola - old_pass: - other: Mevcut parola - original_text: - other: Bu gönderi - email_or_password_wrong_error: - other: E-posta ve parola eşleşmiyor. - error: - common: - invalid_url: - other: Geçersiz URL. - status_invalid: - other: Geçersiz durum. - password: - space_invalid: - other: Parola boşluk içeremez. - admin: - cannot_update_their_password: - other: Parolanızı değiştiremezsiniz. - cannot_edit_their_profile: - other: Profilinizi değiştiremezsiniz. - cannot_modify_self_status: - other: Durumunuzu değiştiremezsiniz. - email_or_password_wrong: - other: E-posta ve parola eşleşmiyor. - answer: - not_found: - other: Cevap bulunamadı. - cannot_deleted: - other: Silme izni yok. - cannot_update: - other: Güncelleme izni yok. - question_closed_cannot_add: - other: Sorular kapatıldı ve cevap eklenemez. - content_cannot_empty: - other: Cevap içeriği boş olamaz. - comment: - edit_without_permission: - other: Yorumları düzenleme izniniz yok. - not_found: - other: Yorum bulunamadı. - cannot_edit_after_deadline: - other: Yorum süresi çok uzun olduğu için artık düzenlenemez. - content_cannot_empty: - other: Yorum içeriği boş olamaz. - email: - duplicate: - other: Bu e-posta adresi zaten kullanılmaktadır. - need_to_be_verified: - other: E-posta doğrulanmalıdır. - verify_url_expired: - other: E-posta doğrulama URL'sinin süresi dolmuş, lütfen e-postayı yeniden gönderin. - illegal_email_domain_error: - other: Bu e-posta alan adına izin verilmiyor. Lütfen başka bir e-posta kullanın. - lang: - not_found: - other: Dil dosyası bulunamadı. - object: - captcha_verification_failed: - other: Captcha yanlış. - disallow_follow: - other: Takip etme izniniz yok. - disallow_vote: - other: Oy verme izniniz yok. - disallow_vote_your_self: - other: Kendi gönderinize oy veremezsiniz. - not_found: - other: Nesne bulunamadı. - verification_failed: - other: Doğrulama başarısız. - email_or_password_incorrect: - other: E-posta ve parola eşleşmiyor. - old_password_verification_failed: - other: Eski parola doğrulaması başarısız oldu. - new_password_same_as_previous_setting: - other: Yeni parola öncekiyle aynı. - already_deleted: - other: Bu gönderi silinmiş. - meta: - object_not_found: - other: Meta nesnesi bulunamadı. - question: - already_deleted: - other: Bu gönderi silinmiş. - under_review: - other: Gönderiniz inceleme bekliyor. Onaylandıktan sonra görünür olacaktır. - not_found: - other: Soru bulunamadı. - cannot_deleted: - other: Silme izni yok. - cannot_close: - other: Kapatma izni yok. - cannot_update: - other: Güncelleme izni yok. - content_cannot_empty: - other: İçerik boş olamaz. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: İtibar seviyesi koşulu karşılamıyor. - vote_fail_to_meet_the_condition: - other: Geri bildiriminiz için teşekkürler. Oy kullanmak için en az {{.Rank}} itibara ihtiyacınız var. - no_enough_rank_to_operate: - other: Bu işlemi yapmak için en az {{.Rank}} itibara ihtiyacınız var. - report: - handle_failed: - other: Rapor işleme başarısız. - not_found: - other: Rapor bulunamadı. - tag: - already_exist: - other: Etiket zaten var. - not_found: - other: Etiket bulunamadı. - recommend_tag_not_found: - other: Önerilen etiket mevcut değil. - recommend_tag_enter: - other: Lütfen en az bir adet gerekli etiket giriniz. - not_contain_synonym_tags: - other: Eş anlamlı etiketler içermemelidir. - cannot_update: - other: Güncelleme izni yok. - is_used_cannot_delete: - other: Kullanımda olan bir etiketi silemezsiniz. - cannot_set_synonym_as_itself: - other: Bir etiketin eş anlamlısını kendisi olarak ayarlayamazsınız. - minimum_count: - other: Yeterli sayıda etiket girilmedi. - smtp: - config_from_name_cannot_be_email: - other: Gönderen adı bir e-posta adresi olamaz. - theme: - not_found: - other: Tema bulunamadı. - revision: - review_underway: - other: Şu anda düzenlenemez, inceleme kuyruğunda bir sürüm var. - no_permission: - other: Düzenleme izniniz yok. - user: - external_login_missing_user_id: - other: Üçüncü taraf platform benzersiz bir Kullanıcı ID'si sağlamıyor, bu nedenle giriş yapamazsınız. Lütfen site yöneticisiyle iletişime geçin. - external_login_unbinding_forbidden: - other: Bu girişi kaldırmadan önce lütfen hesabınız için bir giriş parolası ayarlayın. - email_or_password_wrong: - other: - other: E-posta ve parola eşleşmiyor. - not_found: - other: Kullanıcı bulunamadı. - suspended: - other: Kullanıcı askıya alındı. - username_invalid: - other: Kullanıcı adı geçersiz. - username_duplicate: - other: Kullanıcı adı zaten kullanımda. - set_avatar: - other: Avatar ayarlama başarısız. - cannot_update_your_role: - other: Kendi rolünüzü değiştiremezsiniz. - not_allowed_registration: - other: Şu anda site kayıt için açık değil. - not_allowed_login_via_password: - other: Şu anda site parola ile giriş yapmaya izin vermiyor. - access_denied: - other: Erişim reddedildi. - page_access_denied: - other: Bu sayfaya erişim izniniz yok. - add_bulk_users_format_error: - other: "{{.Line}} satırındaki '{{.Content}}' içeriğinde {{.Field}} biçimi hatası. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "Bir kerede eklediğiniz kullanıcı sayısı 1-{{.MaxAmount}} aralığında olmalıdır." - status_suspended_forever: - other: "Bu kullanıcı süresiz olarak askıya alındı. Bu kullanıcı topluluk kurallarını karşılamıyor." - status_suspended_until: - other: "Bu kullanıcı {{.SuspendedUntil}} tarihine kadar askıya alındı. Bu kullanıcı topluluk kurallarını karşılamıyor." - status_deleted: - other: "Bu kullanıcı silindi." - status_inactive: - other: "Bu kullanıcı aktif değil." - config: - read_config_failed: - other: Yapılandırma okunamadı. - database: - connection_failed: - other: Veritabanı bağlantısı başarısız. - create_table_failed: - other: Tablo oluşturma başarısız. - install: - create_config_failed: - other: config.yaml dosyası oluşturulamıyor. - upload: - unsupported_file_format: - other: Desteklenmeyen dosya formatı. - site_info: - config_not_found: - other: Site yapılandırması bulunamadı. - badge: - object_not_found: - other: Rozet nesnesi bulunamadı. - reason: - spam: - name: - other: spam - desc: - other: Bu gönderi bir reklam veya vandalizm. Mevcut konuyla ilgili veya yararlı değil. - rude_or_abusive: - name: - other: kaba veya taciz edici - desc: - other: "Makul bir kişi bu içeriği saygılı bir iletişim için uygunsuz bulurdu." - a_duplicate: - name: - other: kopya - desc: - other: Bu soru daha önce sorulmuş ve cevaplandırılmış. - placeholder: - other: Mevcut soru bağlantısını girin - not_a_answer: - name: - other: cevap değil - desc: - other: "Bu bir cevap olarak gönderilmiş, ancak soruyu cevaplamaya çalışmıyor. Bir düzenleme, yorum, başka bir soru olabilir veya tamamen silinmesi gerekebilir." - no_longer_needed: - name: - other: artık gerekli değil - desc: - other: Bu yorum güncelliğini yitirmiş, sohbet niteliğinde veya bu gönderiyle ilgili değil. - something: - name: - other: başka bir şey - desc: - other: Bu gönderi, yukarıda listelenmeyen başka bir nedenden dolayı personel ilgisi gerektiriyor. - placeholder: - other: Endişelerinizin ne olduğunu spesifik olarak belirtin - community_specific: - name: - other: topluluk kurallarına aykırı - desc: - other: Bu soru bir topluluk kılavuzuna uymuyor. - not_clarity: - name: - other: detay veya açıklık gerekiyor - desc: - other: Bu soru şu anda tek soruda birden fazla soru içeriyor. Sadece tek bir soruna odaklanmalı. - looks_ok: - name: - other: iyi görünüyor - desc: - other: Bu gönderi olduğu gibi iyi ve düşük kaliteli değil. - needs_edit: - name: - other: düzenleme gerektiriyor ve ben yaptım - desc: - other: Bu gönderideki sorunları kendiniz düzeltin ve iyileştirin. - needs_close: - name: - other: kapatılması gerekiyor - desc: - other: Kapatılmış bir soru cevaplanamaz, ancak düzenlenebilir, oylanabilir ve yorum yapılabilir. - needs_delete: - name: - other: silinmesi gerekiyor - desc: - other: Bu gönderi silinecek. - question: - close: - duplicate: - name: - other: kopya - desc: - other: Bu soru daha önce sorulmuş ve cevaplandırılmış. - guideline: - name: - other: topluluk kurallarına aykırı - desc: - other: Bu soru bir topluluk kılavuzuna uymuyor. - multiple: - name: - other: detay veya açıklık gerekiyor - desc: - other: Bu soru şu anda tek soruda birden fazla soru içeriyor. Sadece tek bir soruna odaklanmalı. - other: - name: - other: başka bir şey - desc: - other: Bu gönderi yukarıda listelenmeyen başka bir neden gerektiriyor. - operation_type: - asked: - other: soruldu - answered: - other: cevaplandı - modified: - other: değiştirildi - deleted_title: - other: Silinmiş soru - questions_title: - other: Sorular - tag: - tags_title: - other: Etiketler - no_description: - other: Bu etiketin açıklaması yok. - notification: - action: - update_question: - other: soruyu güncelledi - answer_the_question: - other: soruyu cevapladı - update_answer: - other: cevabı güncelledi - accept_answer: - other: cevabı kabul etti - comment_question: - other: soruya yorum yaptı - comment_answer: - other: cevaba yorum yaptı - reply_to_you: - other: size yanıt verdi - mention_you: - other: sizden bahsetti - your_question_is_closed: - other: Sorunuz kapatıldı - your_question_was_deleted: - other: Sorunuz silindi - your_answer_was_deleted: - other: Cevabınız silindi - your_comment_was_deleted: - other: Yorumunuz silindi - up_voted_question: - other: soruyu yukarı oyladı - down_voted_question: - other: soruyu aşağı oyladı - up_voted_answer: - other: cevabı yukarı oyladı - down_voted_answer: - other: cevabı aşağı oyladı - up_voted_comment: - other: yorumu yukarı oyladı - invited_you_to_answer: - other: sizi cevaplamaya davet etti - earned_badge: - other: Rozet kazandınız "{{.BadgeName}}" - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Yeni e-posta adresinizi onaylayın" - body: - other: "{{.SiteName}} için aşağıdaki bağlantıya tıklayarak yeni e-posta adresinizi onaylayın:
        \n{{.ChangeEmailUrl}}

        \n\nEğer bu değişikliği siz talep etmediyseniz, lütfen bu e-postayı dikkate almayın.

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} sorunuzu cevapladı" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \n{{.SiteName}} üzerinde görüntüle

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir.

        \n\nAbonelikten çık" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} sizi cevaplamaya davet etti" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Cevabı biliyor olabileceğinizi düşünüyorum.

        \n{{.SiteName}} üzerinde görüntüle

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir.

        \n\nAbonelikten çık" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} gönderinize yorum yaptı" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \n{{.SiteName}} üzerinde görüntüle

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir.

        \n\nAbonelikten çık" - new_question: - title: - other: "[{{.SiteName}}] Yeni soru: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir.

        \n\nAbonelikten çık" - pass_reset: - title: - other: "[{{.SiteName }}] Parola sıfırlama" - body: - other: "Birisi {{.SiteName}} üzerindeki parolanızı sıfırlamak istedi.

        \n\nEğer bu siz değilseniz, bu e-postayı güvenle görmezden gelebilirsiniz.

        \n\nYeni bir parola seçmek için aşağıdaki bağlantıya tıklayın:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir." - register: - title: - other: "[{{.SiteName}}] Yeni hesabınızı onaylayın" - body: - other: "{{.SiteName}} sitesine hoş geldiniz!

        \n\nYeni hesabınızı onaylamak ve etkinleştirmek için aşağıdaki bağlantıya tıklayın:
        \n{{.RegisterUrl}}

        \n\nYukarıdaki bağlantı tıklanabilir değilse, web tarayıcınızın adres çubuğuna kopyalayıp yapıştırmayı deneyin.\n

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir." - test: - title: - other: "[{{.SiteName}}] Test E-postası" - body: - other: "Bu bir test e-postasıdır.\n

        \n\n--
        \nNot: Bu otomatik bir sistem e-postasıdır, lütfen bu mesaja yanıt vermeyin çünkü cevabınız görülmeyecektir." - action_activity_type: - upvote: - other: yukarı oyla - upvoted: - other: yukarı oyladı - downvote: - other: aşağı oyla - downvoted: - other: aşağı oyladı - accept: - other: kabul et - accepted: - other: kabul edildi - edit: - other: düzenle - review: - queued_post: - other: Sıradaki gönderi - flagged_post: - other: Bildirilen gönderi - suggested_post_edit: - other: Önerilen düzenlemeler - reaction: - tooltip: - other: "{{ .Names }} ve {{ .Count }} kişi daha..." - badge: - default_badges: - autobiographer: - name: - other: Otobiyografi Yazarı - desc: - other: Profil bilgilerini doldurdu. - certified: - name: - other: Sertifikalı - desc: - other: Yeni kullanıcı eğitimimizi tamamladı. - editor: - name: - other: Editör - desc: - other: İlk gönderi düzenlemesi. - first_flag: - name: - other: İlk Bildirim - desc: - other: İlk kez bir gönderiyi bildirdi. - first_upvote: - name: - other: İlk Yukarı Oylama - desc: - other: İlk kez bir gönderiyi yukarı oyladı. - first_link: - name: - other: İlk Bağlantı - desc: - other: İlk kez başka bir gönderiye bağlantı ekledi. - first_reaction: - name: - other: İlk Tepki - desc: - other: İlk kez bir gönderiye tepki verdi. - first_share: - name: - other: İlk Paylaşım - desc: - other: İlk kez bir gönderi paylaştı. - scholar: - name: - other: Bilim İnsanı - desc: - other: Bir soru sordu ve bir cevabı kabul etti. - commentator: - name: - other: Yorumcu - desc: - other: 5 yorum bıraktı. - new_user_of_the_month: - name: - other: Ayın Yeni Kullanıcısı - desc: - other: İlk aylarında üstün katkılarda bulundu. - read_guidelines: - name: - other: Kuralları Okuyan - desc: - other: '[Topluluk kurallarını] oku.' - reader: - name: - other: Okuyucu - desc: - other: 10'dan fazla cevap içeren bir konudaki tüm cevapları okudu. - welcome: - name: - other: Hoş Geldin - desc: - other: Bir yukarı oy aldı. - nice_share: - name: - other: Güzel Paylaşım - desc: - other: 25 farklı ziyaretçi tarafından görüntülenen bir gönderi paylaştı. - good_share: - name: - other: İyi Paylaşım - desc: - other: 300 farklı ziyaretçi tarafından görüntülenen bir gönderi paylaştı. - great_share: - name: - other: Harika Paylaşım - desc: - other: 1000 farklı ziyaretçi tarafından görüntülenen bir gönderi paylaştı. - out_of_love: - name: - other: Sevgiden - desc: - other: Bir günde 50 yukarı oy kullandı. - higher_love: - name: - other: Yüksek Sevgi - desc: - other: Bir günde 50 yukarı oyu 5 kez kullandı. - crazy_in_love: - name: - other: Çılgınca Aşık - desc: - other: Bir günde 50 yukarı oyu 20 kez kullandı. - promoter: - name: - other: Destekçi - desc: - other: Bir kullanıcıyı davet etti. - campaigner: - name: - other: Kampanyacı - desc: - other: 3 temel kullanıcıyı davet etti. - champion: - name: - other: Şampiyon - desc: - other: 5 üye davet etti. - thank_you: - name: - other: Teşekkürler - desc: - other: 20 yukarı oy aldı ve 10 yukarı oy verdi. - gives_back: - name: - other: Karşılık Veren - desc: - other: 100 yukarı oy aldı ve 100 yukarı oy verdi. - empathetic: - name: - other: Empatik - desc: - other: 500 yukarı oy aldı ve 1000 yukarı oy verdi. - enthusiast: - name: - other: Hevesli - desc: - other: 10 gün üst üste ziyaret etti. - aficionado: - name: - other: Meraklı - desc: - other: 100 gün üst üste ziyaret etti. - devotee: - name: - other: Hayran - desc: - other: 365 gün üst üste ziyaret etti. - anniversary: - name: - other: Yıldönümü - desc: - other: Bir yıl boyunca aktif üye, en az bir gönderi paylaştı. - appreciated: - name: - other: Takdir Edilen - desc: - other: 20 gönderisinde 1 yukarı oy aldı. - respected: - name: - other: Saygın - desc: - other: 100 gönderisinde 2 yukarı oy aldı. - admired: - name: - other: Hayranlık Uyandıran - desc: - other: 300 gönderisinde 5 yukarı oy aldı. - solved: - name: - other: Çözüldü - desc: - other: Bir cevabı kabul edildi. - guidance_counsellor: - name: - other: Rehber Danışman - desc: - other: 10 cevabı kabul edildi. - know_it_all: - name: - other: Her Şeyi Bilen - desc: - other: 50 cevabı kabul edildi. - solution_institution: - name: - other: Çözüm Kurumu - desc: - other: 150 cevabı kabul edildi. - nice_answer: - name: - other: Güzel Cevap - desc: - other: 10 veya daha fazla cevap puanı. - good_answer: - name: - other: İyi Cevap - desc: - other: 25 veya daha fazla cevap puanı. - great_answer: - name: - other: Harika Cevap - desc: - other: 50 veya daha fazla cevap puanı. - nice_question: - name: - other: Güzel Soru - desc: - other: 10 veya daha fazla soru puanı. - good_question: - name: - other: İyi Soru - desc: - other: 25 veya daha fazla soru puanı. - great_question: - name: - other: Harika Soru - desc: - other: 50 veya daha fazla soru puanı. - popular_question: - name: - other: Popüler Soru - desc: - other: 500 görüntülenme alan soru. - notable_question: - name: - other: Dikkat Çeken Soru - desc: - other: 1.000 görüntülenme alan soru. - famous_question: - name: - other: Ünlü Soru - desc: - other: 5.000 görüntülenme alan soru. - popular_link: - name: - other: Popüler Bağlantı - desc: - other: 50 tıklama alan harici bir bağlantı paylaştı. - hot_link: - name: - other: Sıcak Bağlantı - desc: - other: 300 tıklama alan harici bir bağlantı paylaştı. - famous_link: - name: - other: Ünlü Bağlantı - desc: - other: 100 tıklama alan harici bir bağlantı paylaştı. - default_badge_groups: - getting_started: - name: - other: Başlangıç - community: - name: - other: Topluluk - posting: - name: - other: Gönderi Yazmak -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Nasıl Biçimlendirilir - desc: >- -
        • bir gönderiden bahsetmek için: #post_id

        • bağlantı oluşturmak için

          <https://url.com>

          [Başlık](https://url.com)
        • paragraflar arasında boşluk bırakın

        • _italik_ veya **kalın**

        • kodu 4 boşlukla girintileyin

        • satırın başına > koyarak alıntı yapın

        • ters tırnak işaretleriyle kaçış yapın `_böyle_`

        • ters tırnak işaretleriyle ` kod blokları oluşturun

          ```
          kod buraya
          ```
        - pagination: - prev: Önceki - next: Sonraki - page_title: - question: Soru - questions: Sorular - tag: Etiket - tags: Etiketler - tag_wiki: etiket wikisi - create_tag: Etiket Oluştur - edit_tag: Etiketi Düzenle - ask_a_question: Soru Oluştur - edit_question: Soruyu Düzenle - edit_answer: Cevabı Düzenle - search: Ara - posts_containing: İçeren gönderiler - settings: Ayarlar - notifications: Bildirimler - login: Giriş Yap - sign_up: Kayıt Ol - account_recovery: Hesap Kurtarma - account_activation: Hesap Aktivasyonu - confirm_email: E-posta Onayı - account_suspended: Hesap Askıya Alındı - admin: Yönetici - change_email: E-posta Değiştir - install: Answer Kurulumu - upgrade: Answer Yükseltme - maintenance: Website Bakımı - users: Kullanıcılar - oauth_callback: İşleniyor - http_404: HTTP Hatası 404 - http_50X: HTTP Hatası 500 - http_403: HTTP Hatası 403 - logout: Çıkış Yap - posts: Gönderiler - notifications: - title: Bildirimler - inbox: Gelen Kutusu - achievement: Başarılar - new_alerts: Yeni uyarılar - all_read: Tümünü okundu olarak işaretle - show_more: Daha fazla göster - someone: Birisi - inbox_type: - all: Tümü - posts: Gönderiler - invites: Davetler - votes: Oylar - answer: Cevap - question: Soru - badge_award: Rozet - suspended: - title: Hesabınız Askıya Alındı - until_time: "Hesabınız {{ time }} tarihine kadar askıya alındı." - forever: Bu kullanıcı süresiz olarak askıya alındı. - end: Topluluk kurallarını karşılamıyorsunuz. - contact_us: Bize ulaşın - editor: - blockquote: - text: Alıntı - bold: - text: Kalın - chart: - text: Grafik - flow_chart: Akış şeması - sequence_diagram: Sıralama diyagramı - class_diagram: Sınıf diyagramı - state_diagram: Durum diyagramı - entity_relationship_diagram: Varlık ilişki diyagramı - user_defined_diagram: Kullanıcı tanımlı diyagram - gantt_chart: Gantt şeması - pie_chart: Pasta grafiği - code: - text: Kod Örneği - add_code: Kod örneği ekle - form: - fields: - code: - label: Kod - msg: - empty: Kod boş olamaz. - language: - label: Dil - placeholder: Otomatik algılama - btn_cancel: İptal - btn_confirm: Ekle - formula: - text: Formül - options: - inline: Satır içi formül - block: Blok formül - heading: - text: Başlık - options: - h1: Başlık 1 - h2: Başlık 2 - h3: Başlık 3 - h4: Başlık 4 - h5: Başlık 5 - h6: Başlık 6 - help: - text: Yardım - hr: - text: Yatay çizgi - image: - text: Resim - add_image: Resim ekle - tab_image: Resim Yükle - form_image: - fields: - file: - label: Resim dosyası - btn: Resim seç - msg: - empty: Dosya boş olamaz. - only_image: Sadece resim dosyalarına izin verilir. - max_size: Dosya boyutu {{size}} MB'ı geçemez. - desc: - label: Açıklama - tab_url: Resim URL'si - form_url: - fields: - url: - label: Resim URL'si - msg: - empty: Resim URL'si boş olamaz. - name: - label: Açıklama - btn_cancel: İptal - btn_confirm: Ekle - uploading: Yükleniyor - indent: - text: Girinti - outdent: - text: Girintiyi azalt - italic: - text: İtalik - link: - text: Bağlantı - add_link: Bağlantı ekle - form: - fields: - url: - label: URL - msg: - empty: URL boş olamaz. - name: - label: Açıklama - btn_cancel: İptal - btn_confirm: Ekle - ordered_list: - text: Numaralı liste - unordered_list: - text: Madde işaretli liste - table: - text: Tablo - heading: Başlık - cell: Hücre - file: - text: Dosya ekle - not_supported: "Bu dosya türü desteklenmiyor. {{file_type}} ile tekrar deneyin." - max_size: "Eklenen dosyaların boyutu {{size}} MB'ı geçemez." - close_modal: - title: Bu gönderiyi kapatıyorum çünkü... - btn_cancel: İptal - btn_submit: Gönder - remark: - empty: Boş olamaz. - msg: - empty: Lütfen bir neden seçin. - report_modal: - flag_title: Bu gönderiyi şu nedenle bildiriyorum... - close_title: Bu gönderiyi şu nedenle kapatıyorum... - review_question_title: Soruyu incele - review_answer_title: Cevabı incele - review_comment_title: Yorumu incele - btn_cancel: İptal - btn_submit: Gönder - remark: - empty: Boş olamaz. - msg: - empty: Lütfen bir neden seçin. - not_a_url: URL formatı yanlış. - url_not_match: URL kaynağı mevcut web sitesiyle eşleşmiyor. - tag_modal: - title: Yeni etiket oluştur - form: - fields: - display_name: - label: Görünen ad - msg: - empty: Görünen ad boş olamaz. - range: Görünen ad en fazla 35 karakter olabilir. - slug_name: - label: URL kısaltması - desc: URL kısaltması en fazla 35 karakter olabilir. - msg: - empty: URL kısaltması boş olamaz. - range: URL kısaltması en fazla 35 karakter olabilir. - character: URL kısaltması izin verilmeyen karakter içeriyor. - desc: - label: Açıklama - revision: - label: Revizyon - edit_summary: - label: Düzenleme özeti - placeholder: >- - Değişikliklerinizi kısaca açıklayın (yazım hatası düzeltildi, dilbilgisi düzeltildi, biçimlendirme geliştirildi) - btn_cancel: İptal - btn_submit: Gönder - btn_post: Yeni etiket gönder - tag_info: - created_at: Oluşturuldu - edited_at: Düzenlendi - history: Geçmiş - synonyms: - title: Eş Anlamlılar - text: Aşağıdaki etiketler şuna yeniden eşlenecek - empty: Eş anlamlı bulunamadı. - btn_add: Eş anlamlı ekle - btn_edit: Düzenle - btn_save: Kaydet - synonyms_text: Aşağıdaki etiketler şuna yeniden eşlenecek - delete: - title: Bu etiketi sil - tip_with_posts: >- -

        Gönderileri olan etiketin silinmesine izin vermiyoruz.

        Lütfen önce bu etiketi gönderilerden kaldırın.

        - tip_with_synonyms: >- -

        Eş anlamlıları olan etiketin silinmesine izin vermiyoruz.

        Lütfen önce bu etiketin eş anlamlılarını kaldırın.

        - tip: Silmek istediğinizden emin misiniz? - close: Kapat - merge: - title: Etiket birleştir - source_tag_title: Kaynak etiket - source_tag_description: Kaynak etiket ve ilişkili verileri hedef etikete yeniden eşlenecek. - target_tag_title: Hedef etiket - target_tag_description: Birleştirmeden sonra bu iki etiket arasında bir eş anlamlı ilişkisi oluşturulacak. - no_results: Eşleşen etiket bulunamadı - btn_submit: Gönder - btn_close: Kapat - edit_tag: - title: Etiketi Düzenle - default_reason: Etiketi düzenle - default_first_reason: Etiket ekle - btn_save_edits: Düzenlemeleri kaydet - btn_cancel: İptal - dates: - long_date: D MMM - long_date_with_year: "D MMM, YYYY" - long_date_with_time: "D MMM, YYYY [saat] HH:mm" - now: şimdi - x_seconds_ago: "{{count}} saniye önce" - x_minutes_ago: "{{count}} dakika önce" - x_hours_ago: "{{count}} saat önce" - hour: saat - day: gün - hours: saatler - days: günler - month: ay - months: aylar - year: yıl - reaction: - heart: kalp - smile: gülümseme - frown: üzgün - btn_label: tepki ekle veya kaldır - undo_emoji: '{{emoji}} tepkisini geri al' - react_emoji: '{{emoji}} ile tepki ver' - unreact_emoji: '{{emoji}} tepkisini kaldır' - comment: - btn_add_comment: Yorum ekle - reply_to: Yanıtla - btn_reply: Yanıtla - btn_edit: Düzenle - btn_delete: Sil - btn_flag: Bildir - btn_save_edits: Düzenlemeleri kaydet - btn_cancel: İptal - show_more: "{{count}} daha fazla yorum" - tip_question: >- - Daha fazla bilgi istemek veya iyileştirmeler önermek için yorumları kullanın. Yorumlarda soruları cevaplamaktan kaçının. - tip_answer: >- - Diğer kullanıcılara yanıt vermek veya onları değişikliklerden haberdar etmek için yorumları kullanın. Yeni bilgi ekliyorsanız, yorum yapmak yerine gönderinizi düzenleyin. - tip_vote: Gönderiye faydalı bir şey ekliyor - edit_answer: - title: Cevabı Düzenle - default_reason: Cevabı düzenle - default_first_reason: Cevap ekle - form: - fields: - revision: - label: Revizyon - answer: - label: Cevap - feedback: - characters: içerik en az 6 karakter uzunluğunda olmalıdır. - edit_summary: - label: Düzenleme özeti - placeholder: >- - Yaptığınız değişiklikleri kısaca açıklayın (düzeltilmiş yazım geliştirilmiş biçimlendirme) - btn_save_edits: Düzenlemeleri kaydet - btn_cancel: İptal - tags: - title: Etiketler - sort_buttons: - popular: Popüler - name: İsim - newest: En Yeni - button_follow: Takip Et - button_following: Takip Ediliyor - tag_label: sorular - search_placeholder: Etiket adına göre filtrele - no_desc: Bu etiketin açıklaması yok. - more: Daha Fazla - wiki: Wiki - ask: - title: Soru Oluştur - edit_title: Soruyu Düzenle - default_reason: Soruyu düzenle - default_first_reason: Soru oluştur - similar_questions: Benzer sorular - form: - fields: - revision: - label: Revizyon - title: - label: Başlık - placeholder: Konunuz nedir? Ayrıntılı belirtin. - msg: - empty: Başlık boş olamaz. - range: Başlık en fazla 150 karakter olabilir - body: - label: İçerik - msg: - empty: İçerik boş olamaz. - hint: - optional_body: Sorunun ne hakkında olduğunu açıklayın. - minimum_characters: "Sorunun ne hakkında olduğunu açıklayın, en az {{min_content_length}} karakter gereklidir." - tags: - label: Etiketler - msg: - empty: Etiketler boş olamaz. - answer: - label: Cevap - msg: - empty: Cevap boş olamaz. - edit_summary: - label: Düzenleme özeti - placeholder: >- - Değişikliklerinizi kısaca açıklayın (yazım hatası düzeltildi, dilbilgisi düzeltildi, biçimlendirme geliştirildi) - btn_post_question: Sorunuzu gönderin - btn_save_edits: Düzenlemeleri kaydet - answer_question: Kendi sorunuzu cevaplayın - post_question&answer: Sorunuzu ve cevabınızı gönderin - tag_selector: - add_btn: Etiket ekle - create_btn: Yeni etiket oluştur - search_tag: Etiket ara - hint: İçeriğinizin ne hakkında olduğunu açıklayın, en az bir etiket gereklidir. - hint_zero_tags: İçeriğinizin ne hakkında olduğunu açıklayın. - hint_more_than_one_tag: "İçeriğinizin ne hakkında olduğunu açıklayın, en az {{min_tags_number}} etiket gereklidir." - no_result: Eşleşen etiket bulunamadı - tag_required_text: Gerekli etiket (en az bir tane) - header: - nav: - question: Sorular - tag: Etiketler - user: Kullanıcılar - badges: Rozetler - profile: Profil - setting: Ayarlar - logout: Çıkış yap - admin: Yönetici - review: İnceleme - bookmark: Yer İşaretleri - moderation: Moderasyon - search: - placeholder: Ara - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Değiştir - loading: yükleniyor... - pic_auth_code: - title: Captcha - placeholder: Yukarıdaki metni yazın - msg: - empty: Captcha boş olamaz. - inactive: - first: >- - Neredeyse tamamlandı! {{mail}} adresine bir aktivasyon e-postası gönderdik. Hesabınızı etkinleştirmek için lütfen e-postadaki talimatları izleyin. - info: "E-posta gelmezse, spam klasörünüzü kontrol edin." - another: >- - {{mail}} adresine başka bir aktivasyon e-postası gönderdik. Gelmesi birkaç dakika sürebilir; spam klasörünüzü kontrol etmeyi unutmayın. - btn_name: Aktivasyon e-postasını yeniden gönder - change_btn_name: E-posta değiştir - msg: - empty: Boş olamaz. - resend_email: - url_label: Aktivasyon e-postasını yeniden göndermek istediğinizden emin misiniz? - url_text: Ayrıca yukarıdaki aktivasyon bağlantısını kullanıcıya verebilirsiniz. - login: - login_to_continue: Devam etmek için giriş yapın - info_sign: Hesabınız yok mu? <1>Kaydolun - info_login: Zaten hesabınız var mı? <1>Giriş yapın - agreements: Kaydolarak <1>gizlilik politikasını ve <3>hizmet şartlarını kabul etmiş olursunuz. - forgot_pass: Parolanızı mı unuttunuz? - name: - label: İsim - msg: - empty: İsim boş olamaz. - range: İsim 2 ile 30 karakter arasında olmalıdır. - character: 'Yalnızca "a-z", "0-9", " - . _" karakterleri kullanılabilir' - email: - label: E-posta - msg: - empty: E-posta boş olamaz. - password: - label: Parola - msg: - empty: Parola boş olamaz. - different: Her iki tarafta girilen parolalar tutarsız - account_forgot: - page_title: Parolanızı mı Unuttunuz - btn_name: Bana kurtarma e-postası gönder - send_success: >- - Eğer bir hesap {{mail}} ile eşleşirse, kısa süre içinde parolanızı nasıl sıfırlayacağınıza dair talimatlar içeren bir e-posta almalısınız. - email: - label: E-posta - msg: - empty: E-posta boş olamaz. - change_email: - btn_cancel: İptal - btn_update: E-posta adresini güncelle - send_success: >- - Eğer bir hesap {{mail}} ile eşleşirse, kısa süre içinde parolanızı nasıl sıfırlayacağınıza dair talimatlar içeren bir e-posta almalısınız. - email: - label: Yeni e-posta - msg: - empty: E-posta boş olamaz. - oauth: - connect: '{{auth_name}} ile bağlan' - remove: '{{auth_name}} kaldır' - oauth_bind_email: - subtitle: Hesabınıza bir kurtarma e-postası ekleyin. - btn_update: E-posta adresini güncelle - email: - label: E-posta - msg: - empty: E-posta boş olamaz. - modal_title: E-posta zaten mevcut. - modal_content: Bu e-posta adresi zaten kayıtlı. Mevcut hesaba bağlanmak istediğinizden emin misiniz? - modal_cancel: E-posta değiştir - modal_confirm: Mevcut hesaba bağlan - password_reset: - page_title: Parola Sıfırlama - btn_name: Parolamı sıfırla - reset_success: >- - Parolanızı başarıyla değiştirdiniz; giriş sayfasına yönlendirileceksiniz. - link_invalid: >- - Üzgünüz, bu parola sıfırlama bağlantısı artık geçerli değil. Belki de parolanız zaten sıfırlanmış? - to_login: Giriş sayfasına devam et - password: - label: Parola - msg: - empty: Parola boş olamaz. - length: Uzunluk 8 ile 32 arasında olmalıdır - different: Her iki tarafta girilen parolalar tutarsız - password_confirm: - label: Yeni parolayı onayla - settings: - page_title: Ayarlar - goto_modify: Değiştirmeye git - nav: - profile: Profil - notification: Bildirimler - account: Hesap - interface: Arayüz - profile: - heading: Profil - btn_name: Kaydet - display_name: - label: Görünen ad - msg: Görünen ad boş olamaz. - msg_range: Görünen ad 2-30 karakter uzunluğunda olmalıdır. - username: - label: Kullanıcı adı - caption: İnsanlar size "@kullaniciadi" şeklinde bahsedebilir. - msg: Kullanıcı adı boş olamaz. - msg_range: Kullanıcı adı 2-30 karakter uzunluğunda olmalıdır. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profil resmi - gravatar: Gravatar - gravatar_text: Resmi şurada değiştirebilirsiniz - custom: Özel - custom_text: Kendi resminizi yükleyebilirsiniz. - default: Sistem - msg: Lütfen bir avatar yükleyin - bio: - label: Hakkımda - website: - label: Website - placeholder: "https://example.com" - msg: Website formatı yanlış - location: - label: Konum - placeholder: "Şehir, Ülke" - notification: - heading: E-posta Bildirimleri - turn_on: Aç - inbox: - label: Gelen kutusu bildirimleri - description: Sorularınıza cevaplar, yorumlar, davetler ve daha fazlası. - all_new_question: - label: Tüm yeni sorular - description: Tüm yeni sorulardan haberdar olun. Haftada en fazla 50 soru. - all_new_question_for_following_tags: - label: Takip edilen etiketler için tüm yeni sorular - description: Takip ettiğiniz etiketlerdeki yeni sorulardan haberdar olun. - account: - heading: Hesap - change_email_btn: E-posta değiştir - change_pass_btn: Parola değiştir - change_email_info: >- - Bu adrese bir e-posta gönderdik. Lütfen onay talimatlarını takip edin. - email: - label: E-posta - new_email: - label: Yeni e-posta - msg: Yeni e-posta boş olamaz. - pass: - label: Mevcut parola - msg: Parola boş olamaz. - password_title: Parola - current_pass: - label: Mevcut parola - msg: - empty: Mevcut parola boş olamaz. - length: Uzunluk 8 ile 32 arasında olmalıdır. - different: Girilen iki parola eşleşmiyor. - new_pass: - label: Yeni parola - pass_confirm: - label: Yeni parolayı onayla - interface: - heading: Arayüz - lang: - label: Arayüz dili - text: Kullanıcı arayüzü dili. Sayfa yenilendiğinde değişecektir. - my_logins: - title: Girişlerim - label: Bu hesapları kullanarak bu sitede giriş yapın veya kaydolun. - modal_title: Girişi kaldır - modal_content: Bu girişi hesabınızdan kaldırmak istediğinizden emin misiniz? - modal_confirm_btn: Kaldır - remove_success: Başarıyla kaldırıldı - toast: - update: güncelleme başarılı - update_password: Parola başarıyla değiştirildi. - flag_success: Bildirdiğiniz için teşekkürler. - forbidden_operate_self: Kendinizle ilgili işlem yapmak yasaktır - review: Revizyonunuz incelendikten sonra görünecek. - sent_success: Başarıyla gönderildi - related_question: - title: İlgili - answers: cevap - linked_question: - title: Bağlantılı - description: Bağlantılı gönderiler - no_linked_question: Bu içerikten bağlantı verilen içerik yok. - invite_to_answer: - title: İnsanları Davet Et - desc: Cevap verebileceğini düşündüğünüz kişileri davet edin. - invite: Cevaplamaya davet et - add: Kişi ekle - search: Kişi ara - question_detail: - action: Eylem - created: Oluşturuldu - Asked: Soruldu - asked: sordu - update: Değiştirildi - Edited: Düzenlendi - edit: düzenledi - commented: yorum yaptı - Views: Görüntülendi - Follow: Takip Et - Following: Takip Ediliyor - follow_tip: Bildirim almak için bu soruyu takip edin - answered: cevapladı - closed_in: Burada kapatıldı - show_exist: Var olan soruyu göster. - useful: Faydalı - question_useful: Faydalı ve açık - question_un_useful: Belirsiz veya faydalı değil - question_bookmark: Bu soruyu yer işaretlerine ekle - answer_useful: Faydalı - answer_un_useful: Faydalı değil - answers: - title: Cevaplar - score: Puan - newest: En Yeni - oldest: En Eski - btn_accept: Kabul Et - btn_accepted: Kabul Edildi - write_answer: - title: Cevabınız - edit_answer: Mevcut cevabımı düzenle - btn_name: Cevabınızı gönderin - add_another_answer: Başka bir cevap ekle - confirm_title: Cevaplamaya devam et - continue: Devam et - confirm_info: >- -

        Başka bir cevap eklemek istediğinizden emin misiniz?

        Bunun yerine mevcut cevabınızı iyileştirmek ve geliştirmek için düzenleme bağlantısını kullanabilirsiniz.

        - empty: Cevap boş olamaz. - characters: içerik en az 6 karakter uzunluğunda olmalıdır. - tips: - header_1: Cevabınız için teşekkürler - li1_1: Lütfen soruyu cevapladığınızdan emin olun. Detaylar verin ve araştırmanızı paylaşın. - li1_2: Yaptığınız ifadeleri referanslar veya kişisel deneyimlerle destekleyin. - header_2: Ancak şunlardan kaçının ... - li2_1: Yardım istemek, açıklama istemek veya diğer cevaplara yanıt vermek. - reopen: - confirm_btn: Yeniden Aç - title: Bu gönderiyi yeniden aç - content: Yeniden açmak istediğinizden emin misiniz? - list: - confirm_btn: Listele - title: Bu gönderiyi listele - content: Listelemek istediğinizden emin misiniz? - unlist: - confirm_btn: Listeden Kaldır - title: Bu gönderiyi listeden kaldır - content: Listeden kaldırmak istediğinizden emin misiniz? - pin: - title: Bu gönderiyi sabitle - content: Küresel olarak sabitlemek istediğinizden emin misiniz? Bu gönderi tüm gönderi listelerinin en üstünde görünecektir. - confirm_btn: Sabitle - delete: - title: Bu gönderiyi sil - question: >- - Cevapları olan soruları silmenizi önermiyoruz çünkü bunu yapmak gelecekteki okuyucuları bu bilgiden mahrum bırakır.

        Cevaplanmış soruları tekrar tekrar silmek, hesabınızın soru sorma yeteneğinin engellenmesine neden olabilir. Silmek istediğinizden emin misiniz? - answer_accepted: >- -

        Kabul edilmiş cevabı silmenizi önermiyoruz çünkü bunu yapmak gelecekteki okuyucuları bu bilgiden mahrum bırakır.

        Kabul edilmiş cevapları tekrar tekrar silmek, hesabınızın cevap verme yeteneğinin engellenmesine neden olabilir. Silmek istediğinizden emin misiniz? - other: Silmek istediğinizden emin misiniz? - tip_answer_deleted: Bu cevap silinmiştir - undelete_title: Bu gönderinin silmesini geri al - undelete_desc: Silmeyi geri almak istediğinizden emin misiniz? - btns: - confirm: Onayla - cancel: İptal - edit: Düzenle - save: Kaydet - delete: Sil - undelete: Silmeyi Geri Al - list: Listele - unlist: Listeden Kaldır - unlisted: Listede Değil - login: Giriş Yap - signup: Kayıt Ol - logout: Çıkış Yap - verify: Doğrula - create: Oluştur - approve: Onayla - reject: Reddet - skip: Atla - discard_draft: Taslağı at - pinned: Sabitlendi - all: Tümü - question: Soru - answer: Cevap - comment: Yorum - refresh: Yenile - resend: Yeniden Gönder - deactivate: Devre Dışı Bırak - active: Aktif - suspend: Askıya Al - unsuspend: Askıyı Kaldır - close: Kapat - reopen: Yeniden Aç - ok: Tamam - light: Açık - dark: Koyu - system_setting: Sistem ayarı - default: Varsayılan - reset: Sıfırla - tag: Etiket - post_lowercase: gönderi - filter: Filtrele - ignore: Yoksay - submit: Gönder - normal: Normal - closed: Kapalı - deleted: Silindi - deleted_permanently: Kalıcı olarak silindi - pending: Beklemede - more: Daha Fazla - view: Görüntüle - card: Kart - compact: Kompakt - display_below: Aşağıda göster - always_display: Her zaman göster - or: veya - back_sites: Sitelere geri dön - search: - title: Arama Sonuçları - keywords: Anahtar Kelimeler - options: Seçenekler - follow: Takip Et - following: Takip Ediliyor - counts: "{{count}} Sonuç" - counts_loading: "... Results" - more: Daha Fazla - sort_btns: - relevance: İlgililik - newest: En Yeni - active: Aktif - score: Puan - more: Daha Fazla - tips: - title: Gelişmiş Arama İpuçları - tag: "<1>[etiket] bir etiketle ara" - user: "<1>user:kullanıcıadı yazara göre ara" - answer: "<1>answers:0 cevaplanmamış sorular" - score: "<1>score:3 3+ puana sahip gönderiler" - question: "<1>is:question soruları ara" - is_answer: "<1>is:answer cevapları ara" - empty: Hiçbir şey bulamadık.
        Farklı veya daha az spesifik anahtar kelimeler deneyin. - share: - name: Paylaş - copy: Bağlantıyı kopyala - via: Gönderiyi şurada paylaş... - copied: Kopyalandı - facebook: Facebook'ta Paylaş - twitter: X'te Paylaş - cannot_vote_for_self: Kendi gönderinize oy veremezsiniz. - modal_confirm: - title: Hata... - delete_permanently: - title: Kalıcı olarak sil - content: Kalıcı olarak silmek istediğinizden emin misiniz? - account_result: - success: Yeni hesabınız onaylandı; ana sayfaya yönlendirileceksiniz. - link: Ana sayfaya devam et - oops: Hay aksi! - invalid: Kullandığınız bağlantı artık çalışmıyor. - confirm_new_email: E-postanız güncellendi. - confirm_new_email_invalid: >- - Üzgünüz, bu onay bağlantısı artık geçerli değil. Belki e-postanız zaten değiştirildi? - unsubscribe: - page_title: Abonelikten Çık - success_title: Abonelikten Çıkma Başarılı - success_desc: Bu abone listesinden başarıyla çıkarıldınız ve bizden başka e-posta almayacaksınız. - link: Ayarları değiştir - question: - following_tags: Takip Edilen Etiketler - edit: Düzenle - save: Kaydet - follow_tag_tip: Soru listenizi oluşturmak için etiketleri takip edin. - hot_questions: Popüler Sorular - all_questions: Tüm Sorular - x_questions: "{{ count }} Soru" - x_answers: "{{ count }} cevap" - x_posts: "{{ count }} Posts" - questions: Sorular - answers: Cevaplar - newest: En Yeni - active: Aktif - hot: Popüler - frequent: Sık Sorulan - recommend: Önerilenler - score: Puan - unanswered: Cevaplanmamış - modified: değiştirildi - answered: cevaplandı - asked: soruldu - closed: kapandı - follow_a_tag: Bir etiketi takip et - more: Daha Fazla - personal: - overview: Genel Bakış - answers: Cevaplar - answer: cevap - questions: Sorular - question: soru - bookmarks: Yer İşaretleri - reputation: İtibar - comments: Yorumlar - votes: Oylar - badges: Rozetler - newest: En Yeni - score: Puan - edit_profile: Profili düzenle - visited_x_days: "{{ count }} gün ziyaret edildi" - viewed: Görüntülendi - joined: Katıldı - comma: "," - last_login: Görüldü - about_me: Hakkımda - about_me_empty: "// Merhaba, Dünya !" - top_answers: En İyi Cevaplar - top_questions: En İyi Sorular - stats: İstatistikler - list_empty: Gönderi bulunamadı.
        Belki farklı bir sekme seçmek istersiniz? - content_empty: Gönderi bulunamadı. - accepted: Kabul Edildi - answered: cevaplandı - asked: sordu - downvoted: negatif oylandı - mod_short: MOD - mod_long: Moderatörler - x_reputation: itibar - x_votes: alınan oy - x_answers: cevap - x_questions: soru - recent_badges: Son Rozetler - install: - title: Kurulum - next: İleri - done: Tamamlandı - config_yaml_error: config.yaml dosyası oluşturulamıyor. - lang: - label: Lütfen bir dil seçin - db_type: - label: Veritabanı motoru - db_username: - label: Kullanıcı adı - placeholder: root - msg: Kullanıcı adı boş olamaz. - db_password: - label: Parola - placeholder: root - msg: Parola boş olamaz. - db_host: - label: Veritabanı sunucusu - placeholder: "db:3306" - msg: Veritabanı sunucusu boş olamaz. - db_name: - label: Veritabanı adı - placeholder: answer - msg: Veritabanı adı boş olamaz. - db_file: - label: Veritabanı dosyası - placeholder: /data/answer.db - msg: Veritabanı dosyası boş olamaz. - ssl_enabled: - label: SSL'i Etkinleştir - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Modu - ssl_root_cert: - placeholder: sslrootcert dosya yolu - msg: sslrootcert dosya yolu boş olamaz - ssl_cert: - placeholder: sslcert dosya yolu - msg: sslcert dosya yolu boş olamaz - ssl_key: - placeholder: sslkey dosya yolu - msg: sslkey dosya yolu boş olamaz - config_yaml: - title: config.yaml Oluştur - label: config.yaml dosyası oluşturuldu. - desc: >- - <1>config.yaml dosyasını <1>/var/wwww/xxx/ dizininde manuel olarak oluşturabilir ve aşağıdaki metni içine yapıştırabilirsiniz. - info: Bunu yaptıktan sonra "İleri" düğmesine tıklayın. - site_information: Site Bilgisi - admin_account: Yönetici Hesabı - site_name: - label: Site adı - msg: Saat dilimi boş olamaz. - msg_max_length: Site adı en fazla 30 karakter uzunluğunda olmalıdır. - site_url: - label: Site URL'si - text: Sitenizin adresi. - msg: - empty: Site URL'si boş olamaz. - incorrect: Site URL'si formatı yanlış. - max_length: Site URL'si en fazla 512 karakter uzunluğunda olmalıdır. - contact_email: - label: İletişim e-postası - text: Bu siteden sorumlu kilit kişinin e-posta adresi. - msg: - empty: İletişim e-postası boş olamaz. - incorrect: İletişim e-postası formatı yanlış. - login_required: - label: Özel - switch: Giriş gerekli - text: Bu topluluğa sadece giriş yapmış kullanıcılar erişebilir. - admin_name: - label: İsim - msg: İsim boş olamaz. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: İsim 2 ile 30 karakter arasında olmalıdır. - admin_password: - label: Parola - text: >- - Giriş yapmak için bu parolaya ihtiyacınız olacak. Lütfen güvenli bir yerde saklayın. - msg: Parola boş olamaz. - msg_min_length: Parola en az 8 karakter uzunluğunda olmalıdır. - msg_max_length: Parola en fazla 32 karakter uzunluğunda olmalıdır. - admin_confirm_password: - label: "Parolayı Onayla" - text: "Lütfen onaylamak için parolanızı tekrar girin." - msg: "Onay parolası eşleşmiyor." - admin_email: - label: E-posta - text: Giriş yapmak için bu e-postaya ihtiyacınız olacak. - msg: - empty: E-posta boş olamaz. - incorrect: E-posta formatı yanlış. - ready_title: Siteniz hazır - ready_desc: >- - Daha fazla ayarı değiştirmek isterseniz, <1>yönetici bölümünü ziyaret edin; site menüsünde bulabilirsiniz. - good_luck: "İyi eğlenceler ve iyi şanslar!" - warn_title: Uyarı - warn_desc: >- - <1>config.yaml dosyası zaten var. Bu dosyadaki herhangi bir yapılandırma öğesini sıfırlamanız gerekiyorsa, lütfen önce dosyayı silin. - install_now: <1>Şimdi kurulum yapmayı deneyebilirsiniz. - installed: Zaten kurulu - installed_desc: >- - Zaten kurulum yapmış görünüyorsunuz. Yeniden kurmak için lütfen önce eski veritabanı tablolarınızı temizleyin. - db_failed: Veritabanı bağlantısı başarısız - db_failed_desc: >- - Bu, <1>config.yaml dosyanızdaki veritabanı bilgilerinin yanlış olduğu veya veritabanı sunucusuyla bağlantı kurulamadığı anlamına gelir. Bu, sunucunuzun veritabanı sunucusunun çalışmadığı anlamına gelebilir. - counts: - views: görüntülenme - votes: oy - answers: cevap - accepted: Kabul Edildi - page_error: - http_error: HTTP Hatası {{ code }} - desc_403: Bu sayfaya erişim izniniz yok. - desc_404: Maalesef, bu sayfa mevcut değil. - desc_50X: Sunucu bir hatayla karşılaştı ve isteğinizi tamamlayamadı. - back_home: Ana sayfaya dön - page_maintenance: - desc: "Bakım altındayız, yakında geri döneceğiz." - nav_menus: - dashboard: Gösterge Paneli - contents: İçerikler - questions: Sorular - answers: Cevaplar - users: Kullanıcılar - badges: Rozetler - flags: Bildirimler - settings: Ayarlar - general: Genel - interface: Arayüz - smtp: SMTP - branding: Marka - legal: Yasal - write: Yaz - terms: Terms - tos: Kullanım Şartları - privacy: Gizlilik - seo: SEO - customize: Özelleştir - themes: Temalar - login: Giriş - privileges: Ayrıcalıklar - plugins: Eklentiler - installed_plugins: Kurulu Eklentiler - apperance: Görünüm - website_welcome: '{{site_name}} sitesine hoş geldiniz' - user_center: - login: Giriş - qrcode_login_tip: Lütfen QR kodu taramak ve giriş yapmak için {{ agentName }} kullanın. - login_failed_email_tip: Giriş başarısız oldu, lütfen tekrar denemeden önce bu uygulamanın e-posta bilgilerinize erişmesine izin verin. - badges: - modal: - title: Tebrikler - content: Yeni bir rozet kazandınız. - close: Kapat - confirm: Rozetleri görüntüle - title: Rozetler - awarded: Kazanıldı - earned_×: '{{ number }} kez kazanıldı' - ×_awarded: "{{ number }} kez verildi" - can_earn_multiple: Bunu birden çok kez kazanabilirsiniz. - earned: Kazanıldı - admin: - admin_header: - title: Yönetici - dashboard: - title: Gösterge Paneli - welcome: Yönetici'ye Hoş Geldiniz! - site_statistics: Site istatistikleri - questions: "Sorular:" - resolved: "Çözülmüş:" - unanswered: "Cevaplanmamış:" - answers: "Cevaplar:" - comments: "Yorumlar:" - votes: "Oylar:" - users: "Kullanıcılar:" - flags: "Bildirimler:" - reviews: "İncelemeler:" - site_health: Site sağlığı - version: "Sürüm:" - https: "HTTPS:" - upload_folder: "Yükleme klasörü:" - run_mode: "Çalışma modu:" - private: Özel - public: Herkese Açık - smtp: "SMTP:" - timezone: "Saat dilimi:" - system_info: Sistem bilgisi - go_version: "Go sürümü:" - database: "Veritabanı:" - database_size: "Veritabanı boyutu:" - storage_used: "Kullanılan depolama:" - uptime: "Çalışma süresi:" - links: Bağlantılar - plugins: Eklentiler - github: GitHub - blog: Blog - contact: İletişim - forum: Forum - documents: Belgeler - feedback: Geribildirim - support: Destek - review: İnceleme - config: Yapılandırma - update_to: Güncelle - latest: En son - check_failed: Kontrol başarısız - "yes": "Evet" - "no": "Hayır" - not_allowed: İzin verilmiyor - allowed: İzin veriliyor - enabled: Etkin - disabled: Devre dışı - writable: Yazılabilir - not_writable: Yazılamaz - flags: - title: Bildirimler - pending: Bekleyen - completed: Tamamlanan - flagged: Bildirilen - flagged_type: Bildirilen {{ type }} - created: Oluşturuldu - action: Eylem - review: İnceleme - user_role_modal: - title: Kullanıcı rolünü şuna değiştir... - btn_cancel: İptal - btn_submit: Gönder - new_password_modal: - title: Yeni parola belirle - form: - fields: - password: - label: Parola - text: Kullanıcının oturumu kapatılacak ve tekrar giriş yapması gerekecek. - msg: Parola 8-32 karakter uzunluğunda olmalıdır. - btn_cancel: İptal - btn_submit: Gönder - edit_profile_modal: - title: Profili düzenle - form: - fields: - display_name: - label: Görünen ad - msg_range: Görünen ad 2-30 karakter uzunluğunda olmalıdır. - username: - label: Kullanıcı adı - msg_range: Kullanıcı adı 2-30 karakter uzunluğunda olmalıdır. - email: - label: E-posta - msg_invalid: Geçersiz E-posta Adresi. - edit_success: Başarıyla düzenlendi - btn_cancel: İptal - btn_submit: Gönder - user_modal: - title: Yeni kullanıcı ekle - form: - fields: - users: - label: Toplu kullanıcı ekle - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: İsim, e-posta, parola bilgilerini virgülle ayırın. Her satırda bir kullanıcı. - msg: "Lütfen kullanıcının e-postasını girin, her satırda bir tane." - display_name: - label: Görünen ad - msg: Görünen ad 2-30 karakter uzunluğunda olmalıdır. - email: - label: E-posta - msg: E-posta geçerli değil. - password: - label: Parola - msg: Parola 8-32 karakter uzunluğunda olmalıdır. - btn_cancel: İptal - btn_submit: Gönder - users: - title: Kullanıcılar - name: İsim - email: E-posta - reputation: İtibar - created_at: Oluşturulma zamanı - delete_at: Silinme zamanı - suspend_at: Askıya Alınma Zamanı - suspend_until: Suspend until - status: Durum - role: Rol - action: Eylem - change: Değiştir - all: Tümü - staff: Ekip - more: Daha Fazla - inactive: Etkin Değil - suspended: Askıya Alınmış - deleted: Silinmiş - normal: Normal - Moderator: Moderatör - Admin: Yönetici - User: Kullanıcı - filter: - placeholder: "İsme göre filtreleme, user:id" - set_new_password: Yeni parola belirle - edit_profile: Profili düzenle - change_status: Durumu değiştir - change_role: Rolü değiştir - show_logs: Kayıtları göster - add_user: Kullanıcı ekle - deactivate_user: - title: Kullanıcıyı devre dışı bırak - content: Etkin olmayan bir kullanıcının e-postasını yeniden doğrulaması gerekir. - delete_user: - title: Bu kullanıcıyı sil - content: Bu kullanıcıyı silmek istediğinizden emin misiniz? Bu kalıcıdır! - remove: İçeriklerini kaldır - label: Tüm soruları, cevapları, yorumları vb. kaldır. - text: Sadece kullanıcının hesabını silmek istiyorsanız bunu işaretlemeyin. - suspend_user: - title: Bu kullanıcıyı askıya al - content: Askıya alınmış bir kullanıcı giriş yapamaz. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Sorular - unlisted: Listelenmemiş - post: Gönderi - votes: Oylar - answers: Cevaplar - created: Oluşturuldu - status: Durum - action: Eylem - change: Değiştir - pending: Beklemede - filter: - placeholder: "Başlığa göre filtreleme, question:id" - answers: - page_title: Cevaplar - post: Gönderi - votes: Oylar - created: Oluşturuldu - status: Durum - action: Eylem - change: Değiştir - filter: - placeholder: "Başlığa göre filtreleme, answer:id" - general: - page_title: Genel - name: - label: Site adı - msg: Site adı boş olamaz. - text: "Başlık etiketinde kullanılan bu sitenin adı." - site_url: - label: Site URL'si - msg: Site url'si boş olamaz. - validate: Lütfen geçerli bir URL girin. - text: Sitenizin adresi. - short_desc: - label: Kısa site açıklaması - msg: Kısa site açıklaması boş olamaz. - text: "Ana sayfadaki başlık etiketinde kullanılan kısa açıklama." - desc: - label: Site açıklaması - msg: Site açıklaması boş olamaz. - text: "Bu siteyi bir cümleyle açıklayın, meta açıklama etiketinde kullanılır." - contact_email: - label: İletişim e-postası - msg: İletişim e-postası boş olamaz. - validate: İletişim e-postası geçerli değil. - text: Bu siteden sorumlu kilit kişinin e-posta adresi. - check_update: - label: Yazılım güncellemeleri - text: Güncellemeleri otomatik olarak kontrol et - interface: - page_title: Arayüz - language: - label: Arayüz dili - msg: Arayüz dili boş olamaz. - text: Kullanıcı arayüzü dili. Sayfa yenilendiğinde değişecektir. - time_zone: - label: Saat dilimi - msg: Saat dilimi boş olamaz. - text: Sizinle aynı saat dilimindeki bir şehri seçin. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: Gönderen e-posta - msg: Gönderen e-posta boş olamaz. - text: E-postaların gönderildiği e-posta adresi. - from_name: - label: Gönderen adı - msg: Gönderen adı boş olamaz. - text: E-postaların gönderildiği isim. - smtp_host: - label: SMTP sunucusu - msg: SMTP sunucusu boş olamaz. - text: Mail sunucunuz. - encryption: - label: Şifreleme - msg: Şifreleme boş olamaz. - text: Çoğu sunucu için SSL önerilen seçenektir. - ssl: SSL - tls: TLS - none: Yok - smtp_port: - label: SMTP portu - msg: SMTP portu 1 ~ 65535 arasında bir sayı olmalıdır. - text: Mail sunucunuzun portu. - smtp_username: - label: SMTP kullanıcı adı - msg: SMTP kullanıcı adı boş olamaz. - smtp_password: - label: SMTP parolası - msg: SMTP parolası boş olamaz. - test_email_recipient: - label: Test e-posta alıcıları - text: Test gönderimlerini alacak e-posta adresini girin. - msg: Test e-posta alıcıları geçersiz - smtp_authentication: - label: Kimlik doğrulamayı etkinleştir - title: SMTP kimlik doğrulaması - msg: SMTP kimlik doğrulaması boş olamaz. - "yes": "Evet" - "no": "Hayır" - branding: - page_title: Marka - logo: - label: Logo - msg: Logo boş olamaz. - text: Sitenizin sol üst köşesindeki logo resmi. 56 yüksekliğinde ve 3:1'den büyük en-boy oranlı geniş dikdörtgen bir resim kullanın. Boş bırakılırsa, site başlık metni gösterilecektir. - mobile_logo: - label: Mobil logo - text: Sitenizin mobil versiyonunda kullanılan logo. 56 yüksekliğinde geniş dikdörtgen bir resim kullanın. Boş bırakılırsa, "logo" ayarındaki resim kullanılacaktır. - square_icon: - label: Kare simge - msg: Kare simge boş olamaz. - text: Meta veri simgeleri için temel olarak kullanılan resim. İdeal olarak 512x512'den büyük olmalıdır. - favicon: - label: Favicon - text: Siteniz için bir favicon. CDN üzerinde düzgün çalışması için png olmalıdır. 32x32 boyutuna yeniden boyutlandırılacaktır. Boş bırakılırsa, "kare simge" kullanılacaktır. - legal: - page_title: Yasal - terms_of_service: - label: Kullanım şartları - text: "Buraya kullanım şartları içeriği ekleyebilirsiniz. Başka bir yerde barındırılan bir belgeniz varsa, tam URL'yi buraya girin." - privacy_policy: - label: Gizlilik politikası - text: "Buraya gizlilik politikası içeriği ekleyebilirsiniz. Başka bir yerde barındırılan bir belgeniz varsa, tam URL'yi buraya girin." - external_content_display: - label: Harici içerik - text: "İçerik, harici web sitelerinden gömülen resimler, videolar ve medyayı içerir." - always_display: Her zaman harici içeriği göster - ask_before_display: Harici içeriği göstermeden önce sor - write: - page_title: Yazma - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Cevap yazma - label: Her kullanıcı aynı soru için sadece bir cevap yazabilir - text: "Kullanıcıların aynı soruya birden fazla cevap yazmasına izin vermek için kapatın, bu cevapların odaktan uzaklaşmasına neden olabilir." - min_tags: - label: "Soru başına minimum etiket" - text: "Bir soruda bulunması gereken minimum etiket sayısı." - recommend_tags: - label: Önerilen etiketler - text: "Önerilen etiketler varsayılan olarak açılır listede gösterilecektir." - msg: - contain_reserved: "önerilen etiketler ayrılmış etiketleri içeremez" - required_tag: - title: Gerekli etiketleri ayarla - label: Önerilen etiketleri gerekli etiketler olarak ayarla - text: "Her yeni soru en az bir önerilen etikete sahip olmalıdır." - reserved_tags: - label: Ayrılmış etiketler - text: "Ayrılmış etiketler sadece moderatör tarafından kullanılabilir." - image_size: - label: Maksimum resim boyutu (MB) - text: "Maksimum resim yükleme boyutu." - attachment_size: - label: Maksimum ek dosya boyutu (MB) - text: "Maksimum ek dosya yükleme boyutu." - image_megapixels: - label: Maksimum resim megapikseli - text: "Bir resim için izin verilen maksimum megapiksel sayısı." - image_extensions: - label: İzin verilen resim uzantıları - text: "Resim gösterimi için izin verilen dosya uzantılarının listesi, virgülle ayırın." - attachment_extensions: - label: İzin verilen ek dosya uzantıları - text: "Yükleme için izin verilen dosya uzantılarının listesi, virgülle ayırın. UYARI: Yüklemelere izin vermek güvenlik sorunlarına neden olabilir." - seo: - page_title: SEO - permalink: - label: Kalıcı bağlantı - text: Özel URL yapıları, bağlantılarınızın kullanılabilirliğini ve ileriye dönük uyumluluğunu iyileştirebilir. - robots: - label: robots.txt - text: Bu, ilgili tüm site ayarlarını kalıcı olarak geçersiz kılacaktır. - themes: - page_title: Temalar - themes: - label: Temalar - text: Mevcut bir tema seçin. - color_scheme: - label: Renk şeması - navbar_style: - label: Gezinme çubuğu arka plan stili - primary_color: - label: Ana renk - text: Temalarınızda kullanılan renkleri değiştirin - css_and_html: - page_title: CSS ve HTML - custom_css: - label: Özel CSS - text: > - Bu <link> olarak eklenecektir - head: - label: Head - text: > - Bu </head> öncesine eklenecektir - header: - label: Header - text: > - Bu <body> sonrasına eklenecektir - footer: - label: Footer - text: Bu </body> öncesine eklenecektir - sidebar: - label: Kenar çubuğu - text: Bu kenar çubuğuna eklenecektir. - login: - page_title: Giriş - membership: - title: Üyelik - label: Yeni kayıtlara izin ver - text: Herhangi birinin yeni hesap oluşturmasını engellemek için kapatın. - email_registration: - title: E-posta kaydı - label: E-posta kaydına izin ver - text: Herhangi birinin e-posta yoluyla yeni hesap oluşturmasını engellemek için kapatın. - allowed_email_domains: - title: İzin verilen e-posta alan adları - text: Kullanıcıların hesap kaydı yapması gereken e-posta alan adları. Her satırda bir alan adı. Boş olduğunda dikkate alınmaz. - private: - title: Özel - label: Giriş gerekli - text: Bu topluluğa sadece giriş yapmış kullanıcılar erişebilir. - password_login: - title: Parola ile giriş - label: E-posta ve parola ile girişe izin ver - text: "UYARI: Kapatırsanız, daha önce başka bir giriş yöntemi yapılandırmadıysanız giriş yapamayabilirsiniz." - installed_plugins: - title: Kurulu Eklentiler - plugin_link: Eklentiler işlevselliği genişletir ve artırır. Eklentileri <1>Eklenti Deposu'nda bulabilirsiniz. - filter: - all: Tümü - active: Aktif - inactive: Pasif - outdated: Güncel değil - plugins: - label: Eklentiler - text: Mevcut bir eklenti seçin. - name: İsim - version: Sürüm - status: Durum - action: Eylem - deactivate: Devre dışı bırak - activate: Etkinleştir - settings: Ayarlar - settings_users: - title: Kullanıcılar - avatar: - label: Varsayılan avatar - text: Kendi özel avatarı olmayan kullanıcılar için. - gravatar_base_url: - label: Gravatar temel URL'si - text: Gravatar sağlayıcısının API temel URL'si. Boş olduğunda dikkate alınmaz. - profile_editable: - title: Profil düzenlenebilir - allow_update_display_name: - label: Kullanıcıların görünen adlarını değiştirmelerine izin ver - allow_update_username: - label: Kullanıcıların kullanıcı adlarını değiştirmelerine izin ver - allow_update_avatar: - label: Kullanıcıların profil resimlerini değiştirmelerine izin ver - allow_update_bio: - label: Kullanıcıların hakkında bilgilerini değiştirmelerine izin ver - allow_update_website: - label: Kullanıcıların web sitelerini değiştirmelerine izin ver - allow_update_location: - label: Kullanıcıların konumlarını değiştirmelerine izin ver - privilege: - title: Ayrıcalıklar - level: - label: Gereken itibar seviyesi - text: Ayrıcalıklar için gereken itibarı seçin - msg: - should_be_number: giriş bir sayı olmalıdır - number_larger_1: sayı 1'e eşit veya daha büyük olmalıdır - badges: - action: Eylem - active: Aktif - activate: Etkinleştir - all: Tümü - awards: Ödüller - deactivate: Devre dışı bırak - filter: - placeholder: İsme göre filtreleme, badge:id - group: Grup - inactive: Pasif - name: İsim - show_logs: Kayıtları göster - status: Durum - title: Rozetler - form: - optional: (isteğe bağlı) - empty: boş olamaz - invalid: geçersiz - btn_submit: Kaydet - not_found_props: "Gerekli {{ key }} özelliği bulunamadı." - select: Seç - page_review: - review: İnceleme - proposed: önerilen - question_edit: Soru düzenleme - answer_edit: Cevap düzenleme - tag_edit: Etiket düzenleme - edit_summary: Düzenleme özeti - edit_question: Soruyu düzenle - edit_answer: Cevabı düzenle - edit_tag: Etiketi düzenle - empty: İncelenecek görev kalmadı. - approve_revision_tip: Bu revizyonu onaylıyor musunuz? - approve_flag_tip: Bu bildirimi onaylıyor musunuz? - approve_post_tip: Bu gönderiyi onaylıyor musunuz? - approve_user_tip: Bu kullanıcıyı onaylıyor musunuz? - suggest_edits: Önerilen düzenlemeler - flag_post: Gönderiyi bildir - flag_user: Kullanıcıyı bildir - queued_post: Sıradaki gönderi - queued_user: Sıradaki kullanıcı - filter_label: Tür - reputation: itibar - flag_post_type: Bu gönderiyi {{ type }} olarak bildirdi. - flag_user_type: Bu kullanıcıyı {{ type }} olarak bildirdi. - edit_post: Gönderiyi düzenle - list_post: Gönderiyi listele - unlist_post: Gönderiyi listeden kaldır - timeline: - undeleted: silme geri alındı - deleted: silindi - downvote: negatif oy - upvote: pozitif oy - accept: kabul et - cancelled: iptal edildi - commented: yorum yapıldı - rollback: geri alındı - edited: düzenlendi - answered: cevaplandı - asked: soruldu - closed: kapatıldı - reopened: yeniden açıldı - created: oluşturuldu - pin: sabitlendi - unpin: sabitlenme kaldırıldı - show: listelendi - hide: listelenmedi - title: "Geçmiş:" - tag_title: "Zaman çizelgesi:" - show_votes: "Oyları göster" - n_or_a: Yok - title_for_question: "Zaman çizelgesi:" - title_for_answer: "{{ author }} tarafından {{ title }} sorusuna verilen cevabın zaman çizelgesi" - title_for_tag: "Etiket için zaman çizelgesi" - datetime: Tarih/Saat - type: Tür - by: Yapan - comment: Yorum - no_data: "Hiçbir şey bulamadık." - users: - title: Kullanıcılar - users_with_the_most_reputation: Bu hafta en yüksek itibar puanına sahip kullanıcılar - users_with_the_most_vote: Bu hafta en çok oy veren kullanıcılar - staffs: Topluluk ekibimiz - reputation: itibar - votes: oy - prompt: - leave_page: Sayfadan ayrılmak istediğinizden emin misiniz? - changes_not_save: Değişiklikleriniz kaydedilmeyebilir. - draft: - discard_confirm: Taslağınızı atmak istediğinizden emin misiniz? - messages: - post_deleted: Bu gönderi silindi. - post_cancel_deleted: Bu gönderinin silme işlemi geri alındı. - post_pin: Bu gönderi sabitlendi. - post_unpin: Bu gönderinin sabitlenmesi kaldırıldı. - post_hide_list: Bu gönderi listede gizlendi. - post_show_list: Bu gönderi listede gösterildi. - post_reopen: Bu gönderi yeniden açıldı. - post_list: Bu gönderi listelendi. - post_unlist: Bu gönderi listeden kaldırıldı. - post_pending: Gönderiniz inceleme bekliyor. Bu bir önizlemedir, onaylandıktan sonra görünür olacaktır. - post_closed: Bu gönderi kapatıldı. - answer_deleted: Bu cevap silindi. - answer_cancel_deleted: Bu cevabın silme işlemi geri alındı. - change_user_role: Bu kullanıcının rolü değiştirildi. - user_inactive: Bu kullanıcı zaten etkin değil. - user_normal: Bu kullanıcı zaten normal durumda. - user_suspended: Bu kullanıcı askıya alındı. - user_deleted: Bu kullanıcı silindi. - badge_activated: Bu rozet etkinleştirildi. - badge_inactivated: Bu rozet devre dışı bırakıldı. - users_deleted: Bu kullanıcılar silindi. - posts_deleted: Bu sorular silindi. - answers_deleted: Bu cevaplar silindi. - copy: Panoya kopyala - copied: Kopyalandı - external_content_warning: Harici resimler/medya gösterilmiyor. - - diff --git a/data/i18n/uk_UA.yaml b/data/i18n/uk_UA.yaml deleted file mode 100644 index a9f6aa32a..000000000 --- a/data/i18n/uk_UA.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Успішно. - unknown: - other: Невідома помилка. - request_format_error: - other: Неприпустимий формат запиту. - unauthorized_error: - other: Не авторизовано. - database_error: - other: Помилка сервера даних. - forbidden_error: - other: Заборонено. - duplicate_request_error: - other: Повторний запит. - action: - report: - other: Відмітити - edit: - other: Редагувати - delete: - other: Видалити - close: - other: Закрити - reopen: - other: Відкрити знову - forbidden_error: - other: Заборонено. - pin: - other: Закріпити - hide: - other: Вилучити зі списку - unpin: - other: Відкріпити - show: - other: Список - invite_someone_to_answer: - other: Редагувати - undelete: - other: Скасувати видалення - merge: - other: Merge - role: - name: - user: - other: Користувач - admin: - other: Адмін - moderator: - other: Модератор - description: - user: - other: За замовчуванням без спеціального доступу. - admin: - other: Має повний доступ до сайту. - moderator: - other: Має доступ до всіх дописів, окрім налаштувань адміністратора. - privilege: - level_1: - description: - other: Рівень 1 (для приватної команди, групи потрібна менша репутація) - level_2: - description: - other: Рівень 2 (низька репутація, необхідна для стартап-спільноти) - level_3: - description: - other: Рівень 3 (висока репутація, необхідна для зрілої спільноти) - level_custom: - description: - other: Користувацький рівень - rank_question_add_label: - other: Задати питання - rank_answer_add_label: - other: Написати відповідь - rank_comment_add_label: - other: Написати коментар - rank_report_add_label: - other: Відмітити - rank_comment_vote_up_label: - other: Проголосувати за коментар - rank_link_url_limit_label: - other: Публікуйте більш ніж 2 посилання одночасно - rank_question_vote_up_label: - other: Проголосувати за питання - rank_answer_vote_up_label: - other: Проголосувати за відповідь - rank_question_vote_down_label: - other: Проголосувати проти питання - rank_answer_vote_down_label: - other: Проголосувати проти відповіді - rank_invite_someone_to_answer_label: - other: Запросити когось відповісти - rank_tag_add_label: - other: Створити новий теґ - rank_tag_edit_label: - other: Редагувати опис теґу (необхідно розглянути) - rank_question_edit_label: - other: Редагувати чуже питання (необхідно розглянути) - rank_answer_edit_label: - other: Редагувати чужу відповідь (необхідно розглянути) - rank_question_edit_without_review_label: - other: Редагувати чуже питання без розгляду - rank_answer_edit_without_review_label: - other: Редагувати чужу відповідь без розгляду - rank_question_audit_label: - other: Переглянути редагування питання - rank_answer_audit_label: - other: Переглянути редагування відповіді - rank_tag_audit_label: - other: Переглянути редагування теґу - rank_tag_edit_without_review_label: - other: Редагувати опис теґу без розгляду - rank_tag_synonym_label: - other: Керування синонімами тегів - email: - other: Електронна пошта - e_mail: - other: Електронна пошта - password: - other: Пароль - pass: - other: Пароль - old_pass: - other: Current password - original_text: - other: Цей допис - email_or_password_wrong_error: - other: Електронна пошта та пароль не збігаються. - error: - common: - invalid_url: - other: Невірна URL. - status_invalid: - other: Неприпустимий статус. - password: - space_invalid: - other: Пароль не може містити пробіли. - admin: - cannot_update_their_password: - other: Ви не можете змінити свій пароль. - cannot_edit_their_profile: - other: Ви не можете змінити свій профіль. - cannot_modify_self_status: - other: Ви не можете змінити свій статус. - email_or_password_wrong: - other: Електронна пошта та пароль не збігаються. - answer: - not_found: - other: Відповідь не знайдено. - cannot_deleted: - other: Немає дозволу на видалення. - cannot_update: - other: Немає дозволу на оновлення. - question_closed_cannot_add: - other: Питання закриті й не можуть бути додані. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Коментарі не можна редагувати. - not_found: - other: Коментар не знайдено. - cannot_edit_after_deadline: - other: Час коментаря був занадто довгим, щоб його можна було змінити. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: Такий E-mail вже існує. - need_to_be_verified: - other: Електронна пошта повинна бути підтверджена. - verify_url_expired: - other: Термін дії підтвердженої URL-адреси закінчився, будь ласка, надішліть листа повторно. - illegal_email_domain_error: - other: З цього поштового домену заборонено надсилати електронну пошту. Будь ласка, використовуйте інший. - lang: - not_found: - other: Мовний файл не знайдено. - object: - captcha_verification_failed: - other: Неправильно введено капчу. - disallow_follow: - other: Вам не дозволено підписатися. - disallow_vote: - other: Вам не дозволено голосувати. - disallow_vote_your_self: - other: Ви не можете проголосувати за власну публікацію. - not_found: - other: Обʼєкт не знайдено. - verification_failed: - other: Не вдалося виконати перевірку. - email_or_password_incorrect: - other: Електронна пошта та пароль не збігаються. - old_password_verification_failed: - other: Не вдалося перевірити старий пароль - new_password_same_as_previous_setting: - other: Новий пароль збігається з попереднім. - already_deleted: - other: Публікацію видалено. - meta: - object_not_found: - other: Мета-об'єкт не знайдено - question: - already_deleted: - other: Публікацію видалено. - under_review: - other: Ваше повідомлення очікує на розгляд. Його буде видно після того, як воно буде схвалено. - not_found: - other: Питання не знайдено. - cannot_deleted: - other: Немає дозволу на видалення. - cannot_close: - other: Немає дозволу на закриття. - cannot_update: - other: Немає дозволу на оновлення. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Ранг репутації не відповідає умові. - vote_fail_to_meet_the_condition: - other: Дякуємо за відгук. Щоб проголосувати, вам потрібна репутація не нижче {{.Rank}}. - no_enough_rank_to_operate: - other: Щоб це зробити, вам потрібна репутація не менше {{.Rank}}. - report: - handle_failed: - other: Не вдалося обробити звіт. - not_found: - other: Звіт не знайдено. - tag: - already_exist: - other: Теґ уже існує. - not_found: - other: Теґ не знайдено. - recommend_tag_not_found: - other: Рекомендований теґ не існує. - recommend_tag_enter: - other: Будь ласка, введіть принаймні один необхідний тег. - not_contain_synonym_tags: - other: Не повинно містити теґи синонімів. - cannot_update: - other: Немає дозволу на оновлення. - is_used_cannot_delete: - other: Ви не можете видалити теґ, який використовується. - cannot_set_synonym_as_itself: - other: Ви не можете встановити синонім поточного тегу як сам тег. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: Ім’я відправника не може бути електронною адресою. - theme: - not_found: - other: Тему не знайдено. - revision: - review_underway: - other: Наразі неможливо редагувати, є версія в черзі перегляду. - no_permission: - other: Немає дозволу на перегляд. - user: - external_login_missing_user_id: - other: Платформа сторонніх розробників не надає унікальний ідентифікатор користувача, тому ви не можете увійти, будь ласка, зв’яжіться з адміністратором вебсайту. - external_login_unbinding_forbidden: - other: Будь ласка, встановіть пароль для входу до свого облікового запису, перш ніж видалити ім'я користувача. - email_or_password_wrong: - other: - other: Електронна пошта та пароль не збігаються. - not_found: - other: Користувач не знайдений. - suspended: - other: Користувач був призупинений. - username_invalid: - other: Ім'я користувача недійсне. - username_duplicate: - other: Це ім'я користувача вже використовується. - set_avatar: - other: Не вдалося встановити аватар. - cannot_update_your_role: - other: Ви не можете змінити вашу роль. - not_allowed_registration: - other: На цей час сайт не відкритий для реєстрації. - not_allowed_login_via_password: - other: Наразі на сайті заборонено вхід за допомогою пароля. - access_denied: - other: Доступ заборонено - page_access_denied: - other: Ви не маєте доступу до цієї сторінки. - add_bulk_users_format_error: - other: "Помилка формату {{.Field}} біля '{{.Content}}' у рядку {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "Кількість користувачів, яких ви додаєте одночасно, має бути в діапазоні 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Не вдалося прочитати конфігурацію - database: - connection_failed: - other: Не вдалося встановити з'єднання з базою даних - create_table_failed: - other: Не вдалося створити таблицю - install: - create_config_failed: - other: Не вдалося створити config.yaml файл. - upload: - unsupported_file_format: - other: Непідтримуваний формат файлу. - site_info: - config_not_found: - other: Конфігурацію сайту не знайдено. - badge: - object_not_found: - other: Об'єкт значка не знайдено - reason: - spam: - name: - other: спам - desc: - other: Це повідомлення є рекламою або вандалізмом. Воно не є корисним або не має відношення до поточної теми. - rude_or_abusive: - name: - other: грубо чи образливо - desc: - other: "Розумна людина вважатиме такий зміст неприйнятним для ввічливого спілкування." - a_duplicate: - name: - other: дублікат - desc: - other: Це питання ставилося раніше, і на нього вже є відповідь. - placeholder: - other: Введіть наявне посилання на питання - not_a_answer: - name: - other: не відповідь - desc: - other: "Це повідомлення було опубліковане як відповідь, але воно не є спробою відповісти на запитання. Можливо, його слід відредагувати, прокоментувати, поставити інше запитання або взагалі видалити." - no_longer_needed: - name: - other: більше не потрібно - desc: - other: Цей коментар є застарілим, розмовним або не стосується цієї публікації. - something: - name: - other: інше - desc: - other: Ця публікація вимагає уваги персоналу з іншої причини, що не вказана вище. - placeholder: - other: Дайте нам знати, що саме вас турбує - community_specific: - name: - other: причина для спільноти - desc: - other: Це запитання не відповідає правилам спільноти. - not_clarity: - name: - other: потребує деталей або ясності - desc: - other: Наразі це запитання містить кілька запитань в одному. Воно має бути зосереджене лише на одній проблемі. - looks_ok: - name: - other: виглядає добре - desc: - other: Цей допис хороший, як є, і не є низької якості. - needs_edit: - name: - other: потребує редагування, і я це зробив - desc: - other: Поліпшіть та виправте проблеми з цією публікацією самостійно. - needs_close: - name: - other: потрібно закрити - desc: - other: Закрите питання не може відповісти, але все ще може редагувати, голосувати і коментувати. - needs_delete: - name: - other: потрібно видалити - desc: - other: Цей допис буде видалено. - question: - close: - duplicate: - name: - other: спам - desc: - other: Це питання ставилося раніше, і на нього вже є відповідь. - guideline: - name: - other: причина для спільноти - desc: - other: Це запитання не відповідає правилам спільноти. - multiple: - name: - other: потребує деталей або ясності - desc: - other: Наразі це питання включає кілька запитань в одному. Воно має зосереджуватися лише на одній проблемі. - other: - name: - other: інше - desc: - other: Для цього допису потрібна інша причина, не зазначена вище. - operation_type: - asked: - other: запитав - answered: - other: відповів - modified: - other: змінено - deleted_title: - other: Видалене питання - questions_title: - other: Питання - tag: - tags_title: - other: Теґи - no_description: - other: Тег не має опису. - notification: - action: - update_question: - other: оновлене питання - answer_the_question: - other: питання з відповіддю - update_answer: - other: оновлена відповідь - accept_answer: - other: прийнята відповідь - comment_question: - other: прокоментоване питання - comment_answer: - other: прокоментована відповідь - reply_to_you: - other: відповів(-ла) вам - mention_you: - other: згадав(-ла) вас - your_question_is_closed: - other: Ваше запитання закрито - your_question_was_deleted: - other: Ваше запитання видалено - your_answer_was_deleted: - other: Вашу відповідь видалено - your_comment_was_deleted: - other: Ваш коментар видалено - up_voted_question: - other: питання, за яке найбільше проголосували - down_voted_question: - other: питання, за яке проголосували менше - up_voted_answer: - other: відповідь, за яку проголосували найбільше - down_voted_answer: - other: downvoted answer - up_voted_comment: - other: коментар, за який проголосували - invited_you_to_answer: - other: запросив(-ла) вас відповісти - earned_badge: - other: Ви заробили бейдж "{{.BadgeName}}" - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Підтвердіть нову адресу електронної пошти" - body: - other: "Підтвердьте свою нову адресу електронної пошти для {{.SiteName}} натиснувши на наступне посилання:
        \n{{.ChangeEmailUrl}}

        \n\nЯкщо ви не запитували цю зміну, будь ласка, ігноруйте цей лист.

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} відповів(-ла) на ваше запитання" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nПереглянути на {{.SiteName}}

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена.

        \n\nВідписатися" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} запросив(-ла) вас відповісти" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Думаю, ви можете знати відповідь.

        \nПереглянути на {{.SiteName}}

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена.

        \n\nВідписатися" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} прокоментували ваш допис" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nПереглянути на {{.SiteName}}

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена.

        \n\nВідписатися" - new_question: - title: - other: "[{{.SiteName}}] Нове питання: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Скидання пароля" - body: - other: "Хтось попросив скинути ваш пароль на {{.SiteName}}.

        \n\nЯкщо це не ви, можете сміливо ігнорувати цей лист.

        \n\nПерейдіть за наступним посиланням, щоб вибрати новий пароль:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена." - register: - title: - other: "[{{.SiteName}}] Підтвердьте свій новий обліковий запис" - body: - other: "Ласкаво просимо до {{.SiteName}}!

        \n\nПерейдіть за наступним посиланням, щоб підтвердити та активувати свій новий обліковий запис:
        \n{{.RegisterUrl}}

        \n\nЯкщо наведене вище посилання не відкривається, спробуйте скопіювати і вставити його в адресний рядок вашого веб-браузера.\n

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена." - test: - title: - other: "[{{.SiteName}}] Тестовий електронний лист" - body: - other: "Це тестовий електронний лист.\n

        \n\n--
        \nПримітка: Це автоматичний системний електронний лист, будь ласка, не відповідайте на це повідомлення, оскільки ваша відповідь не буде побачена." - action_activity_type: - upvote: - other: підтримати - upvoted: - other: підтримано - downvote: - other: голос "проти" - downvoted: - other: проголосував проти - accept: - other: прийняти - accepted: - other: прийнято - edit: - other: редагувати - review: - queued_post: - other: Допис у черзі - flagged_post: - other: Відмічений пост - suggested_post_edit: - other: Запропоновані зміни - reaction: - tooltip: - other: "{{ .Names }} і {{ .Count }} більше..." - badge: - default_badges: - autobiographer: - name: - other: Автобіограф - desc: - other: Заповнена інформація про профіль. - certified: - name: - other: Підтверджений - desc: - other: Завершено наш новий посібник користувача. - editor: - name: - other: Редактор - desc: - other: Перше редагування посту. - first_flag: - name: - other: Перший прапор - desc: - other: Спочатку позначено допис. - first_upvote: - name: - other: Перший голос за - desc: - other: Першим голосував за допис. - first_link: - name: - other: Перше посилання - desc: - other: First added a link to another post. - first_reaction: - name: - other: Перша реакція - desc: - other: Першим відреагував на допис. - first_share: - name: - other: Перше поширення - desc: - other: Перший поділився публікацією. - scholar: - name: - other: Вчений - desc: - other: Поставив питання і прийняв відповідь. - commentator: - name: - other: Коментатор - desc: - other: Залиште 5 коментарів. - new_user_of_the_month: - name: - other: Новий користувач місяця - desc: - other: Видатні внески за їх перший місяць. - read_guidelines: - name: - other: Прочитайте Інструкцію - desc: - other: Прочитайте [рекомендації для спільноти]. - reader: - name: - other: Читач - desc: - other: Прочитайте кожну відповідь у темі з більш ніж 10 відповідями. - welcome: - name: - other: Ласкаво просимо - desc: - other: Отримав голос. - nice_share: - name: - other: Гарне поширення - desc: - other: Поділилися постом з 25 унікальними відвідувачами. - good_share: - name: - other: Хороше поширення - desc: - other: Поділилися постом з 300 унікальними відвідувачами. - great_share: - name: - other: Відмінне поширення - desc: - other: Поділилися постом з 1000 унікальними відвідувачами. - out_of_love: - name: - other: З любові - desc: - other: Використав 50 голосів «за» за день. - higher_love: - name: - other: Вище кохання - desc: - other: Використав 50 голосів «за» за день 5 разів. - crazy_in_love: - name: - other: Божевільний в любові - desc: - other: Використав 50 голосів «за» за день 20 разів. - promoter: - name: - other: Промоутер - desc: - other: Запросив користувача. - campaigner: - name: - other: Агітатор - desc: - other: Запрошено 3 основних користувачів. - champion: - name: - other: Чемпіон - desc: - other: Запросив 5 учасників. - thank_you: - name: - other: Дякую - desc: - other: Має 20 дописів, за які проголосували, і віддав 10 голосів «за». - gives_back: - name: - other: Дає назад - desc: - other: Має 100 дописів, за які проголосували, і віддав 100 голосів «за». - empathetic: - name: - other: Емпатичний - desc: - other: Має 500 дописів, за які проголосували, і віддав 1000 голосів «за». - enthusiast: - name: - other: Ентузіаст - desc: - other: Відвідано 10 днів поспіль. - aficionado: - name: - other: Шанувальник - desc: - other: Відвідано 100 днів поспіль. - devotee: - name: - other: Відданий - desc: - other: Відвідано 365 днів поспіль. - anniversary: - name: - other: Річниця - desc: - other: Активний учасник на рік, опублікував принаймні один раз. - appreciated: - name: - other: Оцінений - desc: - other: Отримано 1 голос за 20 дописів. - respected: - name: - other: Шанований - desc: - other: Отримано 2 голоси за 100 дописів. - admired: - name: - other: Захоплений - desc: - other: Отримано 5 голосів за 300 дописів. - solved: - name: - other: Вирішено - desc: - other: Нехай відповідь буде прийнята. - guidance_counsellor: - name: - other: Радник супроводу - desc: - other: Прийміть 10 відповідей. - know_it_all: - name: - other: Усезнайко - desc: - other: Було прийнято 50 відповідей. - solution_institution: - name: - other: Інституція рішення - desc: - other: Було прийнято 150 відповідей. - nice_answer: - name: - other: Чудова відповідь - desc: - other: Оцінка відповіді на 10 або більше. - good_answer: - name: - other: Гарна відповідь - desc: - other: Оцінка відповіді на 25 або більше. - great_answer: - name: - other: Чудова відповідь - desc: - other: Оцінка відповіді на 50 або більше. - nice_question: - name: - other: Гарне питання - desc: - other: Оцінка питання на 10 або більше. - good_question: - name: - other: Хороше питання - desc: - other: Оцінка питання на 25 або більше. - great_question: - name: - other: Відмінне питання - desc: - other: Оцінка питання на 50 або більше. - popular_question: - name: - other: Популярне питання - desc: - other: Питання з 500 переглядами. - notable_question: - name: - other: Помітне питання - desc: - other: Питання з 1000 переглядами. - famous_question: - name: - other: Знамените питання - desc: - other: Питання з 5000 переглядами. - popular_link: - name: - other: Популярне посилання - desc: - other: Опубліковано зовнішнє посилання з 50 натисканнями. - hot_link: - name: - other: Гаряче посилання - desc: - other: Опубліковано зовнішнє посилання з 300 натисканнями. - famous_link: - name: - other: Знамените Посилання - desc: - other: Опубліковано зовнішнє посилання зі 100 натисканнями. - default_badge_groups: - getting_started: - name: - other: Початок роботи - community: - name: - other: Спільнота - posting: - name: - other: Публікація -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Як відформатувати - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: Назад - next: Далі - page_title: - question: Запитання - questions: Запитання - tag: Теґ - tags: Теґи - tag_wiki: тег вікі - create_tag: Створити теґ - edit_tag: Редагувати теґ - ask_a_question: Create Question - edit_question: Редагувати запитання - edit_answer: Редагувати відповідь - search: Пошук - posts_containing: Публікації, що містять - settings: Налаштування - notifications: Сповіщення - login: Увійти - sign_up: Зареєструватися - account_recovery: Відновлення облікового запису - account_activation: Активація облікового запису - confirm_email: Підтвердити електронну адресу - account_suspended: Обліковий запис призупинено - admin: Адмін - change_email: Змінити електронну адресу - install: Встановлення Answer - upgrade: Оновлення Answer - maintenance: Технічне обслуговування сайту - users: Користувачі - oauth_callback: Обробка - http_404: Помилка HTTP 404 - http_50X: Помилка HTTP 500 - http_403: Помилка HTTP 403 - logout: Вийти - posts: Posts - notifications: - title: Сповіщення - inbox: Вхідні - achievement: Досягнення - new_alerts: Нові сповіщення - all_read: Позначити все як прочитане - show_more: Показати більше - someone: Хтось - inbox_type: - all: Усі - posts: Публікації - invites: Запрошення - votes: Голоси - answer: Відповідь - question: Запитання - badge_award: Значок - suspended: - title: Ваш обліковий запис було призупинено - until_time: "Ваш обліковий запис призупинено до {{ time }}." - forever: Цього користувача призупинено назавжди. - end: Ви не дотримуєтеся правил спільноти. - contact_us: Зв'яжіться з нами - editor: - blockquote: - text: Блок Цитування - bold: - text: Надійний - chart: - text: Діаграма - flow_chart: Блок-схема - sequence_diagram: Діаграма послідовності - class_diagram: Діаграма класів - state_diagram: Діаграма станів - entity_relationship_diagram: Діаграма зв'язків сутностей - user_defined_diagram: Визначена користувачем діаграма - gantt_chart: Діаграма Ґанта - pie_chart: Кругова діаграма - code: - text: Зразок коду - add_code: Додати зразок коду - form: - fields: - code: - label: Код - msg: - empty: Код не може бути порожнім. - language: - label: Мова - placeholder: Автоматичне визначення - btn_cancel: Скасувати - btn_confirm: Додати - formula: - text: Формула - options: - inline: Вбудована формула - block: Формула блоку - heading: - text: Заголовок - options: - h1: Заголовок 1 - h2: Заголовок 2 - h3: Заголовок 3 - h4: Заголовок 4 - h5: Заголовок 5 - h6: Заголовок 6 - help: - text: Допомога - hr: - text: Горизонтальна лінійка - image: - text: Зображення - add_image: Додати зображення - tab_image: Завантажити зображення - form_image: - fields: - file: - label: Файл зображення - btn: Обрати зображення - msg: - empty: Файл не може бути порожнім. - only_image: Допустимі лише файли зображень. - max_size: Розмір файлу не може перевищувати {{size}} МБ. - desc: - label: Опис - tab_url: URL зображення - form_url: - fields: - url: - label: URL зображення - msg: - empty: URL-адреса зображення не може бути пустою. - name: - label: Опис - btn_cancel: Скасувати - btn_confirm: Додати - uploading: Завантаження - indent: - text: Абзац - outdent: - text: Відступ - italic: - text: Акцент - link: - text: Гіперпосилання - add_link: Додати гіперпосилання - form: - fields: - url: - label: URL - msg: - empty: URL-адреса не може бути пустою. - name: - label: Опис - btn_cancel: Скасувати - btn_confirm: Додати - ordered_list: - text: Нумерований список - unordered_list: - text: Маркований список - table: - text: Таблиця - heading: Заголовок - cell: Клітинка - file: - text: Прикріпити файли - not_supported: "Не підтримується цей тип файлу. Спробуйте ще раз з {{file_type}}." - max_size: "Розмір прикріплених файлів не може перевищувати {{size}} МБ." - close_modal: - title: Я закриваю цей пост, оскільки... - btn_cancel: Скасувати - btn_submit: Надіслати - remark: - empty: Не може бути порожнім. - msg: - empty: Будь ласка, оберіть причину. - report_modal: - flag_title: Я ставлю відмітку, щоб повідомити про цю публікацію як... - close_title: Я закриваю цей пост, оскільки... - review_question_title: Переглянути питання - review_answer_title: Переглянути відповідь - review_comment_title: Переглянути коментар - btn_cancel: Скасувати - btn_submit: Надіслати - remark: - empty: Не може бути порожнім. - msg: - empty: Будь ласка, оберіть причину. - not_a_url: Формат URL неправильний. - url_not_match: Походження URL не збігається з поточним вебсайтом. - tag_modal: - title: Створити новий теґ - form: - fields: - display_name: - label: Ім'я для відображення - msg: - empty: Ім'я для відображення не може бути порожнім. - range: Ім'я для відображення до 35 символів. - slug_name: - label: Скорочена URL-адреса - desc: Скорочення URL до 35 символів. - msg: - empty: Скорочення URL не може бути пустим. - range: Скорочення URL до 35 символів. - character: Скорочення URL містить незадовільний набір символів. - desc: - label: Опис - revision: - label: Редакція - edit_summary: - label: Підсумок редагування - placeholder: >- - Коротко поясніть ваші зміни (виправлена орфографія, виправлена граматика, покращене форматування) - btn_cancel: Скасувати - btn_submit: Надіслати - btn_post: Опублікувати новий теґ - tag_info: - created_at: Створено - edited_at: Відредаговано - history: Історія - synonyms: - title: Синоніми - text: Наступні теги буде змінено на - empty: Синонімів не знайдено. - btn_add: Додати синонім - btn_edit: Редагувати - btn_save: Зберегти - synonyms_text: Наступні теги буде змінено на - delete: - title: Видалити цей теґ - tip_with_posts: >- -

        Ми не дозволяємо видаляти тег з дописами.

        Передусім, будь ласка, вилучіть цей тег з дописів.

        - tip_with_synonyms: >- -

        Ми не дозволяємо видаляти тег із синонімами.

        Передусім, будь ласка, вилучіть синоніми з цього тега.

        - tip: Ви впевнені, що хочете видалити? - close: Закрити - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Редагувати теґ - default_reason: Редагувати теґ - default_first_reason: Додати теґ - btn_save_edits: Зберегти зміни - btn_cancel: Скасувати - dates: - long_date: МММ Д - long_date_with_year: "МММ Д, РРРР" - long_date_with_time: "МММ Д, РРРР [о] ГГ:хв" - now: зараз - x_seconds_ago: "{{count}}сек назад" - x_minutes_ago: "{{count}}хв назад" - x_hours_ago: "{{count}}год назад" - hour: година - day: день - hours: годин - days: дні - month: month - months: months - year: year - reaction: - heart: серце - smile: посмішка - frown: насупився - btn_label: додавати або вилучати реакції - undo_emoji: скасувати реакцію {{ emoji }} - react_emoji: реагувати з {{ emoji }} - unreact_emoji: не реагувати з {{ emoji }} - comment: - btn_add_comment: Додати коментар - reply_to: Відповісти на - btn_reply: Відповісти - btn_edit: Редагувати - btn_delete: Видалити - btn_flag: Відмітити - btn_save_edits: Зберегти зміни - btn_cancel: Скасувати - show_more: "Ще {{count}} коментарів" - tip_question: >- - Використовуйте коментарі, щоб попросити більше інформації або запропонувати покращення. Уникайте відповідей на питання в коментарях. - tip_answer: >- - Використовуйте коментарі, щоб відповідати іншим користувачам або повідомляти їх про зміни. Якщо ви додаєте нову інформацію, відредагуйте свою публікацію, а не коментуйте. - tip_vote: Це додає щось корисне до допису - edit_answer: - title: Редагувати відповідь - default_reason: Редагувати відповідь - default_first_reason: Додати відповідь - form: - fields: - revision: - label: Редакція - answer: - label: Відповідь - feedback: - characters: вміст має бути не менше 6 символів. - edit_summary: - label: Редагувати підсумок - placeholder: >- - Коротко поясніть ваші зміни (виправлена орфографія, виправлена граматика, покращене форматування) - btn_save_edits: Зберегти зміни - btn_cancel: Скасувати - tags: - title: Теґи - sort_buttons: - popular: Популярне - name: Назва - newest: Найновіші - button_follow: Підписатися - button_following: Підписані - tag_label: запитання - search_placeholder: Фільтрувати за назвою теґу - no_desc: Цей теґ не має опису. - more: Більше - wiki: Вікі - ask: - title: Create Question - edit_title: Редагувати питання - default_reason: Редагувати питання - default_first_reason: Create question - similar_questions: Подібні питання - form: - fields: - revision: - label: Редакція - title: - label: Назва - placeholder: What's your topic? Be specific. - msg: - empty: Назва не може бути порожньою. - range: Назва до 150 символів - body: - label: Тіло - msg: - empty: Тіло не може бути порожнім. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Теґи - msg: - empty: Теґи не можуть бути порожніми. - answer: - label: Відповідь - msg: - empty: Відповідь не може бути порожньою. - edit_summary: - label: Редагувати підсумок - placeholder: >- - Коротко поясніть ваші зміни (виправлена орфографія, виправлена граматика, покращене форматування) - btn_post_question: Опублікуйте своє запитання - btn_save_edits: Зберегти зміни - answer_question: Відповісти на власне питання - post_question&answer: Опублікуйте своє запитання і відповідь - tag_selector: - add_btn: Додати теґ - create_btn: Створити новий теґ - search_tag: Шукати теґ - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: Не знайдено тегів - tag_required_text: Обов'язковий тег (принаймні один) - header: - nav: - question: Запитання - tag: Теґи - user: Користувачі - badges: Значки - profile: Профіль - setting: Налаштування - logout: Вийти - admin: Адмін - review: Огляд - bookmark: Закладки - moderation: Модерація - search: - placeholder: Пошук - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Змінити - loading: завантаження... - pic_auth_code: - title: Капча - placeholder: Введіть текст вище - msg: - empty: Капча не може бути порожньою. - inactive: - first: >- - Ви майже закінчили! Ми надіслали лист для активації на {{mail}}. Будь ласка, дотримуйтесь інструкцій, щоб активувати свій обліковий запис. - info: "Якщо він не надійшов, перевірте папку зі спамом." - another: >- - Ми надіслали вам інший електронний лист для активації на {{mail}}. Це може зайняти кілька хвилин, перш ніж він прибуде; обов'язково перевірте теку зі спамом. - btn_name: Повторно надіслати електронний лист для активації - change_btn_name: Змінити електронну пошту - msg: - empty: Не може бути порожнім. - resend_email: - url_label: Ви впевнені, що бажаєте повторно надіслати електронний лист для активації? - url_text: Ви також можете дати користувачеві наведене вище посилання для активації. - login: - login_to_continue: Увійдіть, щоб продовжити - info_sign: Немає облікового запису? <1>Зареєструйтесь - info_login: Вже маєте обліковий запис? <1>Увійдіть - agreements: Реєструючись, ви погоджуєтеся з <1>політикою конфіденційності та <3>умовами використання. - forgot_pass: Забули пароль? - name: - label: Ім’я - msg: - empty: Ім'я не може бути порожнім. - range: Ім'я повинно мати довжину від 2 до 30 символів. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: Електронна пошта - msg: - empty: Поле електронної пошти не може бути пустим. - password: - label: Пароль - msg: - empty: Поле паролю не може бути порожнім. - different: Двічі введені паролі є несумісними - account_forgot: - page_title: Забули свій пароль - btn_name: Надішліть мені електронний лист для відновлення - send_success: >- - Якщо обліковий запис збігається з {{mail}}, незабаром ви отримаєте електронний лист з інструкціями щодо скидання пароля. - email: - label: Електронна пошта - msg: - empty: Поле електронної пошти не може бути пустим. - change_email: - btn_cancel: Скасувати - btn_update: Оновити адресу електронної пошти - send_success: >- - Якщо обліковий запис збігається з {{mail}}, незабаром ви отримаєте електронний лист з інструкціями щодо скидання пароля. - email: - label: Нова електронна пошта - msg: - empty: Поле електронної пошти не може бути пустим. - oauth: - connect: З'єднати з {{ auth_name }} - remove: Видалити {{ auth_name }} - oauth_bind_email: - subtitle: Додайте резервну електронну пошту до свого облікового запису. - btn_update: Оновити адресу електронної пошти - email: - label: Електронна пошта - msg: - empty: Поле електронної пошти не може бути пустим. - modal_title: Електронна адреса вже існує. - modal_content: Ця електронна адреса вже зареєстрована. Ви впевнені, що бажаєте підключитися до існуючого облікового запису? - modal_cancel: Змінити електронну пошту - modal_confirm: Під'єднати до існуючого облікового запису - password_reset: - page_title: Скинути пароль - btn_name: Скинути мій пароль - reset_success: >- - Ви успішно змінили пароль; вас буде перенаправлено на сторінку входу в систему. - link_invalid: >- - На жаль, це посилання для зміни пароля більше недійсне. Можливо, ваш пароль уже скинуто? - to_login: Продовжити вхід на сторінку - password: - label: Пароль - msg: - empty: Поле паролю не може бути порожнім. - length: Довжина повинна бути від 8 до 32 символів - different: Двічі введені паролі є несумісними - password_confirm: - label: Підтвердити новий пароль - settings: - page_title: Налаштування - goto_modify: Перейти до зміни - nav: - profile: Профіль - notification: Сповіщення - account: Обліковий запис - interface: Інтерфейс - profile: - heading: Профіль - btn_name: Зберегти - display_name: - label: Ім'я для відображення - msg: Ім'я для відображення не може бути порожнім. - msg_range: Display name must be 2-30 characters in length. - username: - label: Ім'я користувача - caption: Користувачі можуть згадувати вас як "@username". - msg: Ім’я користувача не може бути порожнім. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Зображення профілю - gravatar: Gravatar - gravatar_text: Ви можете змінити зображення на - custom: Власне - custom_text: Ви можете завантажити своє зображення. - default: Системне - msg: Будь ласка, завантажте аватар - bio: - label: Про мене - website: - label: Вебсайт - placeholder: "https://example.com" - msg: Неправильний формат вебсайту - location: - label: Місцезнаходження - placeholder: "Місто, Країна" - notification: - heading: Сповіщення електронною поштою - turn_on: Увімкнути - inbox: - label: Вхідні сповіщення - description: Відповіді на ваші запитання, коментарі, запрошення тощо. - all_new_question: - label: Усі нові запитання - description: Отримуйте сповіщення про всі нові питання. До 50 питань на тиждень. - all_new_question_for_following_tags: - label: Всі нові запитання з наступними тегами - description: Отримувати сповіщення про нові запитання з наступними тегами. - account: - heading: Обліковий запис - change_email_btn: Змінити електронну пошту - change_pass_btn: Змінити пароль - change_email_info: >- - Ми надіслали електронний лист на цю адресу. Будь ласка, дотримуйтесь інструкцій для підтвердження. - email: - label: Нова електронна пошта - new_email: - label: Нова електронна пошта - msg: Нова електронна пошта не може бути порожньою. - pass: - label: Поточний пароль - msg: Комірка паролю не може бути порожньою. - password_title: Пароль - current_pass: - label: Поточний пароль - msg: - empty: Комірка поточного пароля не може бути порожньою. - length: Довжина повинна бути від 8 до 32 символів. - different: Два введені паролі не збігаються. - new_pass: - label: Новий пароль - pass_confirm: - label: Підтвердити новий пароль - interface: - heading: Інтерфейс - lang: - label: Мова інтерфейсу - text: Мова інтерфейсу користувача. Зміниться, коли ви оновите сторінку. - my_logins: - title: Мої логіни - label: Увійдіть або зареєструйтеся на цьому сайті, використовуючи ці облікові записи. - modal_title: Видалити логін - modal_content: Ви впевнені, що хочете видалити цей логін з облікового запису? - modal_confirm_btn: Видалити - remove_success: Успішно видалено - toast: - update: успішно оновлено - update_password: Пароль успішно змінено. - flag_success: Дякую, що відмітили. - forbidden_operate_self: Заборонено застосовувати на собі - review: Ваша версія з'явиться після перевірки. - sent_success: Успішно відправлено - related_question: - title: Related - answers: відповіді - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Люди запитували - desc: Виберіть людей, які, на вашу думку, можуть знати відповідь. - invite: Запросити відповісти - add: Додати людей - search: Шукати людей - question_detail: - action: Дія - created: Created - Asked: Запитали - asked: запитали - update: Змінено - Edited: Edited - edit: відредаговано - commented: прокоментовано - Views: Переглянуто - Follow: Підписатися - Following: Підписані - follow_tip: Підпишіться на це запитання, щоб отримувати сповіщення - answered: дано відповідь - closed_in: Зачинено в - show_exist: Показати наявне запитання. - useful: Корисне - question_useful: Це корисно і ясно - question_un_useful: Це неясно або некорисно - question_bookmark: Додати в закладки це питання - answer_useful: Це корисно - answer_un_useful: Це некорисно - answers: - title: Відповіді - score: Оцінка - newest: Найновіші - oldest: Найдавніші - btn_accept: Прийняти - btn_accepted: Прийнято - write_answer: - title: Ваша відповідь - edit_answer: Редагувати мою чинну відповідь - btn_name: Опублікувати свою відповідь - add_another_answer: Додати ще одну відповідь - confirm_title: Перейти до відповіді - continue: Продовжити - confirm_info: >- -

        Ви впевнені, що хочете додати ще одну відповідь?

        Натомість ви можете скористатися посиланням редагування, щоб уточнити та покращити вже існуючу відповідь.

        - empty: Відповідь не може бути порожньою. - characters: вміст має бути не менше 6 символів. - tips: - header_1: Дякуємо за відповідь - li1_1: Будь ласка, не забудьте відповісти на запитання. Надайте детальну інформацію та поділіться своїми дослідженнями. - li1_2: Підкріплюйте будь-які ваші твердження посиланнями чи особистим досвідом. - header_2: Але уникайте... - li2_1: Просити про допомогу, шукати роз'яснення або реагувати на інші відповіді. - reopen: - confirm_btn: Відкрити знову - title: Повторно відкрити цей допис - content: Ви впевнені, що хочете повторно відкрити? - list: - confirm_btn: Список - title: Показати цей допис - content: Ви впевнені, що хочете скласти список? - unlist: - confirm_btn: Вилучити зі списку - title: Вилучити допис зі списку - content: Ви впевнені, що хочете вилучити зі списку? - pin: - title: Закріпити цей допис - content: Ви впевнені, що хочете закріпити глобально? Цей допис відображатиметься вгорі всіх списків публікацій. - confirm_btn: Закріпити - delete: - title: Видалити цей допис - question: >- - Ми не рекомендуємо видаляти питання з відповідями, оскільки це позбавляє майбутніх читачів цих знань.

        Повторне видалення запитань із відповідями може призвести до блокування запитів у вашому обліковому записі. Ви впевнені, що хочете видалити? - answer_accepted: >- -

        Ми не рекомендуємо видаляти прийняту відповідь, оскільки це позбавляє майбутніх читачів цих знань.

        Повторне видалення прийнятих відповідей може призвести до того, що ваш обліковий запис буде заблоковано для відповідей. Ви впевнені, що хочете видалити? - other: Ви впевнені, що хочете видалити? - tip_answer_deleted: Ця відповідь була видалена - undelete_title: Скасувати видалення цього допису - undelete_desc: Ви впевнені, що бажаєте скасувати видалення? - btns: - confirm: Підтвердити - cancel: Скасувати - edit: Редагувати - save: Зберегти - delete: Видалити - undelete: Скасувати видалення - list: Список - unlist: Вилучити зі списку - unlisted: Вилучене зі списку - login: Увійти - signup: Зареєструватися - logout: Вийти - verify: Підтвердити - create: Create - approve: Затвердити - reject: Відхилити - skip: Пропустити - discard_draft: Видалити чернетку - pinned: Закріплено - all: Усі - question: Запитання - answer: Відповідь - comment: Коментар - refresh: Оновити - resend: Надіслати повторно - deactivate: Деактивувати - active: Активні - suspend: Призупинити - unsuspend: Відновити - close: Закрити - reopen: Відкрити знову - ok: ОК - light: Світла - dark: Темна - system_setting: Налаштування системи - default: За замовчуванням - reset: Скинути - tag: Тег - post_lowercase: допис - filter: Фільтр - ignore: Ігнорувати - submit: Надіслати - normal: Нормальний - closed: Закриті - deleted: Видалені - deleted_permanently: Deleted permanently - pending: Очікування - more: Більше - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Результати пошуку - keywords: Ключові слова - options: Параметри - follow: Підписатися - following: Підписані - counts: "{{count}} Результатів" - counts_loading: "... Results" - more: Більше - sort_btns: - relevance: Релевантність - newest: Найновіші - active: Активні - score: Оцінка - more: Більше - tips: - title: Підказки щодо розширеного пошуку - tag: "<1>[tag] шукати за тегом" - user: "<1>користувач:ім'я користувача пошук за автором" - answer: "<1>відповіді:0 питання без відповіді" - score: "<1>рахунок: 3 записи із 3+ рахунком" - question: "<1>є:питання пошукові питання" - is_answer: "<1>є:відповідь пошукові відповіді" - empty: Ми не змогли нічого знайти.
        Спробуйте різні або менш конкретні ключові слова. - share: - name: Поділитись - copy: Копіювати посилання - via: Поділитися дописом через... - copied: Скопійовано - facebook: Поділитись на Facebook - twitter: Share to X - cannot_vote_for_self: Ви не можете проголосувати за власну публікацію. - modal_confirm: - title: Помилка... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Ваш новий обліковий запис підтверджено; вас буде перенаправлено на головну сторінку. - link: Перейти на головну сторінку - oops: Йой! - invalid: Посилання, яке ви використовували, більше не працює. - confirm_new_email: Вашу адресу електронної пошти було оновлено. - confirm_new_email_invalid: >- - На жаль, це посилання для підтвердження більше не дійсне. Можливо, ваша електронна пошта вже була змінена? - unsubscribe: - page_title: Відписатися - success_title: Ви успішно відписалися - success_desc: Вас успішно вилучено з цього списку підписників, і ви більше не будете отримувати від нас електронні листи. - link: Змінити налаштування - question: - following_tags: Підписки на теги - edit: Редагувати - save: Зберегти - follow_tag_tip: Підпишіться на теги, щоб упорядкувати свій список запитань. - hot_questions: Гарячі питання - all_questions: Всі питання - x_questions: "{{ count }} Питань" - x_answers: "{{ count }} відповідей" - x_posts: "{{ count }} Posts" - questions: Запитання - answers: Відповіді - newest: Найновіші - active: Активні - hot: Гаряче - frequent: Часто - recommend: Рекомендовано - score: Оцінка - unanswered: Без відповідей - modified: змінено - answered: дано відповідь - asked: запитано - closed: закрито - follow_a_tag: Підписатися на тег - more: Більше - personal: - overview: Загальний огляд - answers: Відповіді - answer: відповідь - questions: Запитання - question: запитання - bookmarks: Закладки - reputation: Репутація - comments: Коментарі - votes: Голоси - badges: Значки - newest: Найновіше - score: Оцінка - edit_profile: Редагувати профіль - visited_x_days: "Відвідано {{ count }} днів" - viewed: Переглянуто - joined: Приєднано - comma: "," - last_login: Переглянуто - about_me: Про мене - about_me_empty: "// Привіт, світ!" - top_answers: Найкращі відповіді - top_questions: Найкращі запитання - stats: Статистика - list_empty: Не знайдено жодного допису.
        Можливо, ви хочете вибрати іншу вкладку? - content_empty: Постів не знайдено. - accepted: Прийнято - answered: дано відповідь - asked: запитано - downvoted: проголосовано проти - mod_short: MOD - mod_long: Модератори - x_reputation: репутація - x_votes: отримані голоси - x_answers: відповіді - x_questions: запитання - recent_badges: Нещодавні значки - install: - title: Встановлення - next: Далі - done: Готово - config_yaml_error: Не вдалося створити config.yaml файл. - lang: - label: Будь ласка, виберіть мову - db_type: - label: Рушій бази даних - db_username: - label: Ім'я користувача - placeholder: корінь - msg: Ім’я користувача не може бути порожнім. - db_password: - label: Пароль - placeholder: корінь - msg: Поле паролю не може бути порожнім. - db_host: - label: Хост бази даних - placeholder: "db:3306" - msg: Хост бази даних не може бути порожнім. - db_name: - label: Назва бази даних - placeholder: відповідь - msg: Назва бази даних не може бути порожня. - db_file: - label: Файл бази даних - placeholder: /data/answer.db - msg: Файл бази даних не може бути порожнім. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Створити config.yaml - label: Файл config.yaml створено. - desc: >- - Ви можете створити файл <1>config.yaml вручну в каталозі <1>/var/www/xxx/ і вставити в нього наступний текст. - info: Після цього натисніть кнопку "Далі". - site_information: Інформація про сайт - admin_account: Обліковий запис адміністратора - site_name: - label: Назва сайту - msg: Назва сайту не може бути порожньою. - msg_max_length: Назва сайту повинна містити не більше 30 символів. - site_url: - label: URL сайту - text: Адреса вашого сайту. - msg: - empty: URL-адреса сайту не може бути пустою. - incorrect: Неправильний формат URL-адреси сайту. - max_length: Максимальна довжина URL-адреси сайту – 512 символів. - contact_email: - label: Контактна електронна адреса - text: Електронна адреса основної контактної особи, відповідальної за цей сайт. - msg: - empty: Контактна електронна адреса не може бути порожньою. - incorrect: Неправильний формат контактної електронної пошти. - login_required: - label: Приватний - switch: Вхід обов'язковий - text: Лише авторизовані користувачі можуть отримати доступ до цієї спільноти. - admin_name: - label: Ім’я - msg: Ім'я не може бути порожнім. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Пароль - text: >- - Вам знадобиться цей пароль для входу. Зберігайте його в надійному місці. - msg: Поле паролю не може бути порожнім. - msg_min_length: Пароль має бути не менше 8 символів. - msg_max_length: Пароль має бути не менше 32 символів. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: Електронна пошта - text: Вам знадобиться ця електронна адреса для входу. - msg: - empty: Поле електронної пошти не може бути пустим. - incorrect: Невірний формат електронної пошти. - ready_title: Ваш сайт готовий - ready_desc: >- - Якщо ви коли-небудь захочете змінити інші налаштування, відвідайте <1>розділ адміністрування; знайдіть його в меню сайту. - good_luck: "Веселіться, і хай щастить!" - warn_title: Попередження - warn_desc: >- - Файл <1>config.yaml вже існує. Якщо вам потрібно скинути будь-який з елементів конфігурації в цьому файлі, будь ласка, спочатку видаліть його. - install_now: Ви можете спробувати <1>встановити зараз. - installed: Уже встановлено - installed_desc: >- - Ви, здається, уже встановили. Щоб перевстановити, спочатку очистіть старі таблиці бази даних. - db_failed: Не вдалося встановити з'єднання з базою даних - db_failed_desc: >- - Це означає, що інформація про базу даних у вашому файлі <1>config.yaml невірна або що не вдалося встановити контакт із сервером бази даних. Це може означати, що сервер бази даних вашого хоста не працює. - counts: - views: перегляди - votes: голоси - answers: відповіді - accepted: Схвалено - page_error: - http_error: Помилка HTTP {{ code }} - desc_403: Ви не маєте дозволу на доступ до цієї сторінки. - desc_404: На жаль, такої сторінки не існує. - desc_50X: Сервер виявив помилку і не зміг виконати ваш запит. - back_home: Повернутися на головну сторінку - page_maintenance: - desc: "Ми технічно обслуговуємось, ми скоро повернемося." - nav_menus: - dashboard: Панель - contents: Зміст - questions: Питання - answers: Відповіді - users: Користувачі - badges: Значки - flags: Відмітки - settings: Налаштування - general: Основне - interface: Інтерфейс - smtp: SMTP - branding: Брендинг - legal: Правила та умови - write: Написати - terms: Terms - tos: Умови використання - privacy: Приватність - seo: SEO - customize: Персоналізувати - themes: Теми - login: Вхід - privileges: Привілеї - plugins: Плагіни - installed_plugins: Встановлені плагіни - apperance: Appearance - website_welcome: Ласкаво просимо до {{site_name}} - user_center: - login: Вхід - qrcode_login_tip: Будь ласка, використовуйте {{ agentName }}, щоб просканувати QR-код і увійти в систему. - login_failed_email_tip: Не вдалося увійти, будь ласка, дозвольте цьому додатку отримати доступ до вашої електронної пошти, перш ніж спробувати ще раз. - badges: - modal: - title: Вітаємо - content: Ти отримав новий значок. - close: Закрити - confirm: Переглянути значки - title: Значки - awarded: Присвоєно - earned_×: Зароблено ×{{ number }} - ×_awarded: "Присвоєно {{ number }}" - can_earn_multiple: Ви можете заробити це багато разів. - earned: Зароблено - admin: - admin_header: - title: Адмін - dashboard: - title: Панель - welcome: Ласкаво просимо до адміністратора! - site_statistics: Статистика сайту - questions: "Запитання:" - resolved: "Вирішено:" - unanswered: "Без відповідей:" - answers: "Відповіді:" - comments: "Коментарі:" - votes: "Голоси:" - users: "Користувачі:" - flags: "Відмітки:" - reviews: "Відгуки:" - site_health: Стан сайту - version: "Версія:" - https: "HTTPS:" - upload_folder: "Завантажити теку:" - run_mode: "Активний режим:" - private: Приватний - public: Публічний - smtp: "SMTP:" - timezone: "Часовий пояс:" - system_info: Інформація про систему - go_version: "Перейти до версії:" - database: "База даних:" - database_size: "Розмір бази даних:" - storage_used: "Використаний обсяг пам’яті:" - uptime: "Час роботи:" - links: Посилання - plugins: Плаґіни - github: GitHub - blog: Блоґ - contact: Контакт - forum: Форум - documents: Документи - feedback: Відгук - support: Підтримка - review: Огляд - config: Конфігурація - update_to: Оновити до - latest: Останній - check_failed: Не вдалося перевірити - "yes": "Так" - "no": "Ні" - not_allowed: Не дозволено - allowed: Дозволено - enabled: Увімкнено - disabled: Вимкнено - writable: Записуваний - not_writable: Не можна записувати - flags: - title: Відмітки - pending: В очікуванні - completed: Завершено - flagged: Відмічено - flagged_type: Відмічено {{ type }} - created: Створені - action: Дія - review: Огляд - user_role_modal: - title: Змінити роль користувача на... - btn_cancel: Скасувати - btn_submit: Надіслати - new_password_modal: - title: Встановити новий пароль - form: - fields: - password: - label: Пароль - text: Користувача буде виведено з системи, і йому потрібно буде увійти знову. - msg: Пароль повинен мати довжину від 8 до 32 символів. - btn_cancel: Скасувати - btn_submit: Надіслати - edit_profile_modal: - title: Редагувати профіль - form: - fields: - display_name: - label: Зображуване ім'я - msg_range: Display name must be 2-30 characters in length. - username: - label: Ім'я користувача - msg_range: Username must be 2-30 characters in length. - email: - label: Електронна пошта - msg_invalid: Невірна адреса електронної пошти. - edit_success: Успішно відредаговано - btn_cancel: Скасувати - btn_submit: Надіслати - user_modal: - title: Додати нового користувача - form: - fields: - users: - label: Масове додавання користувача - placeholder: "Джон Сміт, john@example.com, BUSYopr2\nАліса, alice@example.com, fpDntV8q" - text: '“Ім''я, електронну пошту, пароль” розділити комами. Один користувач у рядку.' - msg: "Будь ласка, введіть електронну пошту користувача, по одній на рядок." - display_name: - label: Ім'я для відображення - msg: Ім'я для показу повинно мати довжину від 2 до 30 символів. - email: - label: Електронна пошта - msg: Електронна пошта недійсна. - password: - label: Пароль - msg: Пароль повинен мати довжину від 8 до 32 символів. - btn_cancel: Скасувати - btn_submit: Надіслати - users: - title: Користувачі - name: Ім’я - email: Електронна пошта - reputation: Репутація - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Статус - role: Роль - action: Дія - change: Зміна - all: Усі - staff: Персонал - more: Більше - inactive: Неактивні - suspended: Призупинено - deleted: Видалено - normal: Нормальний - Moderator: Модератор - Admin: Адмін - User: Користувач - filter: - placeholder: "Фільтр на ім'я, користувач:id" - set_new_password: Встановити новий пароль - edit_profile: Редагувати профіль - change_status: Змінити статус - change_role: Змінити роль - show_logs: Показати записи журналу - add_user: Додати користувача - deactivate_user: - title: Деактивувати користувача - content: Неактивний користувач повинен повторно підтвердити свою електронну адресу. - delete_user: - title: Видалити цього користувача - content: Ви впевнені, що хочете видалити цього користувача? Це назавжди! - remove: Вилучити їх вміст - label: Видалити всі запитання, відповіді, коментарі тощо. - text: Не позначайте цю опцію, якщо ви хочете лише видалити обліковий запис користувача. - suspend_user: - title: Призупинити цього користувача - content: Призупинений користувач не може увійти в систему. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Запитання - unlisted: Вилучене зі списку - post: Опублікувати - votes: Голоси - answers: Відповіді - created: Створені - status: Статус - action: Дія - change: Зміна - pending: Очікування - filter: - placeholder: "Фільтр за назвою, питання:id" - answers: - page_title: Відповіді - post: Допис - votes: Голоси - created: Створено - status: Статус - action: Дія - change: Зміна - filter: - placeholder: "Фільтр за назвою, відповідь:id" - general: - page_title: Основне - name: - label: Назва сайту - msg: Назва сайту не може бути порожньою. - text: "Назва цього сайту як зазначено у заголовку тегу." - site_url: - label: URL сайту - msg: Url сайту не може бути порожньою. - validate: Будь ласка, введіть дійсну URL. - text: Адреса вашого сайту. - short_desc: - label: Короткий опис сайту - msg: Короткий опис сайту не може бути пустим. - text: "Короткий опис, як використовується в заголовку на головній сторінці." - desc: - label: Опис сайту - msg: Опис сайту не може бути порожнім. - text: "Опишіть цей сайт одним реченням, як у тезі метаопису." - contact_email: - label: Контактна електронна пошта - msg: Контактна електронна пошта не може бути порожньою. - validate: Контактна електронна пошта недійсна. - text: Адреса електронної пошти ключової особи, відповідальної за цей сайт. - check_update: - label: Оновлення програмного забезпечення - text: Автоматично перевіряти оновлення - interface: - page_title: Інтерфейс - language: - label: Мова інтерфейсу - msg: Мова інтерфейсу не може бути пустою. - text: Мова інтерфейсу користувача. Зміниться, коли ви оновите сторінку. - time_zone: - label: Часовий пояс - msg: Часовий пояс не може бути пустим. - text: Виберіть місто в тому ж часовому поясі, що й ви. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: З електронної пошти - msg: Поле з електронної пошти не може бути пустим. - text: Адреса електронної пошти, з якої надсилаються листи. - from_name: - label: Від імені - msg: Поле від імені не може бути пустим. - text: Ім'я, з якого надсилаються електронні листи. - smtp_host: - label: SMTP-хост - msg: SMTP хост не може бути порожнім. - text: Ваш поштовий сервер. - encryption: - label: Шифрування - msg: Поле шифрування не може бути пустим. - text: Для більшості серверів SSL є рекомендованим параметром. - ssl: SSL - tls: TLS - none: Нічого - smtp_port: - label: SMTP порт - msg: SMTP порт має бути числом 1 ~ 65535. - text: Порт на ваш поштовий сервер. - smtp_username: - label: Ім'я користувача SMTP - msg: Ім'я користувача SMTP не може бути порожнім. - smtp_password: - label: Пароль SMTP - msg: Пароль до SMTP не може бути порожнім. - test_email_recipient: - label: Тест отримувачів електронної пошти - text: Вкажіть адресу електронної пошти, на яку будуть надходити тестові надсилання. - msg: Тест отримувачів електронної пошти не вірний - smtp_authentication: - label: Увімкнути автентифікацію - title: SMTP аутентифікація - msg: SMTP аутентифікація не може бути порожньою. - "yes": "Так" - "no": "Ні" - branding: - page_title: Брендинг - logo: - label: Логотип - msg: Логотип не може бути порожнім. - text: Зображення логотипу у верхньому лівому кутку вашого сайту. Використовуйте широке прямокутне зображення з висотою 56 і співвідношенням сторін більше 3:1. Якщо залишити це поле порожнім, буде показано текст заголовка сайту. - mobile_logo: - label: Мобільний логотип - text: Логотип, що використовується на мобільній версії вашого сайту. Використовуйте широке прямокутне зображення висотою 56. Якщо залишити поле порожнім, буде використано зображення з налаштування "логотип". - square_icon: - label: Квадратна іконка - msg: Квадратна іконка не може бути пустою. - text: Зображення, що використовується як основа для іконок метаданих. В ідеалі має бути більшим за 512x512. - favicon: - label: Favicon - text: Іконка для вашого сайту. Для коректної роботи через CDN має бути у форматі png. Буде змінено розмір до 32x32. Якщо залишити порожнім, буде використовуватися "квадратна іконка". - legal: - page_title: Правила та умови - terms_of_service: - label: Умови використання - text: "Ви можете додати вміст про умови використання тут. Якщо у вас уже є документ, розміщений деінде, надайте тут повну URL-адресу." - privacy_policy: - label: Політика конфіденційности - text: "Ви можете додати вміст політики конфіденційності тут. Якщо у вас уже є документ, розміщений деінде, надайте тут повну URL-адресу." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Написати - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Відповідь на запис - label: Кожен користувач може написати лише одну відповідь на кожне запитання - text: "Вимкнути, щоб дозволити користувачам писати кілька відповідей на одне і те ж питання, що може призвести до розфокусування відповідей." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Рекомендовані теги - text: "За замовчуванням рекомендовані теги будуть показані у спадному списку." - msg: - contain_reserved: "рекомендовані теги не можуть містити зарезервовані теги" - required_tag: - title: Встановіть необхідні теги - label: Встановіть “Рекомендовані теги” як необхідні теги - text: "Кожне нове питання повинно мати принаймні один рекомендований тег." - reserved_tags: - label: Зарезервовані теги - text: "Зарезервовані теги можуть використовуватися лише модератором." - image_size: - label: Максимальний розмір зображення (МБ) - text: "Максимальний розмір вивантаженого зображення." - attachment_size: - label: Максимальний розмір вкладення (МБ) - text: "Максимальний розмір вкладених файлів для вивантаження." - image_megapixels: - label: Максимальна кількість мегапікселів зображення - text: "Максимальна кількість мегапікселів, дозволена для зображення." - image_extensions: - label: Дозволені розширення зображень - text: "Список розширень файлів, дозволених для показу зображень, через кому." - attachment_extensions: - label: Авторизовані розширення вкладень - text: "Список дозволених для вивантаження розширень файлів, розділених комами. ПОПЕРЕДЖЕННЯ: Дозвіл на вивантаження може спричинити проблеми з безпекою." - seo: - page_title: SEO - permalink: - label: Постійне посилання - text: Користувацькі структури URL можуть покращити уміння та сумісність з надсиланням посилань. - robots: - label: robots.txt - text: Це назавжди замінить будь-які відповідні налаштування сайту. - themes: - page_title: Теми - themes: - label: Теми - text: Виберіть наявну тему. - color_scheme: - label: Схема кольорів - navbar_style: - label: Navbar background style - primary_color: - label: Основний колір - text: Змінюйте кольори, що використовуються у ваших темах - css_and_html: - page_title: CSS та HTML - custom_css: - label: Користувацький CSS - text: > - - head: - label: Головний - text: > - - header: - label: Заголовок - text: > - - footer: - label: Низ - text: Це вставить перед </body>. - sidebar: - label: Бічна панель - text: Це буде вставлено в бічну панель. - login: - page_title: Увійти - membership: - title: Членство - label: Дозволити нові реєстрації - text: Вимкнути, щоб ніхто не міг створити новий обліковий запис. - email_registration: - title: Реєстрація за електронною поштою - label: Дозволити реєстрацію за електронною поштою - text: Вимкніть, щоб запобігти створенню нових облікових записів через електронну пошту. - allowed_email_domains: - title: Дозволені домени електронної пошти - text: Домени електронної пошти, на які користувачі повинні зареєструвати облікові записи. Один домен у рядку. Ігнорується, якщо порожній. - private: - title: Приватний - label: Вхід обов'язковий - text: Доступ до цієї спільноти мають лише зареєстровані користувачі. - password_login: - title: Вхід через пароль - label: Дозволити вхід через електронну пошту і пароль - text: "ПОПЕРЕДЖЕННЯ: Якщо вимкнути, ви не зможете увійти в систему, якщо раніше не налаштували інший метод входу." - installed_plugins: - title: Встановлені плагіни - plugin_link: Плагіни розширюють і поглиблюють функціональність. Ви можете знайти плагіни у <1>Сховищі плагінів. - filter: - all: Усі - active: Активні - inactive: Неактивні - outdated: Застарілі - plugins: - label: Плагіни - text: Виберіть наявний плагін. - name: Ім’я - version: Версія - status: Статус - action: Дія - deactivate: Деактивувати - activate: Активувати - settings: Налаштування - settings_users: - title: Користувачі - avatar: - label: Аватар за замовчуванням - text: Для користувачів без аватара власного. - gravatar_base_url: - label: Основна URL Gravatar - text: URL бази API постачальника Gravatar. Ігнорується, якщо порожній. - profile_editable: - title: Профіль можна редагувати - allow_update_display_name: - label: Дозволити користувачам змінювати ім'я для відображення - allow_update_username: - label: Дозволити користувачам змінювати своє ім'я користувача - allow_update_avatar: - label: Дозволити користувачам змінювати зображення свого профілю - allow_update_bio: - label: Дозволити користувачам змінювати дані про себе - allow_update_website: - label: Дозволити користувачам змінювати свій вебсайт - allow_update_location: - label: Дозволити користувачам змінювати своє місцеперебування - privilege: - title: Привілеї - level: - label: Рівень репутації необхідний - text: Виберіть репутацію, необхідну для привілеїв - msg: - should_be_number: введення має бути числом - number_larger_1: число має бути рівним або більшим за 1 - badges: - action: Дія - active: Активні - activate: Активувати - all: Усі - awards: Нагороди - deactivate: Деактивувати - filter: - placeholder: Фільтрувати за іменем, значок:id - group: Група - inactive: Неактивні - name: Ім’я - show_logs: Показати записи журналу - status: Статус - title: Значки - form: - optional: (необов'язково) - empty: не може бути порожнім - invalid: недійсне - btn_submit: Зберегти - not_found_props: "Необхідний параметр {{ key }} не знайдено." - select: Вибрати - page_review: - review: Огляд - proposed: запропоновано - question_edit: Редагування питання - answer_edit: Редагування відповіді - tag_edit: Редагування тегу - edit_summary: Редагувати звіт - edit_question: Редагувати питання - edit_answer: Редагувати відповідь - edit_tag: Редагувати тег - empty: Не залишилось завдань огляду. - approve_revision_tip: Ви схвалюєте цю редакцію? - approve_flag_tip: Ви схвалюєте цю відмітку? - approve_post_tip: Ви схвалюєте цей допис? - approve_user_tip: Ви схвалюєте цього користувача? - suggest_edits: Запропоновані зміни - flag_post: Відмітити публікацію - flag_user: Відмітити користувача - queued_post: Черговий допис - queued_user: Черговий користувач - filter_label: Тип - reputation: репутація - flag_post_type: Відмічено цей пост як {{ type }}. - flag_user_type: Відмічено цього користувача як {{ type }}. - edit_post: Редагувати допис - list_post: Додати допис до списку - unlist_post: Видалити допис зі списку - timeline: - undeleted: не видалений - deleted: видалений - downvote: голос "проти" - upvote: голос "за" - accept: прийняти - cancelled: скасовано - commented: прокоментовано - rollback: відкат назад - edited: відредаговано - answered: дано відповідь - asked: запитано - closed: закрито - reopened: знову відкрито - created: створено - pin: закріплено - unpin: відкріплено - show: додано до списку - hide: не внесено до списку - title: "Історія для" - tag_title: "Хронологія для" - show_votes: "Показати голоси" - n_or_a: Н/Д - title_for_question: "Хронологія для" - title_for_answer: "Часова шкала для відповіді на {{ title }} від {{ author }}" - title_for_tag: "Часова шкала для тега" - datetime: Дата й час - type: Тип - by: Від - comment: Коментар - no_data: "Ми не змогли нічого знайти." - users: - title: Користувачі - users_with_the_most_reputation: Користувачі з найвищою репутацією на цьому тижні - users_with_the_most_vote: Користувачі, які голосували за найбільше цього тижня - staffs: Персонал нашої спільноти - reputation: репутація - votes: голоси - prompt: - leave_page: Ви дійсно хочете покинути сторінку? - changes_not_save: Ваші зміни можуть не зберегтися. - draft: - discard_confirm: Ви дійсно бажаєте скасувати чернетку? - messages: - post_deleted: Цей допис було видалено. - post_cancel_deleted: Цей допис було не видалено. - post_pin: Цей допис було закріплено. - post_unpin: Цей допис було відкріплено. - post_hide_list: Цей допис було приховано зі списку. - post_show_list: Цей допис було показано у списку. - post_reopen: Цей допис було знову відкрито. - post_list: Цей допис було додано до списку. - post_unlist: Цей допис було приховано. - post_pending: Ваш допис очікує на розгляд. Це попередній перегляд, його буде видно після того, як його буде схвалено. - post_closed: Ця публікація була закрита. - answer_deleted: Ця відповідь була видалена. - answer_cancel_deleted: Ця відповідь була не видалена. - change_user_role: Роль цього користувача було змінено. - user_inactive: Цей користувач вже неактивний. - user_normal: Цей користувач вже нормальний. - user_suspended: Цього користувача було відсторонено. - user_deleted: Цього користувача було видалено. - badge_activated: Цей бейдж було активовано. - badge_inactivated: Цей бейдж було деактивовано. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/vi_VN.yaml b/data/i18n/vi_VN.yaml deleted file mode 100644 index d379c4930..000000000 --- a/data/i18n/vi_VN.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: Thành công. - unknown: - other: Lỗi không xác định. - request_format_error: - other: Định dạng yêu cầu không hợp lệ. - unauthorized_error: - other: Chưa được cấp quyền. - database_error: - other: Lỗi dữ liệu máy chủ. - forbidden_error: - other: Bị cấm. - duplicate_request_error: - other: Trùng lặp yêu cầu. - action: - report: - other: Gắn nhãn - edit: - other: Chỉnh sửa - delete: - other: Xóa - close: - other: Đóng - reopen: - other: Mở lại - forbidden_error: - other: Bị cấm. - pin: - other: Ghim - hide: - other: Gỡ bỏ khỏi danh sách - unpin: - other: Bỏ ghim - show: - other: Hiển thị - invite_someone_to_answer: - other: Chỉnh sửa - undelete: - other: Khôi phục - merge: - other: Merge - role: - name: - user: - other: Người dùng - admin: - other: Quản trị viên - moderator: - other: Người điều hành - description: - user: - other: Mặc định không có quyền truy cập đặc biệt. - admin: - other: Có toàn quyền truy cập vào trang. - moderator: - other: Có quyền truy cập vào tất cả bài viết trừ cài đặt quản trị. - privilege: - level_1: - description: - other: Cấp độ 1 (yêu cầu danh tiếng thấp cho nhóm riêng, nhóm) - level_2: - description: - other: Cấp độ 2 (yêu cầu danh tiếng cao cho cộng đồng đã phát triển) - level_3: - description: - other: Cấp độ 3 (yêu cầu danh tiếng cao cho cộng đồng đã phát triển) - level_custom: - description: - other: Cấp độ tùy chỉnh - rank_question_add_label: - other: Đặt câu hỏi - rank_answer_add_label: - other: Viết câu trả lời - rank_comment_add_label: - other: Viết bình luận - rank_report_add_label: - other: Gắn Cờ - rank_comment_vote_up_label: - other: Bình chọn lên cho bình luận - rank_link_url_limit_label: - other: Đăng nhiều hơn 2 liên kết cùng một lúc - rank_question_vote_up_label: - other: Bình chọn lên cho câu hỏi - rank_answer_vote_up_label: - other: Bình chọn lên cho câu trả lời - rank_question_vote_down_label: - other: Bình chọn xuống cho câu hỏi - rank_answer_vote_down_label: - other: Bình chọn xuống cho câu trả lời - rank_invite_someone_to_answer_label: - other: Mời ai đó trả lời - rank_tag_add_label: - other: Tạo thẻ mới - rank_tag_edit_label: - other: Chỉnh sửa mô tả thẻ (cần xem xét) - rank_question_edit_label: - other: Chỉnh sửa câu hỏi của người khác (cần xem xét) - rank_answer_edit_label: - other: Chỉnh sửa câu trả lời của người khác (cần xem xét) - rank_question_edit_without_review_label: - other: Chỉnh sửa câu hỏi của người khác không cần xem xét - rank_answer_edit_without_review_label: - other: Chỉnh sửa câu trả lời của người khác không cần xem xét - rank_question_audit_label: - other: Xem xét chỉnh sửa câu hỏi - rank_answer_audit_label: - other: Xem xét chỉnh sửa câu trả lời - rank_tag_audit_label: - other: Xem xét chỉnh sửa thẻ - rank_tag_edit_without_review_label: - other: Chỉnh sửa mô tả thẻ không cần xem xét - rank_tag_synonym_label: - other: Quản lý từ đồng nghĩa của thẻ - email: - other: Email - e_mail: - other: Email - password: - other: Mật khẩu - pass: - other: Mật khẩu - old_pass: - other: Current password - original_text: - other: Bài viết này - email_or_password_wrong_error: - other: Email và mật khẩu không trùng khớp. - error: - common: - invalid_url: - other: URL không tồn tại. - status_invalid: - other: Trạng thái không hợp lệ - password: - space_invalid: - other: Mật khẩu không thể tồn tại khoảng trắng. - admin: - cannot_update_their_password: - other: Bạn không thể thay đổi mật khẩu. - cannot_edit_their_profile: - other: Bạn không thể thay đổi hồ sơ. - cannot_modify_self_status: - other: Bạn không thể thay đổi trạng thái của mình. - email_or_password_wrong: - other: Email và mật khẩu không khớp. - answer: - not_found: - other: Không tìm thấy câu trả lời. - cannot_deleted: - other: Không có quyền xóa. - cannot_update: - other: Không có quyền cập nhật. - question_closed_cannot_add: - other: Câu hỏi đã đóng và không thể thêm. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: Không được phép chỉnh sửa bình luận. - not_found: - other: Không tìm thấy bình luận. - cannot_edit_after_deadline: - other: Thời gian bình luận đã quá lâu để chỉnh sửa. - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: Email đã được dùng. - need_to_be_verified: - other: Email cần được xác minh. - verify_url_expired: - other: URL xác minh email đã hết hạn, vui lòng gửi lại email. - illegal_email_domain_error: - other: Email không được phép từ miền email đó. Vui lòng sử dụng miền khác. - lang: - not_found: - other: Không tìm thấy file ngôn ngữ. - object: - captcha_verification_failed: - other: Xác minh Captcha thất bại. - disallow_follow: - other: Bạn không được phép theo dõi. - disallow_vote: - other: Bạn không được phép bỏ phiếu. - disallow_vote_your_self: - other: Bạn không thể bỏ phiếu cho bài đăng của chính mình. - not_found: - other: Đối tượng không tìm thấy. - verification_failed: - other: Xác thực không thành công. - email_or_password_incorrect: - other: Email và mật khẩu không trùng khớp. - old_password_verification_failed: - other: Xác minh mật khẩu cũ thất bại. - new_password_same_as_previous_setting: - other: Mật khẩu mới giống như cài đặt trước. - already_deleted: - other: Mật khẩu mới giống như cài đặt trước. - meta: - object_not_found: - other: Đối tượng không tìm thấy - question: - already_deleted: - other: Bài đăng này đã bị xóa. - under_review: - other: Bài đăng của bạn đang chờ xem xét. Nó sẽ hiển thị sau khi được phê duyệt. - not_found: - other: Không tìm thấy câu hỏi. - cannot_deleted: - other: Không có quyền xóa. - cannot_close: - other: Không có quyền đóng. - cannot_update: - other: Không có quyền cập nhật. - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Xếp hạng danh tiếng không đạt được điều kiện. - vote_fail_to_meet_the_condition: - other: Cảm ơn phản hồi của bạn. Bạn cần ít nhất {{.Rank}} danh tiếng để bỏ phiếu. - no_enough_rank_to_operate: - other: Bạn cần ít nhất {{.Rank}} danh tiếng để làm điều này. - report: - handle_failed: - other: Xử lý báo cáo thất bại. - not_found: - other: Không tìm thấy báo cáo. - tag: - already_exist: - other: Thẻ đã tồn tại. - not_found: - other: Không tìm thấy thẻ. - recommend_tag_not_found: - other: Thẻ đề xuất không tồn tại. - recommend_tag_enter: - other: Vui lòng nhập ít nhất một thẻ bắt buộc. - not_contain_synonym_tags: - other: Không nên chứa các thẻ đồng nghĩa. - cannot_update: - other: Không có quyền cập nhật. - is_used_cannot_delete: - other: Bạn không thể xóa thẻ đang được sử dụng. - cannot_set_synonym_as_itself: - other: Bạn không thể đặt từ đồng nghĩa của thẻ hiện tại là chính nó. - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: Tên người gửi không thể là địa chỉ email. - theme: - not_found: - other: Chủ đề không tìm thấy. - revision: - review_underway: - other: Không thể chỉnh sửa hiện tại, có một phiên bản đang trong hàng đợi xem xét. - no_permission: - other: Không có quyền sửa đổi. - user: - external_login_missing_user_id: - other: Nền tảng bên thứ ba không cung cấp UserID duy nhất, vì vậy bạn không thể đăng nhập, vui lòng liên hệ với quản trị viên trang web. - external_login_unbinding_forbidden: - other: Vui lòng đặt mật khẩu đăng nhập cho tài khoản của bạn trước khi bạn gỡ bỏ đăng nhập này. - email_or_password_wrong: - other: - other: Email và mật khẩu không khớp. - not_found: - other: Không tìm thấy người dùng. - suspended: - other: Người dùng đã bị đình chỉ. - username_invalid: - other: Tên người dùng không hợp lệ. - username_duplicate: - other: Tên người dùng đã được sử dụng. - set_avatar: - other: Thiết lập hình đại diện thất bại. - cannot_update_your_role: - other: Bạn không thể sửa đổi vai trò của mình. - not_allowed_registration: - other: Hiện tại trang không mở đăng ký. - not_allowed_login_via_password: - other: Hiện tại trang không cho phép đăng nhập qua mật khẩu. - access_denied: - other: Truy cập bị từ chối - page_access_denied: - other: Bạn không có quyền truy cập trang này. - add_bulk_users_format_error: - other: "Lỗi định dạng {{.Field}} gần '{{.Content}}' tại dòng {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "Số lượng người dùng bạn thêm cùng một lúc nên nằm trong khoảng từ 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: Đọc cấu hình thất bại - database: - connection_failed: - other: Kết nối cơ sở dữ liệu thất bại - create_table_failed: - other: Tạo bảng thất bại - install: - create_config_failed: - other: Không thể tạo file config.yaml. - upload: - unsupported_file_format: - other: Định dạng tệp không được hỗ trợ. - site_info: - config_not_found: - other: Không tìm thấy cấu hình trang. - badge: - object_not_found: - other: Đối tượng không tìm thấy - reason: - spam: - name: - other: thư rác - desc: - other: Bài đăng này quảng cáo hoặc phá hoại. Nó không hữu ích hoặc liên quan đến chủ đề hiện tại. - rude_or_abusive: - name: - other: thô lỗ hoặc lạm dụng - desc: - other: "Một người hợp lý sẽ thấy nội dung này không phù hợp để diễn thuyết một cách tôn trọng." - a_duplicate: - name: - other: một bản sao - desc: - other: Câu hỏi này đã được hỏi trước đó, đã có câu trả lời. - placeholder: - other: Nhập liên kết câu hỏi hiện tại - not_a_answer: - name: - other: không phải câu trả lời - desc: - other: "Điều này đã được đăng dưới dạng câu trả lời nhưng nó không cố gắng trả lời câu hỏi. Nó có thể là một bản chỉnh sửa, một nhận xét, một câu hỏi khác hoặc bị xóa hoàn toàn." - no_longer_needed: - name: - other: không còn cần thiết - desc: - other: Bình luận này đã lỗi thời, đối thoại hoặc không liên quan đến bài đăng này. - something: - name: - other: điều gì đó khác - desc: - other: Bài đăng này cần sự chú ý của nhân viên vì một lý do khác không được liệt kê ở trên. - placeholder: - other: Hãy cho chúng tôi biết cụ thể điều gì bạn quan tâm - community_specific: - name: - other: một lý do cụ thể của cộng đồng - desc: - other: Câu hỏi này không đáp ứng hướng dẫn của cộng đồng. - not_clarity: - name: - other: cần chi tiết hoặc rõ ràng - desc: - other: Câu hỏi này hiện bao gồm nhiều câu hỏi trong một. Nó nên tập trung vào một vấn đề duy nhất. - looks_ok: - name: - other: trông ổn - desc: - other: Bài đăng này tốt như vậy và không kém chất lượng. - needs_edit: - name: - other: cần chỉnh sửa, và tôi đã làm điều đó - desc: - other: Cải thiện và sửa các vấn đề với bài đăng này bằng chính bạn. - needs_close: - name: - other: cần đóng - desc: - other: Một câu hỏi đã đóng không thể trả lời, nhưng vẫn có thể chỉnh sửa, bỏ phiếu và bình luận. - needs_delete: - name: - other: cần xóa - desc: - other: Bài đăng này sẽ bị xóa. - question: - close: - duplicate: - name: - other: spam - desc: - other: Câu hỏi này đã được hỏi trước đó và đã có câu trả lời. - guideline: - name: - other: một lý do cụ thể của cộng đồng - desc: - other: Câu hỏi này không đáp ứng hướng dẫn của cộng đồng. - multiple: - name: - other: cần chi tiết hoặc rõ ràng - desc: - other: Câu hỏi này hiện bao gồm nhiều câu hỏi trong một. Nó chỉ nên tập trung vào một vấn đề. - other: - name: - other: điều gì đó khác - desc: - other: Bài đăng này cần một lý do khác không được liệt kê ở trên. - operation_type: - asked: - other: đã hỏi - answered: - other: đã trả lời - modified: - other: đã chỉnh sửa - deleted_title: - other: Câu hỏi đã xóa - questions_title: - other: Các câu hỏi - tag: - tags_title: - other: Thẻ - no_description: - other: Thẻ không có mô tả. - notification: - action: - update_question: - other: câu hỏi đã cập nhật - answer_the_question: - other: đã trả lời câu hỏi - update_answer: - other: câu trả lời đã cập nhật - accept_answer: - other: câu trả lời đã chấp nhận - comment_question: - other: đã bình luận câu hỏi - comment_answer: - other: đã bình luận câu trả lời - reply_to_you: - other: đã trả lời bạn - mention_you: - other: đã nhắc đến bạn - your_question_is_closed: - other: Câu hỏi của bạn đã được đóng - your_question_was_deleted: - other: Câu hỏi của bạn đã bị xóa - your_answer_was_deleted: - other: Câu trả lời của bạn đã bị xóa - your_comment_was_deleted: - other: Bình luận của bạn đã bị xóa - up_voted_question: - other: câu hỏi đã bình chọn lên - down_voted_question: - other: câu hỏi đã bình chọn xuống - up_voted_answer: - other: câu trả lời đã bình chọn lên - down_voted_answer: - other: câu trả lời đã bình chọn xuống - up_voted_comment: - other: bình luận đã bình chọn lên - invited_you_to_answer: - other: đã mời bạn trả lời - earned_badge: - other: Bạn đã nhận được huy hiệu "{{.BadgeName}}" - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Xác nhận địa chỉ email mới của bạn" - body: - other: "Xác nhận địa chỉ email mới của bạn cho {{.SiteName}} bằng cách nhấp vào liên kết sau:
        \n{{.ChangeEmailUrl}}

        \n\nNếu bạn không yêu cầu thay đổi này, vui lòng bỏ qua email này.

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời tin nhắn này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} đã trả lời câu hỏi của bạn" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nXem trên {{.SiteName}}

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời thư này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn.

        \n\nHủy đăng ký" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} mời bạn trả lời" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        Tôi nghĩ bạn có thể biết câu trả lời.

        \nXem trên {{.SiteName}}

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời thư này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn.

        \n\nHủy đăng ký" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} đã bình luận về bài đăng của bạn" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nXem trên {{.SiteName}}

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời thư này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn.

        \n\nHủy đăng ký" - new_question: - title: - other: "[{{.SiteName}}] Câu hỏi mới: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName}}] Đặt lại mật khẩu" - body: - other: "Ai đó đã yêu cầu đặt lại mật khẩu của bạn trên {{.SiteName}}.

        \n\nNếu người đó không phải là bạn thì bạn có thể yên tâm bỏ qua email này.

        \n\nNhấp vào liên kết sau để chọn mật khẩu mới:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời tin nhắn này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn." - register: - title: - other: "[{{.SiteName}}] Xác nhận tài khoản mới của bạn" - body: - other: "Chào mừng bạn đến với {{.SiteName}}!

        \n\nNhấp vào liên kết sau để xác nhận và kích hoạt tài khoản mới của bạn:
        \n{{.RegisterUrl}}

        \n\nNếu liên kết trên không nhấp vào được, hãy thử sao chép và dán nó vào thanh địa chỉ trình duyệt web của bạn.\n

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời tin nhắn này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn." - test: - title: - other: "[{{.SiteName}}] Email kiểm tra" - body: - other: "Đây là một email thử nghiệm.\n

        \n\n--
        \nLưu ý: Đây là email hệ thống tự động, vui lòng không trả lời tin nhắn này vì chúng tôi sẽ không nhìn thấy phản hồi của bạn." - action_activity_type: - upvote: - other: bình chọn lên - upvoted: - other: đã bình chọn lên - downvote: - other: bình chọn xuống - downvoted: - other: đã bình chọn xuống - accept: - other: chấp nhận - accepted: - other: đã chấp nhận - edit: - other: chỉnh sửa - review: - queued_post: - other: Bài đăng trong hàng đợi - flagged_post: - other: Bài đăng được đánh dấu - suggested_post_edit: - other: Đề xuất chỉnh sửa - reaction: - tooltip: - other: "{{ .Names }} và {{ .Count }} thêm..." - badge: - default_badges: - autobiographer: - name: - other: Tác giả tự truyện - desc: - other: Đã điền thông tin hồ sơ. - certified: - name: - other: Đã xác minh - desc: - other: Hoàn thành hướng dẫn cho người dùng mới của chúng tôi. - editor: - name: - other: Trình chỉnh sửa - desc: - other: Chỉnh sửa bài đăng đầu tiên. - first_flag: - name: - other: Cờ đầu tiên - desc: - other: Lần đầu tiên báo cáo một bài viết. - first_upvote: - name: - other: Lượt thích đầu tiên - desc: - other: Lần đầu tiên báo cáo một bài viết. - first_link: - name: - other: Liên kết đầu tiên - desc: - other: First added a link to another post. - first_reaction: - name: - other: Phản ứng đầu tiên - desc: - other: Phản ứng với bài viết đầu tiên. - first_share: - name: - other: Chia sẻ đầu tiên - desc: - other: Lần đầu chia sẻ một bài viết. - scholar: - name: - other: Học giả - desc: - other: Đặt một câu hỏi và chấp nhận một câu trả lời. - commentator: - name: - other: Bình luận viên - desc: - other: Để lại 5 bình luận. - new_user_of_the_month: - name: - other: Người dùng mới của tháng - desc: - other: Đóng góp nổi bật trong tháng đầu tiên của họ. - read_guidelines: - name: - other: Đọc hướng dẫn - desc: - other: Đọc [nguyên tắc cộng đồng]. - reader: - name: - other: Người đọc - desc: - other: Đọc mọi câu trả lời trong một chủ đề có hơn 10 câu trả lời. - welcome: - name: - other: Xin chào - desc: - other: Đã nhận được phiếu tán thành. - nice_share: - name: - other: Chia sẻ hay - desc: - other: Đã chia sẻ một bài đăng với 25 khách truy cập. - good_share: - name: - other: Chia sẻ tốt - desc: - other: Đã chia sẻ một bài đăng với 300 khách truy cập. - great_share: - name: - other: Chia sẻ tuyệt vời - desc: - other: Đã chia sẻ một bài đăng với 1000 khách truy cập. - out_of_love: - name: - other: Hết yêu thích - desc: - other: Đã sử dụng 50 phiếu bầu trong một ngày. - higher_love: - name: - other: Thích cao hơn - desc: - other: Đã sử dụng 50 phiếu bầu trong một ngày. - crazy_in_love: - name: - other: Thích điên cuồng - desc: - other: Đã sử dụng 50 phiếu bầu trong một ngày 20 lần. - promoter: - name: - other: Người quảng bá - desc: - other: Đã mời một người dùng. - campaigner: - name: - other: Chiến dịch - desc: - other: Đã mời 3 người dùng cơ bản. - champion: - name: - other: Vô địch - desc: - other: Mời 5 thành viên. - thank_you: - name: - other: Cảm ơn bạn - desc: - other: Có 20 bài đăng được bình chọn đưa ra 10 phiếu bầu. - gives_back: - name: - other: Trả lại - desc: - other: Có 100 bài đăng được bình chọn và đưa ra 100 phiếu bầu. - empathetic: - name: - other: Đồng cảm - desc: - other: Có 500 bài đăng được bình chọn đưa ra 1000 phiếu bầu. - enthusiast: - name: - other: Người nhiệt thành - desc: - other: Đã truy cập 10 ngày liên tiếp. - aficionado: - name: - other: Người hâm mộ - desc: - other: Đã truy cập 100 ngày liên tiếp. - devotee: - name: - other: Tín đồ - desc: - other: Đã truy cập 365 ngày liên tiếp. - anniversary: - name: - other: Kỉ niệm - desc: - other: Thành viên tích cực trong một năm, đăng ít nhất một lần. - appreciated: - name: - other: Đánh giá cao - desc: - other: Nhận được 1 lượt bình chọn cho 20 bài viết. - respected: - name: - other: Tôn trọng - desc: - other: Nhận được 2 lượt bình chọn cho 100 bài viết. - admired: - name: - other: Ngưỡng mộ - desc: - other: Nhận được 5 lượt bình chọn trên 300 bài đăng. - solved: - name: - other: Đã giải quyết - desc: - other: Có một câu trả lời được chấp nhận. - guidance_counsellor: - name: - other: Cố vấn hướng dẫn - desc: - other: Có 10 câu trả lời được chấp nhận. - know_it_all: - name: - other: Biết tất cả - desc: - other: Có 50 câu trả lời được chấp nhận. - solution_institution: - name: - other: Viện giải pháp - desc: - other: Có 150 câu trả lời được chấp nhận. - nice_answer: - name: - other: Câu trả lời tốt - desc: - other: Điểm trả lời từ 10 trở lên. - good_answer: - name: - other: Câu trả lời của bạn - desc: - other: Điểm trả lời từ 25 trở lên. - great_answer: - name: - other: Câu trả lời tuyệt vời - desc: - other: Điểm trả lời từ 50 trở lên. - nice_question: - name: - other: Câu trả lời tốt - desc: - other: Điểm trả lời từ 10 trở lên. - good_question: - name: - other: Câu trả lời tốt - desc: - other: Điểm trả lời từ 25 trở lên. - great_question: - name: - other: Câu trả lời tốt - desc: - other: Điểm trả lời từ 50 trở lên. - popular_question: - name: - other: Câu hỏi phổ biến - desc: - other: Câu hỏi với 500 lượt xem. - notable_question: - name: - other: Câu hỏi đáng chú ý - desc: - other: Câu hỏi với 1.000 lượt xem. - famous_question: - name: - other: Câu hỏi nổi tiếng - desc: - other: Câu hỏi với 5.000 lượt xem. - popular_link: - name: - other: Liên kết phổ biến - desc: - other: Đã đăng một liên kết bên ngoài với 50 lần nhấp chuột. - hot_link: - name: - other: Liên kết nổi bật - desc: - other: Đã đăng một liên kết bên ngoài với 300 lần nhấp chuột. - famous_link: - name: - other: Liên kết nổi tiếng - desc: - other: Đã đăng một liên kết bên ngoài với 100 lần nhấp chuột. - default_badge_groups: - getting_started: - name: - other: Bắt đầu - community: - name: - other: Cộng đồng - posting: - name: - other: Viết bài thảo luận -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: Cách định dạng - desc: >- -
        • đề cập đến bài đăng: #post_id

        • để tạo liên kết

          <https://url.com>

          [Title](https://url.com)
        • đặt trả về giữa đoạn văn

        • _italic_ hoặc **in đậm**

        • mã thụt lề 4 dấu cách

        • trích dẫn bằng cách đặt > ở đầu dòng

        • backtick thoát `like _this_`

        • tạo hàng rào mã bằng dấu backticks `

          ```
          mã vào đây
          ```
        - pagination: - prev: Trước - next: Tiếp - page_title: - question: Câu hỏi - questions: Các câu hỏi - tag: Thẻ - tags: Các thẻ - tag_wiki: wiki thẻ - create_tag: Tạo thẻ - edit_tag: Chỉnh sửa thẻ - ask_a_question: Create Question - edit_question: Chỉnh sửa câu hỏi - edit_answer: Chỉnh sửa câu - search: Tìm kiếm - posts_containing: Bài đăng chứa - settings: Cài đặt - notifications: Các thông báo - login: Đăng nhập - sign_up: Đăng ký - account_recovery: Khôi phục tài khoản - account_activation: Kích hoạt tài khoản - confirm_email: Xác nhận Email - account_suspended: Tài khoản bị đình chỉ - admin: Quản trị - change_email: Thay đổi Email - install: Cài đặt Answer - upgrade: Nâng cấp Answer - maintenance: Bảo trì trang web - users: Người dùng - oauth_callback: Đang xử lý - http_404: Lỗi HTTP 404 - http_50X: Lỗi HTTP 500 - http_403: Lỗi HTTP 403 - logout: Đăng xuất - posts: Posts - notifications: - title: Các thông báo - inbox: Hộp thư đến - achievement: Thành tích - new_alerts: Cảnh báo mới - all_read: Đánh dấu tất cả đã đọc - show_more: Xem thêm - someone: Ai đó - inbox_type: - all: Tất cả - posts: Bài đăng - invites: Lời mời - votes: Bình chọn - answer: Câu trả lời - question: Câu hỏi - badge_award: Huy hiệu - suspended: - title: Tài khoản của bạn đã bị đình chỉ - until_time: "Tài khoản của bạn đã bị đình chỉ cho đến {{ time }}." - forever: Người dùng này đã bị đình chỉ vĩnh viễn. - end: Bạn không tuân thủ hướng dẫn cộng đồng. - contact_us: Liên hệ với chúng tôi - editor: - blockquote: - text: Trích dẫn - bold: - text: Đậm - chart: - text: Biểu đồ - flow_chart: Biểu đồ luồng - sequence_diagram: Sơ đồ trình tự - class_diagram: Sơ đồ lớp - state_diagram: Sơ đồ trạng thái - entity_relationship_diagram: Sơ đồ quan hệ thực thể - user_defined_diagram: Sơ đồ do người dùng định nghĩa - gantt_chart: Biểu đồ Gantt - pie_chart: Biểu đồ tròn - code: - text: Mẫu code - add_code: Thêm code mẫu - form: - fields: - code: - label: Mã - msg: - empty: Mã không thể trống. - language: - label: Ngôn ngữ - placeholder: Phát hiện tự động - btn_cancel: Hủy - btn_confirm: Thêm - formula: - text: Công thức - options: - inline: Công thức nội dòng - block: Công thức khối - heading: - text: Tiêu đề - options: - h1: Tiêu đề 1 - h2: Tiêu đề 2 - h3: Tiêu đề 3 - h4: Tiêu đề 4 - h5: Tiêu đề 5 - h6: Tiêu đề 6 - help: - text: Trợ giúp - hr: - text: Thước ngang - image: - text: Hình ảnh - add_image: Thêm hình ảnh - tab_image: Tải Ảnh lên - form_image: - fields: - file: - label: Tệp hình ảnh - btn: Chọn hình ảnh - msg: - empty: Tệp không thể trống. - only_image: Chỉ cho phép tệp hình ảnh. - max_size: Kích thước tệp không được vượt quá {{size}} MB. - desc: - label: Mô tả - tab_url: URL hình ảnh - form_url: - fields: - url: - label: URL hình ảnh - msg: - empty: URL hình ảnh không thể trống. - name: - label: Mô tả - btn_cancel: Hủy - btn_confirm: Thêm - uploading: Đang tải lên - indent: - text: Canh lề - outdent: - text: Lùi lề - italic: - text: Nhấn mạnh - link: - text: Liên kết - add_link: Thêm liên kết - form: - fields: - url: - label: Đường link url - msg: - empty: URL không thể trống. - name: - label: Mô tả - btn_cancel: Hủy - btn_confirm: Thêm - ordered_list: - text: Danh sách đánh số - unordered_list: - text: Danh sách gạch đầu dòng - table: - text: Bảng - heading: Tiêu đề - cell: Ô - file: - text: Đính kèm tập tin - not_supported: "Không hỗ trợ loại tệp đó. Hãy thử lại với {{file_type}}." - max_size: "Kích thước tệp đính kèm không được vượt quá {{size}} MB." - close_modal: - title: Tôi đang đóng bài đăng này với lý do... - btn_cancel: Hủy - btn_submit: Gửi - remark: - empty: Không thể trống. - msg: - empty: Vui lòng chọn một lý do. - report_modal: - flag_title: Tôi đang đánh dấu để báo cáo bài đăng này với lý do... - close_title: Tôi đang đóng bài đăng này với lý do... - review_question_title: Xem xét câu hỏi - review_answer_title: Xem xét câu trả lời - review_comment_title: Xem xét bình luận - btn_cancel: Hủy - btn_submit: Gửi - remark: - empty: Không thể trống. - msg: - empty: Vui lòng chọn một lý do. - not_a_url: Định dạng URL không chính xác. - url_not_match: Nguồn gốc URL không khớp với trang web hiện tại. - tag_modal: - title: Tạo thẻ mới - form: - fields: - display_name: - label: Tên hiển thị - msg: - empty: Tên hiển thị không thể trống. - range: Tên hiển thị tối đa 35 ký tự. - slug_name: - label: Đường dẫn URL - desc: Đường dẫn tối đa 35 ký tự. - msg: - empty: Đường dẫn URL không thể trống. - range: Đường dẫn URL tối đa 35 ký tự. - character: Đường dẫn URL chứa bộ ký tự không được phép. - desc: - label: Mô tả - revision: - label: Sửa đổi - edit_summary: - label: Tóm tắt chỉnh sửa - placeholder: >- - Giải thích ngắn gọn các thay đổi của bạn (sửa chính tả, sửa ngữ pháp, cải thiện định dạng) - btn_cancel: Hủy - btn_submit: Gửi - btn_post: Đăng thẻ mới - tag_info: - created_at: Đã tạo - edited_at: Đã chỉnh sửa - history: Lịch sử - synonyms: - title: Từ đồng nghĩa - text: Các thẻ sau sẽ được ánh xạ lại thành - empty: Không tìm thấy từ đồng nghĩa. - btn_add: Thêm từ đồng nghĩa - btn_edit: Chỉnh sửa - btn_save: Lưu - synonyms_text: Các thẻ sau sẽ được ánh xạ lại thành - delete: - title: Xóa thẻ này - tip_with_posts: >- -

        Chúng tôi không cho phép xóa thẻ có bài đăng.

        Vui lòng xóa thẻ này khỏi các bài đăng trước.

        - tip_with_synonyms: >- -

        Chúng tôi không cho phép xóa thẻ có từ đồng nghĩa.

        Vui lòng xóa các từ đồng nghĩa khỏi thẻ này trước.

        - tip: Bạn có chắc chắn muốn xóa không? - close: Đóng - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: Submit - btn_close: Close - edit_tag: - title: Chỉnh sửa Thẻ - default_reason: Chỉnh sửa thẻ - default_first_reason: Thêm thẻ - btn_save_edits: Lưu chỉnh sửa - btn_cancel: Hủy - dates: - long_date: MMM D - long_date_with_year: "MMM D, YYYY" - long_date_with_time: "MMM D, YYYY [at] HH:mm" - now: bây giờ - x_seconds_ago: "{{count}}giây trước" - x_minutes_ago: "{{count}}phút trước" - x_hours_ago: "{{count}}giờ trước" - hour: giờ - day: ngày - hours: giờ - days: ngày - month: month - months: months - year: year - reaction: - heart: trái tim - smile: nụ cười - frown: nhăn mặt - btn_label: thêm hoặc loại bỏ phản ứng - undo_emoji: bỏ dấu {{ emoji }} phản ứng - react_emoji: biểu cảm với {{ emoji }} - unreact_emoji: hủy biểu cảm {{ emoji }} - comment: - btn_add_comment: Thêm bình luận - reply_to: Trả lời cho - btn_reply: Trả lời - btn_edit: Chỉnh sửa - btn_delete: Xóa - btn_flag: Gắn Cờ - btn_save_edits: Lưu chỉnh sửa - btn_cancel: Hủy - show_more: "{{count}} bình luận khác" - tip_question: >- - Sử dụng bình luận để yêu cầu thêm thông tin hoặc đề xuất cải tiến. Tránh trả lời câu hỏi trong bình luận. - tip_answer: >- - Sử dụng bình luận để trả lời cho người dùng khác hoặc thông báo cho họ về các thay đổi. Nếu bạn đang thêm thông tin mới, hãy chỉnh sửa bài đăng của mình thay vì bình luận. - tip_vote: Nó thêm điều gì đó hữu ích cho bài đăng - edit_answer: - title: Chỉnh sửa Câu trả lời - default_reason: Chỉnh sửa câu trả lời - default_first_reason: Thêm câu trả lời - form: - fields: - revision: - label: Sửa đổi - answer: - label: Câu trả lời - feedback: - characters: nội dung phải có ít nhất 6 ký tự. - edit_summary: - label: Tóm tắt chỉnh sửa - placeholder: >- - Giải thích ngắn gọn các thay đổi của bạn (sửa chính tả, sửa ngữ pháp, cải thiện định dạng) - btn_save_edits: Lưu chỉnh sửa - btn_cancel: Hủy - tags: - title: Thẻ - sort_buttons: - popular: Phổ biến - name: Tên - newest: Mới nhất - button_follow: Theo dõi - button_following: Đang theo dõi - tag_label: câu hỏi - search_placeholder: Lọc theo tên thẻ - no_desc: Thẻ không có mô tả. - more: Thêm - wiki: Wiki - ask: - title: Create Question - edit_title: Chỉnh sửa Câu hỏi - default_reason: Chỉnh sửa câu hỏi - default_first_reason: Create question - similar_questions: Câu hỏi tương tự - form: - fields: - revision: - label: Sửa đổi - title: - label: Tiêu đề - placeholder: What's your topic? Be specific. - msg: - empty: Tiêu đề không thể trống. - range: Tiêu đề tối đa 150 ký tự - body: - label: Nội dung - msg: - empty: Nội dung không thể trống. - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: Thẻ - msg: - empty: Thẻ không thể trống. - answer: - label: Câu trả lời - msg: - empty: Câu trả lời không thể trống. - edit_summary: - label: Tóm tắt chỉnh sửa - placeholder: >- - Giải thích ngắn gọn các thay đổi của bạn (sửa chính tả, sửa ngữ pháp, cải thiện định dạng) - btn_post_question: Đăng câu hỏi của bạn - btn_save_edits: Lưu chỉnh sửa - answer_question: Trả lời câu hỏi của chính bạn - post_question&answer: Đăng câu hỏi và câu trả lời của bạn - tag_selector: - add_btn: Thêm thẻ - create_btn: Tạo thẻ mới - search_tag: Tìm kiếm thẻ - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: Không có thẻ phù hợp - tag_required_text: Thẻ bắt buộc (ít nhất một) - header: - nav: - question: Câu hỏi - tag: Thẻ - user: Người dùng - badges: Danh hiệu - profile: Hồ sơ - setting: Cài đặt - logout: Đăng xuất - admin: Quản trị - review: Xem xét - bookmark: Đánh dấu - moderation: Điều hành - search: - placeholder: Tìm kiếm - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: Thay đổi - loading: đang tải... - pic_auth_code: - title: Mã xác minh - placeholder: Nhập văn bản ở trên - msg: - empty: Captcha không thể trống. - inactive: - first: >- - Bạn gần như đã hoàn tất! Chúng tôi đã gửi một email kích hoạt đến {{mail}}. Vui lòng làm theo hướng dẫn trong email để kích hoạt tài khoản của bạn. - info: "Nếu không nhận được, hãy kiểm tra thư mục spam của bạn." - another: >- - Chúng tôi đã gửi một email kích hoạt khác cho bạn tại {{mail}}. Có thể mất vài phút để nó đến; hãy chắc chắn kiểm tra thư mục thư rác của bạn. - btn_name: Gửi lại email kích hoạt - change_btn_name: Thay đổi email - msg: - empty: Không thể để trống mục này. - resend_email: - url_label: Bạn có chắc chắn muốn gửi lại email kích hoạt không? - url_text: Bạn cũng có thể cung cấp liên kết kích hoạt ở trên cho người dùng. - login: - login_to_continue: Đăng nhập để tiếp tục - info_sign: Bạn không có tài khoản? <1>Đăng ký - info_login: Bạn đã có tài khoản? <1>Đăng nhập - agreements: Bằng cách đăng ký, bạn đồng ý với <1>chính sách bảo mật và <3>điều khoản dịch vụ. - forgot_pass: Quên mật khẩu? - name: - label: Tên - msg: - empty: Tên không thể trống. - range: Tên phải có độ dài từ 2 đến 30 ký tự. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: Email - msg: - empty: Email không thể trống. - password: - label: Mật khẩu - msg: - empty: Mật khẩu không thể trống. - different: Mật khẩu nhập vào ở hai bên không nhất quán - account_forgot: - page_title: Quên mật khẩu - btn_name: Gửi email khôi phục cho tôi - send_success: >- - Nếu một tài khoản khớp với {{mail}}, bạn sẽ sớm nhận được một email với hướng dẫn về cách đặt lại mật khẩu của mình. - email: - label: Email - msg: - empty: Email không thể trống. - change_email: - btn_cancel: Hủy - btn_update: Cập nhật địa chỉ email - send_success: >- - Nếu một tài khoản khớp với {{mail}}, bạn sẽ sớm nhận được một email với hướng dẫn về cách đặt lại mật khẩu của mình. - email: - label: Email mới - msg: - empty: Email không thể trống. - oauth: - connect: Kết nối với {{ auth_name }} - remove: Xóa bỏ {{ auth_name }} - oauth_bind_email: - subtitle: Thêm email khôi phục vào tài khoản của bạn. - btn_update: Cập nhật địa chỉ email - email: - label: Email - msg: - empty: Email không thể trống. - modal_title: Email đã tồn tại. - modal_content: Địa chỉ email này đã được đăng ký. Bạn có chắc chắn muốn kết nối với tài khoản hiện tại không? - modal_cancel: Thay đổi email - modal_confirm: Kết nối với tài khoản hiện tại - password_reset: - page_title: Đặt lại mật khẩu - btn_name: Đặt lại mật khẩu của tôi - reset_success: >- - Bạn đã thay đổi mật khẩu thành công; bạn sẽ được chuyển hướng đến trang đăng nhập. - link_invalid: >- - Xin lỗi, liên kết đặt lại mật khẩu này không còn hợp lệ. Có thể mật khẩu của bạn đã được đặt lại? - to_login: Tiếp tục đến trang đăng nhập - password: - label: Mật khẩu - msg: - empty: Mật khẩu không thể trống. - length: Độ dài cần nằm trong khoảng từ 8 đến 32 - different: Mật khẩu nhập vào ở hai bên không nhất quán - password_confirm: - label: Xác nhận mật khẩu mới - settings: - page_title: Cài đặt - goto_modify: Đi đến sửa đổi - nav: - profile: Hồ sơ - notification: Thông báo - account: Tài khoản - interface: Giao diện - profile: - heading: Hồ sơ - btn_name: Lưu - display_name: - label: Tên hiển thị - msg: Tên hiển thị không thể trống. - msg_range: Display name must be 2-30 characters in length. - username: - label: Tên người dùng - caption: Mọi người có thể nhắc đến bạn với "@username". - msg: Tên người dùng không thể trống. - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Hình ảnh hồ sơ - gravatar: Gravatar - gravatar_text: Bạn có thể thay đổi hình ảnh trên - custom: Tùy chỉnh - custom_text: Bạn có thể tải lên hình ảnh của mình. - default: Hệ thống - msg: Vui lòng tải lên một hình đại diện - bio: - label: Giới thiệu về tôi - website: - label: Website - placeholder: "https://example.com" - msg: Định dạng website không chính xác - location: - label: Địa điểm - placeholder: "Thành phố, Quốc gia" - notification: - heading: Thông báo qua Email - turn_on: Bật - inbox: - label: Thông báo hộp thư đến - description: Các câu trả lời cho câu hỏi của bạn, bình luận, lời mời và nhiều hơn nữa. - all_new_question: - label: Tất cả câu hỏi mới - description: Nhận thông báo về tất cả các câu hỏi mới. Tối đa 50 câu hỏi mỗi tuần. - all_new_question_for_following_tags: - label: Tất cả câu hỏi mới cho các thẻ theo dõi - description: Nhận thông báo về các câu hỏi mới cho các thẻ đang theo dõi. - account: - heading: Tài khoản - change_email_btn: Thay đổi email - change_pass_btn: Thay đổi mật khẩu - change_email_info: >- - Chúng tôi đã gửi một email đến địa chỉ đó. Vui lòng làm theo hướng dẫn xác nhận. - email: - label: Email - new_email: - label: Email mới - msg: Email mới không được để trống. - pass: - label: Mật khẩu hiện tại - msg: Mật khẩu không thể trống. - password_title: Mật khẩu - current_pass: - label: Mật khẩu hiện tại - msg: - empty: Mật khẩu hiện tại không thể trống. - length: Độ dài cần nằm trong khoảng từ 8 đến 32. - different: Hai mật khẩu nhập vào không khớp. - new_pass: - label: Mật khẩu mới - pass_confirm: - label: Xác nhận mật khẩu mới - interface: - heading: Giao diện - lang: - label: Ngôn ngữ giao diện - text: Ngôn ngữ giao diện người dùng. Nó sẽ thay đổi khi bạn làm mới trang. - my_logins: - title: Đăng nhập của tôi - label: Đăng nhập hoặc đăng ký trên trang này bằng các tài khoản này. - modal_title: Xóa đăng nhập - modal_content: Bạn có chắc chắn muốn xóa đăng nhập này khỏi tài khoản của bạn không? - modal_confirm_btn: Xóa - remove_success: Đã xóa thành công - toast: - update: cập nhật thành công - update_password: Mật khẩu đã được thay đổi thành công. - flag_success: Cảm ơn bạn đã đánh dấu. - forbidden_operate_self: Không được phép thao tác trên chính mình - review: Sửa đổi của bạn sẽ được hiển thị sau khi được xem xét. - sent_success: Đã gửi thành công - related_question: - title: Related - answers: câu trả lời - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: Mời mọi người - desc: Mời những người bạn nghĩ có thể trả lời. - invite: Mời trả lời - add: Thêm người - search: Tìm kiếm người - question_detail: - action: Hành động - created: Created - Asked: Đã hỏi - asked: đã hỏi - update: Đã chỉnh sửa - Edited: Edited - edit: đã chỉnh sửa - commented: đã bình luận - Views: Lượt xem - Follow: Theo dõi - Following: Đang theo dõi - follow_tip: Theo dõi câu hỏi này để nhận thông báo - answered: đã trả lời - closed_in: Đóng trong - show_exist: Hiển thị câu hỏi hiện tại. - useful: Hữu ích - question_useful: Nó hữu ích và rõ ràng - question_un_useful: Nó không rõ ràng hoặc không hữu ích - question_bookmark: Đánh dấu câu hỏi này - answer_useful: Nó hữu ích - answer_un_useful: Nó không hữu ích - answers: - title: Các câu trả lời - score: Điểm - newest: Mới nhất - oldest: Cũ nhất - btn_accept: Chấp nhận - btn_accepted: Đã chấp nhận - write_answer: - title: Câu trả lời của bạn - edit_answer: Chỉnh sửa câu trả lời hiện tại của tôi - btn_name: Đăng câu trả lời của bạn - add_another_answer: Thêm câu trả lời khác - confirm_title: Tiếp tục trả lời - continue: Tiếp tục - confirm_info: >- -

        Bạn có chắc chắn muốn thêm một câu trả lời khác không?

        Bạn có thể sử dụng liên kết chỉnh sửa để tinh chỉnh và cải thiện câu trả lời hiện tại của mình, thay vì.

        - empty: Câu trả lời không thể trống. - characters: nội dung phải có ít nhất 6 ký tự. - tips: - header_1: Cảm ơn câu trả lời của bạn - li1_1: Vui lòng chắc chắn trả lời câu hỏi. Cung cấp chi tiết và chia sẻ nghiên cứu của bạn. - li1_2: Hỗ trợ bất kỳ tuyên bố nào bạn đưa ra với tài liệu tham khảo hoặc kinh nghiệm cá nhân. - header_2: Nhưng tránh ... - li2_1: Yêu cầu trợ giúp, yêu cầu làm rõ, hoặc trả lời cho các câu trả lời khác. - reopen: - confirm_btn: Mở lại - title: Mở lại bài đăng này - content: Bạn có chắc chắn muốn mở lại không? - list: - confirm_btn: Danh sách - title: Danh sách bài đăng này - content: Bạn có chắc chắn muốn liệt kê không? - unlist: - confirm_btn: Gỡ bỏ khỏi danh sách - title: Gỡ bỏ bài đăng này khỏi danh sách - content: Bạn có chắc chắn muốn gỡ bỏ không? - pin: - title: Ghim bài đăng này - content: Bạn có chắc chắn muốn ghim toàn cầu không? Bài đăng này sẽ xuất hiện ở đầu tất cả các danh sách bài đăng. - confirm_btn: Ghim - delete: - title: Xóa bài đăng này - question: >- - Chúng tôi không khuyến khích xóa câu hỏi có câu trả lời vì làm như vậy sẽ tước đoạt kiến thức của độc giả trong tương lai.

        Việc xóa liên tục các câu hỏi đã được trả lời có thể dẫn đến việc tài khoản của bạn bị chặn không được phép hỏi. Bạn có chắc chắn muốn xóa không? - answer_accepted: >- -

        Chúng tôi không khuyến khích xóa câu trả lời đã được chấp nhận vì làm như vậy sẽ tước đoạt kiến thức của độc giả trong tương lai.

        Việc xóa liên tục các câu trả lời đã được chấp nhận có thể dẫn đến việc tài khoản của bạn bị chặn không được phép trả lời. Bạn có chắc chắn muốn xóa không? - other: Bạn có chắc chắn muốn xóa không? - tip_answer_deleted: Câu trả lời này đã bị xóa - undelete_title: Khôi phục bài đăng này - undelete_desc: Bạn có chắc chắn muốn khôi phục không? - btns: - confirm: Xác nhận - cancel: Hủy - edit: Chỉnh sửa - save: Lưu - delete: Xóa - undelete: Khôi phục - list: Danh sách - unlist: Gỡ bỏ khỏi danh sách - unlisted: Không được liệt kê - login: Đăng nhập - signup: Đăng ký - logout: Đăng xuất - verify: Xác minh - create: Create - approve: Phê duyệt - reject: Từ chối - skip: Bỏ qua - discard_draft: Hủy bản nháp - pinned: Đã ghim - all: Tất cả - question: Câu hỏi - answer: Câu trả lời - comment: Bình luận - refresh: Làm mới - resend: Gửi lại - deactivate: Ngừng kích hoạt - active: Hoạt động - suspend: Tạm ngừng - unsuspend: Bỏ vô hiệu hóa - close: Đóng - reopen: Mở lại - ok: Đồng ý - light: Phông nền sáng - dark: Tối - system_setting: Cài đặt hệ thống - default: Mặc định - reset: Đặt lại - tag: Thẻ - post_lowercase: bài đăng - filter: Lọc - ignore: Bỏ qua - submit: Gửi - normal: Bình thường - closed: Đã đóng - deleted: Đã xóa - deleted_permanently: Deleted permanently - pending: Đang chờ xử lý - more: Thêm - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: Kết quả tìm kiếm - keywords: Từ khóa - options: Tùy chọn - follow: Theo dõi - following: Đang theo dõi - counts: "{{count}} Kết quả" - counts_loading: "... Results" - more: Thêm - sort_btns: - relevance: Liên quan - newest: Mới nhất - active: Hoạt động - score: Điểm - more: Thêm - tips: - title: Mẹo tìm kiếm nâng cao - tag: "<1>[tag] tìm kiếm trong một thẻ" - user: "<1>user:username tìm kiếm theo tác giả" - answer: "<1>answers:0 câu hỏi chưa có câu trả lời" - score: "<1>score:3 bài đăng có điểm 3+" - question: "<1>is:question tìm kiếm câu hỏi" - is_answer: "<1>is:answer tìm kiếm câu trả lời" - empty: Chúng tôi không thể tìm thấy bất cứ thứ gì.
        Thử các từ khóa khác hoặc ít cụ thể hơn. - share: - name: Chia sẻ - copy: Sao chép liên kết - via: Chia sẻ bài đăng qua... - copied: Đã sao chép - facebook: Chia sẻ lên Facebook - twitter: Share to X - cannot_vote_for_self: Bạn không thể bỏ phiếu cho bài đăng của chính mình. - modal_confirm: - title: Lỗi... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: Tài khoản mới của bạn đã được xác nhận; bạn sẽ được chuyển hướng đến trang chủ. - link: Tiếp tục đến trang chủ - oops: Rất tiếc! - invalid: Liên kết bạn đã dùng không còn hoạt động nữa. - confirm_new_email: Email của bạn đã được cập nhật. - confirm_new_email_invalid: >- - Xin lỗi, liên kết xác nhận này không còn hợp lệ. Có thể email của bạn đã được thay đổi? - unsubscribe: - page_title: Hủy đăng ký - success_title: Hủy đăng ký thành công - success_desc: Bạn đã được gỡ bỏ khỏi danh sách người đăng ký này và sẽ không nhận được thêm email từ chúng tôi. - link: Thay đổi cài đặt - question: - following_tags: Thẻ đang theo dõi - edit: Chỉnh sửa - save: Lưu - follow_tag_tip: Theo dõi các thẻ để tùy chỉnh danh sách câu hỏi của bạn. - hot_questions: Câu hỏi nổi bật - all_questions: Tất cả câu hỏi - x_questions: "{{ count }} Câu hỏi" - x_answers: "{{ count }} câu trả lời" - x_posts: "{{ count }} Posts" - questions: Câu hỏi - answers: Câu trả lời - newest: Mới nhất - active: Hoạt động - hot: Được nhiều quan tâm - frequent: Thường xuyên - recommend: Đề xuất - score: Điểm - unanswered: Chưa được trả lời - modified: đã chỉnh sửa - answered: đã trả lời - asked: đã hỏi - closed: đã đóng - follow_a_tag: Theo dõi một thẻ - more: Thêm - personal: - overview: Tổng quan - answers: Câu trả lời - answer: câu trả lời - questions: Câu hỏi - question: câu hỏi - bookmarks: Đánh dấu - reputation: Danh tiếng - comments: Bình luận - votes: Bình chọn - badges: Danh hiệu - newest: Mới nhất - score: Điểm - edit_profile: Chỉnh sửa hồ sơ - visited_x_days: "Đã truy cập {{ count }} ngày" - viewed: Đã xem - joined: Tham gia - comma: "," - last_login: Đã xem - about_me: Về tôi - about_me_empty: "// Xin chào, Thế giới !" - top_answers: Câu trả lời hàng đầu - top_questions: Câu hỏi hàng đầu - stats: Thống kê - list_empty: Không tìm thấy bài đăng.
        Có thể bạn muốn chọn một thẻ khác? - content_empty: Không tìm thấy bài viết nào. - accepted: Đã chấp nhận - answered: đã trả lời - asked: đã hỏi - downvoted: đã bỏ phiếu xuống - mod_short: MOD - mod_long: Người điều hành - x_reputation: danh tiếng - x_votes: phiếu bầu nhận được - x_answers: câu trả lời - x_questions: câu hỏi - recent_badges: Huy hiệu gần đây - install: - title: Cài đặt - next: Tiếp theo - done: Hoàn thành - config_yaml_error: Không thể tạo file config.yaml. - lang: - label: Vui lòng chọn một ngôn ngữ - db_type: - label: Hệ quản trị cơ sở dữ liệu - db_username: - label: Tên người dùng - placeholder: root - msg: Tên người dùng không thể trống. - db_password: - label: Mật khẩu - placeholder: root - msg: Mật khẩu không thể trống. - db_host: - label: Máy chủ cơ sở dữ liệu - placeholder: "db:3306" - msg: Máy chủ cơ sở dữ liệu không thể trống. - db_name: - label: Tên cơ sở dữ liệu - placeholder: câu trả lời - msg: Tên cơ sở dữ liệu không thể trống. - db_file: - label: Tệp tin Database - placeholder: /data/answer.db - msg: Tệp cơ sở dữ liệu không thể trống. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: Tạo config.yaml - label: Tệp config.yaml đã được tạo. - desc: >- - Bạn có thể tạo tệp <1>config.yaml thủ công trong thư mục <1>/var/wwww/xxx/ và dán văn bản sau vào đó. - info: Sau khi bạn đã làm xong, nhấp vào nút "Tiếp theo". - site_information: Thông tin trang - admin_account: Tài khoản quản trị - site_name: - label: Tên trang - msg: Tên trang không thể trống. - msg_max_length: Tên trang phải có tối đa 30 ký tự. - site_url: - label: URL trang - text: Địa chỉ của trang của bạn. - msg: - empty: URL trang không thể trống. - incorrect: Định dạng URL trang không chính xác. - max_length: URL trang phải có tối đa 512 ký tự. - contact_email: - label: Email liên hệ - text: Địa chỉ email của người liên hệ chính phụ trách trang này. - msg: - empty: Email liên hệ không thể trống. - incorrect: Định dạng email liên hệ không chính xác. - login_required: - label: Riêng tư - switch: Yêu cầu đăng nhập - text: Chỉ người dùng đã đăng nhập mới có thể truy cập cộng đồng này. - admin_name: - label: Tên - msg: Tên không thể trống. - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: Mật khẩu - text: >- - Bạn sẽ cần mật khẩu này để đăng nhập. Vui lòng lưu trữ nó ở một nơi an toàn. - msg: Mật khẩu không thể trống. - msg_min_length: Mật khẩu phải có ít nhất 8 ký tự. - msg_max_length: Mật khẩu phải có tối đa 32 ký tự. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: Email - text: Bạn sẽ cần email này để đăng nhập. - msg: - empty: Email không thể trống. - incorrect: Định dạng email không chính xác. - ready_title: Trang web của bạn đã sẵn sàng - ready_desc: >- - Nếu bạn cảm thấy muốn thay đổi thêm cài đặt nào đó, hãy truy cập <1>mục quản trị; tìm nó trong menu trang. - good_luck: "Chúc bạn vui vẻ và may mắn!" - warn_title: Cảnh báo - warn_desc: >- - Tệp <1>config.yaml đã tồn tại. Nếu bạn cần đặt lại bất kỳ mục cấu hình nào trong tệp này, vui lòng xóa nó trước. - install_now: Bạn có thể thử <1>cài đặt ngay bây giờ. - installed: Đã cài đặt - installed_desc: >- - Có vẻ như bạn đã cài đặt rồi. Để cài đặt lại, vui lòng xóa các bảng cơ sở dữ liệu cũ trước. - db_failed: Kết nối cơ sở dữ liệu thất bại - db_failed_desc: >- - Điều này có thể có nghĩa là thông tin cơ sở dữ liệu trong tệp <1>config.yaml của bạn không chính xác hoặc không thể thiết lập liên lạc với máy chủ cơ sở dữ liệu. Điều này có thể có nghĩa là máy chủ cơ sở dữ liệu của máy chủ của bạn đang bị tắt. - counts: - views: lượt xem - votes: bình chọn - answers: câu trả lời - accepted: Đã chấp nhận - page_error: - http_error: Lỗi HTTP {{ code }} - desc_403: Bạn không có quyền truy cập trang này. - desc_404: Thật không may, trang này không tồn tại. - desc_50X: Máy chủ đã gặp sự cố và không thể hoàn thành yêu cầu của bạn. - back_home: Quay lại trang chủ - page_maintenance: - desc: "Chúng tôi đang bảo trì, chúng tôi sẽ trở lại sớm." - nav_menus: - dashboard: Bảng điều khiển - contents: Nội dung - questions: Câu hỏi - answers: Câu trả lời - users: Người dùng - badges: Huy hiệu - flags: Cờ - settings: Cài đặt - general: Chung - interface: Giao diện - smtp: SMTP - branding: Thương hiệu - legal: Pháp lý - write: Viết - terms: Terms - tos: Điều khoản dịch vụ - privacy: Quyền riêng tư - seo: SEO - customize: Tùy chỉnh - themes: Chủ đề - login: Đăng nhập - privileges: Đặc quyền - plugins: Plugins - installed_plugins: Plugin đã cài đặt - apperance: Appearance - website_welcome: Chào mừng bạn đến với {{site_name}} - user_center: - login: Đăng nhập - qrcode_login_tip: Vui lòng sử dụng {{ agentName }} để quét mã QR và đăng nhập. - login_failed_email_tip: Đăng nhập thất bại, vui lòng cho phép ứng dụng này truy cập thông tin email của bạn trước khi thử lại. - badges: - modal: - title: Chúc mừng - content: Bạn đã nhận được huy hiệu mới. - close: Đóng - confirm: Xem huy hiệu - title: Huy hiệu - awarded: Giải Thưởng - earned_×: Nhận được ×{{ number }} - ×_awarded: "{{ number }} được trao tặng" - can_earn_multiple: Bạn có thể kiếm được nhiều lần. - earned: Đã nhận - admin: - admin_header: - title: Quản trị - dashboard: - title: Bảng điều khiển - welcome: Chào mừng bạn đến với Answer Admin! - site_statistics: Thống kê trang - questions: "Câu hỏi:" - resolved: "Đã giải quyết:" - unanswered: "Chưa được trả lời:" - answers: "Câu trả lời:" - comments: "Bình luận:" - votes: "Phiếu bầu:" - users: "Người dùng:" - flags: "Cờ:" - reviews: "Đánh giá:" - site_health: Sức khỏe trang - version: "Phiên bản:" - https: "HTTPS:" - upload_folder: "Thư mục tải lên:" - run_mode: "Chế độ hoạt động:" - private: Riêng tư - public: Công cộng - smtp: "SMTP:" - timezone: "Múi giờ:" - system_info: Thông tin hệ thống - go_version: "Phiên bản Go:" - database: "Database:" - database_size: "Tệp tin Database:" - storage_used: "Bộ nhớ đã sử dụng:" - uptime: "Thời gian hoạt động:" - links: Links - plugins: Plugin - github: GitHub - blog: Blog - contact: Liên hệ - forum: Diễn đàn - documents: Tài liệu - feedback: Phản hồi - support: Hỗ trợ - review: Đánh giá - config: Cấu hình - update_to: Cập nhật lên - latest: Mới nhất - check_failed: Kiểm tra thất bại - "yes": "Có" - "no": "Không" - not_allowed: Không được phép - allowed: Được phép - enabled: Đã bật - disabled: Đã tắt - writable: Có thể chỉnh sửa - not_writable: Không thể ghi - flags: - title: Cờ - pending: Đang chờ xử lý - completed: Hoàn thành - flagged: Đã đánh dấu - flagged_type: Đã đánh dấu {{ type }} - created: Đã tạo - action: Hành động - review: Đánh giá - user_role_modal: - title: Thay đổi vai trò người dùng thành... - btn_cancel: Hủy - btn_submit: Gửi - new_password_modal: - title: Đặt mật khẩu mới - form: - fields: - password: - label: Mật khẩu - text: Người dùng sẽ bị đăng xuất và cần đăng nhập lại. - msg: Mật khẩu phải có độ dài từ 8 đến 32 ký tự. - btn_cancel: Hủy - btn_submit: Gửi - edit_profile_modal: - title: Chỉnh sửa hồ sơ - form: - fields: - display_name: - label: Tên hiển thị - msg_range: Display name must be 2-30 characters in length. - username: - label: Tên người dùng - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Địa chỉ email không hợp lệ. - edit_success: Chỉnh Sửa Thành Công - btn_cancel: Hủy - btn_submit: Gửi - user_modal: - title: Thêm người dùng mới - form: - fields: - users: - label: Thêm người dùng hàng loạt - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Tách "tên, email, mật khẩu" bằng dấu phẩy. Một người dùng mỗi dòng. - msg: "Vui lòng nhập email của người dùng, một dòng mỗi người." - display_name: - label: Tên hiển thị - msg: Tên hiển thị phải dài từ 2-30 ký tự. - email: - label: Email - msg: Email không hợp lệ. - password: - label: Mật khẩu - msg: Mật khẩu phải có từ 8 đến 32 ký tự. - btn_cancel: Hủy - btn_submit: Gửi - users: - title: Người dùng - name: Tên - email: Email - reputation: Danh tiếng - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: Trạng thái - role: Vai trò - action: Hành động - change: Thay đổi - all: Tất cả - staff: Nhân viên - more: Thêm - inactive: Không hoạt động - suspended: Bị tạm ngưng - deleted: Đã xóa - normal: Bình thường - Moderator: Người điều hành - Admin: Quản trị viên - User: Người dùng - filter: - placeholder: "Lọc theo tên, user:id" - set_new_password: Đặt mật khẩu mới - edit_profile: Chỉnh sửa hồ sơ - change_status: Thay đổi trạng thái - change_role: Thay đổi vai trò - show_logs: Hiển thị nhật ký - add_user: Thêm người dùng - deactivate_user: - title: Ngừng kích hoạt người dùng - content: Người dùng không hoạt động phải xác nhận lại email của họ. - delete_user: - title: Xóa người dùng này - content: Bạn có chắc chắn muốn xóa người dùng này không? Điều này là vĩnh viễn! - remove: Xóa nội dung của họ - label: Xóa tất cả các câu hỏi, câu trả lời, bình luận, vv. - text: Không chọn điều này nếu bạn chỉ muốn xóa tài khoản của người dùng. - suspend_user: - title: Đình chỉ người dùng này - content: Người dùng bị đình chỉ không thể đăng nhập. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: Câu hỏi - unlisted: Không được liệt kê - post: Bài đăng - votes: Phiếu bầu - answers: Câu trả lời - created: Đã tạo - status: Trạng thái - action: Hành động - change: Thay đổi - pending: Đang chờ xử lý - filter: - placeholder: "Lọc theo tiêu đề, question:id" - answers: - page_title: Câu trả lời - post: Bài đăng - votes: Phiếu bầu - created: Đã tạo - status: Trạng thái - action: Hành động - change: Thay đổi - filter: - placeholder: "Lọc theo tiêu đề, answer:id" - general: - page_title: Chung - name: - label: Tên trang - msg: Tên trang không thể trống. - text: "Tên của trang này, được sử dụng trong thẻ tiêu đề." - site_url: - label: URL trang - msg: Url trang không thể trống. - validate: Vui lòng nhập URL hợp lệ. - text: Địa chỉ của trang của bạn. - short_desc: - label: Mô tả ngắn của trang - msg: Mô tả ngắn của trang không thể trống. - text: "Mô tả ngắn, được sử dụng trong thẻ tiêu đề trên trang chủ." - desc: - label: Mô tả trang - msg: Mô tả trang không thể trống. - text: "Mô tả trang này trong một câu, được sử dụng trong thẻ mô tả meta." - contact_email: - label: Email liên hệ - msg: Email liên hệ không thể trống. - validate: Định dạng email liên hệ không hợp lệ. - text: Địa chỉ email của người liên hệ chính phụ trách trang này. - check_update: - label: Cập nhật phần mềm - text: Tự động kiểm tra cập nhật - interface: - page_title: Giao diện - language: - label: Ngôn ngữ giao diện - msg: Ngôn ngữ giao diện không thể trống. - text: Ngôn ngữ giao diện người dùng. Nó sẽ thay đổi khi bạn làm mới trang. - time_zone: - label: Múi giờ - msg: Múi giờ không thể trống. - text: Chọn một thành phố cùng múi giờ với bạn. - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: Email gửi từ - msg: Email gửi từ không thể trống. - text: Địa chỉ email mà các email được gửi từ đó. - from_name: - label: Tên gửi từ - msg: Tên gửi từ không thể trống. - text: Tên mà các email được gửi từ đó. - smtp_host: - label: Máy chủ SMTP - msg: Máy chủ SMTP không thể trống. - text: Máy chủ thư của bạn. - encryption: - label: Mã hóa - msg: Mã hóa không thể trống. - text: Đối với hầu hết các máy chủ, SSL là tùy chọn được khuyến nghị. - ssl: SSL - tls: TLS - none: Không - smtp_port: - label: Cổng SMTP - msg: Cổng SMTP phải là số từ 1 đến 65535. - text: Cổng đến máy chủ thư của bạn. - smtp_username: - label: Tên người dùng SMTP - msg: Tên người dùng SMTP không thể trống. - smtp_password: - label: Mật khẩu SMTP - msg: Mật khẩu SMTP không thể trống. - test_email_recipient: - label: Người nhận email kiểm tra - text: Cung cấp địa chỉ email sẽ nhận email kiểm tra. - msg: Người nhận email kiểm tra không hợp lệ - smtp_authentication: - label: Bật xác thực - title: Xác thực SMTP - msg: Xác thực SMTP không thể trống. - "yes": "Có" - "no": "Không" - branding: - page_title: Thương hiệu - logo: - label: Logo - msg: Logo không thể trống. - text: Hình ảnh logo ở góc trên bên trái của trang của bạn. Sử dụng hình ảnh hình chữ nhật rộng với chiều cao 56 và tỷ lệ khung hình lớn hơn 3:1. Nếu để trống, văn bản tiêu đề trang sẽ được hiển thị. - mobile_logo: - label: Logo di động - text: Logo được sử dụng trên phiên bản di động của trang của bạn. Sử dụng hình ảnh hình chữ nhật rộng với chiều cao 56. Nếu để trống, hình ảnh từ cài đặt "logo" sẽ được sử dụng. - square_icon: - label: Biểu tượng vuông - msg: Biểu tượng vuông không thể trống. - text: Hình ảnh được sử dụng làm cơ sở cho các biểu tượng siêu dữ liệu. Nên lớn hơn 512x512. - favicon: - label: Favicon - text: Favicon cho trang của bạn. Để hoạt động chính xác trên một CDN, nó phải là png. Sẽ được thay đổi kích thước thành 32x32. Nếu để trống, "biểu tượng vuông" sẽ được sử dụng. - legal: - page_title: Pháp lý - terms_of_service: - label: Điều khoản dịch vụ - text: "Bạn có thể thêm nội dung điều khoản dịch vụ ở đây. Nếu bạn đã có một tài liệu được lưu trữ ở nơi khác, cung cấp URL đầy đủ ở đây." - privacy_policy: - label: Chính sách bảo mật - text: "Bạn có thể thêm nội dung chính sách bảo mật ở đây. Nếu bạn đã có một tài liệu được lưu trữ ở nơi khác, cung cấp URL đầy đủ ở đây." - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: Viết - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Câu trả lời chỉnh sửa - label: Each user can only write one answer for each question - text: "Tắt để cho phép người dùng viết nhiều câu trả lời cho cùng một câu hỏi, điều này có thể khiến các câu trả lời bị mất trọng tâm." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Thẻ được đề xuất - text: "Các thẻ gợi ý sẽ hiển thị trong danh sách thả xuống theo mặc định." - msg: - contain_reserved: "các thẻ được đề xuất không được chứa thẻ dự bị" - required_tag: - title: Đặt thẻ cần thiết - label: Đặt thẻ được đề xuất là bắt buộc - text: "Mỗi câu hỏi mới phải có ít nhất một thẻ được đề xuất." - reserved_tags: - label: Thẻ dành riêng - text: "Thẻ dành riêng chỉ có thể được thêm vào một bài đăng bởi điều hành viên." - image_size: - label: Kích thước hình ảnh tối đa (MB) - text: "Kích thước tải lên hình ảnh tối đa." - attachment_size: - label: Kích thước tệp đính kèm tối đa (MB) - text: "Kích thước tải lên tệp đính kèm tối đa." - image_megapixels: - label: Megapixel hình ảnh tối đa - text: "Số megapixel tối đa được phép cho một hình ảnh." - image_extensions: - label: Tiện ích mở rộng hình ảnh được ủy quyền - text: "Danh sách đuôi file được phép hiển thị hình ảnh, phân cách bằng dấu phẩy." - attachment_extensions: - label: Các loại tệp đính kèm được phép tải lên - text: "Danh sách các đuôi file được phép tải lên, phân cách bằng dấu phẩy. CẢNH BÁO: Cho phép tải lên có thể gây ra vấn đề bảo mật." - seo: - page_title: SEO - permalink: - label: Liên kết cố định - text: Cấu trúc URL tùy chỉnh có thể cải thiện khả năng sử dụng và khả năng tương thích về sau của liên kết của bạn. - robots: - label: robots.txt - text: Điều này sẽ ghi đè vĩnh viễn bất kỳ cài đặt trang web liên quan nào. - themes: - page_title: Giao diện - themes: - label: Giao diện - text: Chọn một chủ đề hiện có. - color_scheme: - label: Sơ đồ màu - navbar_style: - label: Navbar background style - primary_color: - label: Màu chính - text: Thay đổi các màu sắc được sử dụng bởi chủ đề của bạn - css_and_html: - page_title: CSS và HTML - custom_css: - label: CSS tùy chỉnh - text: > - - head: - label: Đầu - text: > - - header: - label: Đầu trang - text: > - - footer: - label: Cuối trang - text: Điều này sẽ chèn trước </body>. - sidebar: - label: Thanh bên - text: Điều này sẽ chèn vào thanh bên. - login: - page_title: Đăng nhập - membership: - title: Thành viên - label: Cho phép đăng ký mới - text: Tắt để ngăn ai đó tạo tài khoản mới. - email_registration: - title: Đăng ký qua email - label: Cho phép đăng ký qua email - text: Tắt để ngăn ai đó tạo tài khoản mới thông qua email. - allowed_email_domains: - title: Miền email được phép - text: Miền email mà người dùng phải đăng ký tài khoản. Một miền mỗi dòng. Bỏ qua khi trống. - private: - title: Riêng tư - label: Yêu cầu đăng nhập - text: Chỉ người dùng đã đăng nhập mới có thể truy cập cộng đồng này. - password_login: - title: Đăng nhập bằng mật khẩu - label: Cho phép đăng nhập bằng email và mật khẩu - text: "CẢNH BÁO: Nếu tắt, bạn có thể không thể đăng nhập nếu bạn chưa cấu hình phương thức đăng nhập khác trước đó." - installed_plugins: - title: Plugin đã cài đặt - plugin_link: Plugin mở rộng và mở rộng chức năng của trang web. Bạn có thể tìm thấy plugin trong <1>Kho Plugin Answer. - filter: - all: Tất cả - active: Đang hoạt động - inactive: Không hoạt động - outdated: Quá hạn - plugins: - label: Plugin - text: Chọn một plugin hiện có. - name: Tên - version: Phiên bản - status: Trạng thái - action: Hành động - deactivate: Vô hiệu hóa - activate: Kích hoạt - settings: Cài đặt - settings_users: - title: Người dùng - avatar: - label: Hình đại diện mặc định - text: Dành cho người dùng không có hình đại diện tùy chỉnh của riêng họ. - gravatar_base_url: - label: Gravatar Base URL - text: URL của nhà cung cấp API Gravatar. Bỏ qua khi trống. - profile_editable: - title: Hồ sơ có thể chỉnh sửa - allow_update_display_name: - label: Cho phép người dùng thay đổi tên hiển thị của họ - allow_update_username: - label: Cho phép người dùng thay đổi tên người dùng của họ - allow_update_avatar: - label: Cho phép người dùng thay đổi hình ảnh hồ sơ của họ - allow_update_bio: - label: Cho phép người dùng thay đổi giới thiệu về mình - allow_update_website: - label: Cho phép người dùng thay đổi trang web của họ - allow_update_location: - label: Cho phép người dùng thay đổi vị trí của họ - privilege: - title: Đặc quyền - level: - label: Mức độ danh tiếng yêu cầu - text: Chọn mức danh tiếng yêu cầu cho các đặc quyền - msg: - should_be_number: dữ liệu đầu vào phải là kiểu số - number_larger_1: số phải bằng hoặc lớn hơn 1 - badges: - action: Hành động - active: Hoạt động - activate: Kích hoạt - all: Tất cả - awards: Giải Thưởng - deactivate: Ngừng kích hoạt - filter: - placeholder: Lọc theo tên, user:id - group: Nhóm - inactive: Không hoạt động - name: Tên - show_logs: Hiển thị nhật ký - status: Trạng thái - title: Danh hiệu - form: - optional: (tùy chọn) - empty: không thể trống - invalid: không hợp lệ - btn_submit: Lưu - not_found_props: "Không tìm thấy thuộc tính bắt buộc {{ key }}." - select: Chọn - page_review: - review: Xem xét - proposed: đề xuất - question_edit: Chỉnh sửa câu hỏi - answer_edit: Câu trả lời chỉnh sửa - tag_edit: Chỉnh sửa thẻ - edit_summary: Tóm tắt chỉnh sửa - edit_question: Chỉnh sửa câu hỏi - edit_answer: Chỉnh sửa câu trả lời - edit_tag: Chỉnh sửa thẻ - empty: Không còn nhiệm vụ xem xét nào. - approve_revision_tip: Bạn có chấp nhận sửa đổi này không? - approve_flag_tip: Bạn có chấp nhận cờ này không? - approve_post_tip: Bạn có chấp nhận bài đăng này không? - approve_user_tip: Bạn có chấp nhận người dùng này không? - suggest_edits: Đề xuất chỉnh sửa - flag_post: Đánh dấu bài đăng - flag_user: Đánh dấu người dùng - queued_post: Bài đăng trong hàng đợi - queued_user: Người dùng trong hàng đợi - filter_label: Loại - reputation: danh tiếng - flag_post_type: Đánh dấu bài đăng này là {{ type }}. - flag_user_type: Đánh dấu người dùng này là {{ type }}. - edit_post: Chỉnh sửa bài đăng - list_post: Liệt kê bài đăng - unlist_post: Gỡ bỏ bài đăng khỏi danh sách - timeline: - undeleted: đã khôi phục - deleted: đã xóa - downvote: bỏ phiếu xuống - upvote: bỏ phiếu lên - accept: chấp nhận - cancelled: đã hủy - commented: đã bình luận - rollback: quay lại - edited: đã chỉnh sửa - answered: đã trả lời - asked: đã hỏi - closed: đã đóng - reopened: đã mở lại - created: đã tạo - pin: đã ghim - unpin: bỏ ghim - show: được liệt kê - hide: không được liệt kê - title: "Lịch sử cho" - tag_title: "Dòng thời gian cho" - show_votes: "Hiển thị phiếu bầu" - n_or_a: N/A - title_for_question: "Dòng thời gian cho" - title_for_answer: "Dòng thời gian cho câu trả lời của {{ title }} bởi {{ author }}" - title_for_tag: "Dòng thời gian cho thẻ" - datetime: Ngày giờ - type: Loại - by: Bởi - comment: Bình luận - no_data: "Chúng tôi không thể tìm thấy bất cứ thứ gì." - users: - title: Người dùng - users_with_the_most_reputation: Người dùng có điểm danh tiếng cao nhất trong tuần này - users_with_the_most_vote: Người dùng đã bỏ phiếu nhiều nhất trong tuần này - staffs: Nhân viên cộng đồng của chúng tôi - reputation: danh tiếng - votes: phiếu bầu - prompt: - leave_page: Bạn có chắc chắn muốn rời khỏi trang không? - changes_not_save: Các thay đổi của bạn có thể không được lưu. - draft: - discard_confirm: Bạn có chắc chắn muốn hủy bản nháp của mình không? - messages: - post_deleted: Bài đăng này đã bị xóa. - post_cancel_deleted: Bài đăng này đã được phục hồi. - post_pin: Bài đăng này đã được ghim. - post_unpin: Bài đăng này đã bị bỏ ghim. - post_hide_list: Bài đăng này đã được ẩn khỏi danh sách. - post_show_list: Bài đăng này đã được hiển thị trên danh sách. - post_reopen: Bài đăng này đã được mở lại. - post_list: Bài đăng này đã được liệt kê. - post_unlist: Bài đăng này đã được gỡ bỏ khỏi danh sách. - post_pending: Bài đăng của bạn đang chờ xem xét. Đây là bản xem trước, nó sẽ được hiển thị sau khi được phê duyệt. - post_closed: Bài đăng này đã bị đóng. - answer_deleted: Câu trả lời này đã bị xóa. - answer_cancel_deleted: Câu trả lời này đã được phục hồi. - change_user_role: Vai trò của người dùng này đã được thay đổi. - user_inactive: Người dùng này đã không hoạt động. - user_normal: Người dùng này đã bình thường. - user_suspended: Người dùng này đã bị đình chỉ. - user_deleted: Người dùng này đã bị xóa. - badge_activated: Huy hiệu này đã được kích hoạt. - badge_inactivated: Huy hiệu này đã bị vô hiệu hóa. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - diff --git a/data/i18n/zh_CN.yaml b/data/i18n/zh_CN.yaml deleted file mode 100644 index 53dca07e3..000000000 --- a/data/i18n/zh_CN.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: 成功。 - unknown: - other: 未知错误。 - request_format_error: - other: 请求格式错误。 - unauthorized_error: - other: 未授权。 - database_error: - other: 数据服务器错误。 - forbidden_error: - other: 禁止访问。 - duplicate_request_error: - other: 重复提交。 - action: - report: - other: 举报 - edit: - other: 编辑 - delete: - other: 删除 - close: - other: 关闭 - reopen: - other: 重新打开 - forbidden_error: - other: 禁止访问。 - pin: - other: 置顶 - hide: - other: 列表隐藏 - unpin: - other: 取消置顶 - show: - other: 列表显示 - invite_someone_to_answer: - other: 编辑 - undelete: - other: 撤消删除 - merge: - other: 合并 - role: - name: - user: - other: 用户 - admin: - other: 管理员 - moderator: - other: 版主 - description: - user: - other: 默认没有特殊权限。 - admin: - other: 拥有管理网站的全部权限。 - moderator: - other: 拥有除访问后台管理以外的所有权限。 - privilege: - level_1: - description: - other: 级别 1(少量声望要求,适合私有团队、群组) - level_2: - description: - other: 级别 2(低声望要求,适合初启动的社区) - level_3: - description: - other: 级别 3(高声望要求,适合成熟的社区) - level_custom: - description: - other: 自定义等级 - rank_question_add_label: - other: 提问 - rank_answer_add_label: - other: 写答案 - rank_comment_add_label: - other: 写评论 - rank_report_add_label: - other: 举报 - rank_comment_vote_up_label: - other: 点赞评论 - rank_link_url_limit_label: - other: 每次发布超过 2 个链接 - rank_question_vote_up_label: - other: 点赞问题 - rank_answer_vote_up_label: - other: 点赞答案 - rank_question_vote_down_label: - other: 点踩问题 - rank_answer_vote_down_label: - other: 点踩答案 - rank_invite_someone_to_answer_label: - other: 邀请回答 - rank_tag_add_label: - other: 创建新标签 - rank_tag_edit_label: - other: 编辑标签描述(需要审核) - rank_question_edit_label: - other: 编辑别人的问题(需要审核) - rank_answer_edit_label: - other: 编辑别人的答案(需要审核) - rank_question_edit_without_review_label: - other: 编辑别人的问题无需审核 - rank_answer_edit_without_review_label: - other: 编辑别人的答案无需审核 - rank_question_audit_label: - other: 审核问题编辑 - rank_answer_audit_label: - other: 审核回答编辑 - rank_tag_audit_label: - other: 审核标签编辑 - rank_tag_edit_without_review_label: - other: 编辑标签描述无需审核 - rank_tag_synonym_label: - other: 管理标签同义词 - email: - other: 邮箱 - e_mail: - other: 邮箱 - password: - other: 密码 - pass: - other: 密码 - old_pass: - other: 当前密码 - original_text: - other: 本帖 - email_or_password_wrong_error: - other: 邮箱和密码不匹配。 - error: - common: - invalid_url: - other: 无效的 URL。 - status_invalid: - other: 无效状态。 - password: - space_invalid: - other: 密码不得含有空格。 - admin: - cannot_update_their_password: - other: 你无法修改自己的密码。 - cannot_edit_their_profile: - other: 您不能修改您的个人资料。 - cannot_modify_self_status: - other: 你无法修改自己的状态。 - email_or_password_wrong: - other: 邮箱和密码不匹配。 - answer: - not_found: - other: 没有找到答案。 - cannot_deleted: - other: 没有删除权限。 - cannot_update: - other: 没有更新权限。 - question_closed_cannot_add: - other: 问题已关闭,无法添加。 - content_cannot_empty: - other: 回答内容不能为空。 - comment: - edit_without_permission: - other: 不允许编辑评论。 - not_found: - other: 评论未找到。 - cannot_edit_after_deadline: - other: 评论时间太久,无法修改。 - content_cannot_empty: - other: 评论内容不能为空。 - email: - duplicate: - other: 邮箱已存在。 - need_to_be_verified: - other: 邮箱需要验证。 - verify_url_expired: - other: 邮箱验证的网址已过期,请重新发送邮件。 - illegal_email_domain_error: - other: 此邮箱不在允许注册的邮箱域中。请使用其他邮箱尝试。 - lang: - not_found: - other: 语言文件未找到。 - object: - captcha_verification_failed: - other: 验证码错误。 - disallow_follow: - other: 你不能关注。 - disallow_vote: - other: 你不能投票。 - disallow_vote_your_self: - other: 你不能为自己的帖子投票。 - not_found: - other: 对象未找到。 - verification_failed: - other: 验证失败。 - email_or_password_incorrect: - other: 邮箱和密码不匹配。 - old_password_verification_failed: - other: 旧密码验证失败。 - new_password_same_as_previous_setting: - other: 新密码和旧密码相同。 - already_deleted: - other: 该帖子已被删除。 - meta: - object_not_found: - other: Meta 对象未找到 - question: - already_deleted: - other: 该帖子已被删除。 - under_review: - other: 您的帖子正在等待审核。它将在它获得批准后可见。 - not_found: - other: 问题未找到。 - cannot_deleted: - other: 没有删除权限。 - cannot_close: - other: 没有关闭权限。 - cannot_update: - other: 没有更新权限。 - content_cannot_empty: - other: 内容不能为空。 - content_less_than_minimum: - other: 输入的内容不足。 - rank: - fail_to_meet_the_condition: - other: 声望值未达到要求。 - vote_fail_to_meet_the_condition: - other: 感谢投票。你至少需要 {{.Rank}} 声望才能投票。 - no_enough_rank_to_operate: - other: 你至少需要 {{.Rank}} 声望才能执行此操作。 - report: - handle_failed: - other: 报告处理失败。 - not_found: - other: 报告未找到。 - tag: - already_exist: - other: 标签已存在。 - not_found: - other: 标签未找到。 - recommend_tag_not_found: - other: 推荐标签不存在。 - recommend_tag_enter: - other: 请选择至少一个必选标签。 - not_contain_synonym_tags: - other: 不应包含同义词标签。 - cannot_update: - other: 没有更新权限。 - is_used_cannot_delete: - other: 你不能删除这个正在使用的标签。 - cannot_set_synonym_as_itself: - other: 你不能将当前标签设为自己的同义词。 - minimum_count: - other: 没有输入足够的标签。 - smtp: - config_from_name_cannot_be_email: - other: 发件人名称不能是邮箱地址。 - theme: - not_found: - other: 主题未找到。 - revision: - review_underway: - other: 目前无法编辑,有一个版本在审阅队列中。 - no_permission: - other: 无权限修改。 - user: - external_login_missing_user_id: - other: 第三方平台没有提供唯一的 UserID,所以你不能登录,请联系网站管理员。 - external_login_unbinding_forbidden: - other: 请在移除此登录之前为你的账户设置登录密码。 - email_or_password_wrong: - other: - other: 邮箱和密码不匹配。 - not_found: - other: 用户未找到。 - suspended: - other: 用户已被封禁。 - username_invalid: - other: 用户名无效。 - username_duplicate: - other: 用户名已被使用。 - set_avatar: - other: 头像设置错误。 - cannot_update_your_role: - other: 你不能修改自己的角色。 - not_allowed_registration: - other: 该网站暂未开放注册。 - not_allowed_login_via_password: - other: 该网站暂不支持密码登录。 - access_denied: - other: 拒绝访问 - page_access_denied: - other: 您没有权限访问此页面。 - add_bulk_users_format_error: - other: "发生错误,{{.Field}} 格式错误,在 '{{.Content}}' 行数 {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "一次性添加的用户数量应在 1-{{.MaxAmount}} 之间。" - status_suspended_forever: - other: "该用户已被永久封禁。该用户不符合社区准则。" - status_suspended_until: - other: "该用户已被封禁至 {{.SuspendedUntil}}。该用户不符合社区准则。" - status_deleted: - other: "该用户已被删除。" - status_inactive: - other: "该用户未激活。" - config: - read_config_failed: - other: 读取配置失败 - database: - connection_failed: - other: 数据库连接失败 - create_table_failed: - other: 创建表失败 - install: - create_config_failed: - other: 无法创建 config.yaml 文件。 - upload: - unsupported_file_format: - other: 不支持的文件格式。 - site_info: - config_not_found: - other: 未找到网站的该配置信息。 - badge: - object_not_found: - other: 没有找到徽章对象 - reason: - spam: - name: - other: 垃圾信息 - desc: - other: 这个帖子是一个广告,或是破坏性行为。它对当前的主题无帮助或无关。 - rude_or_abusive: - name: - other: 粗鲁或辱骂的 - desc: - other: "一个有理智的人都会认为这种内容不适合进行尊重性的讨论。" - a_duplicate: - name: - other: 重复内容 - desc: - other: 该问题有人问过,而且已经有了答案。 - placeholder: - other: 输入已有的问题链接 - not_a_answer: - name: - other: 不是答案 - desc: - other: "该帖是作为答案发布的,但它并没有试图回答这个问题。总之,它可能应该是个编辑、评论、另一个问题或者需要被删除。" - no_longer_needed: - name: - other: 不再需要 - desc: - other: 该评论已过时,对话性质或与此帖子无关。 - something: - name: - other: 其他原因 - desc: - other: 此帖子需要工作人员注意,因为是上述所列以外的其他理由。 - placeholder: - other: 让我们具体知道你关心的什么 - community_specific: - name: - other: 社区特定原因 - desc: - other: 该问题不符合社区准则。 - not_clarity: - name: - other: 需要细节或澄清 - desc: - other: 该问题目前涵盖多个问题。它应该侧重在一个问题上。 - looks_ok: - name: - other: 看起来没问题 - desc: - other: 这个帖子是好的,不是低质量。 - needs_edit: - name: - other: 需要编辑,我已做了修改。 - desc: - other: 改进和纠正你自己帖子中的问题。 - needs_close: - name: - other: 需要关闭 - desc: - other: 关闭的问题不能回答,但仍然可以编辑、投票和评论。 - needs_delete: - name: - other: 需要删除 - desc: - other: 该帖子将被删除。 - question: - close: - duplicate: - name: - other: 垃圾信息 - desc: - other: 此问题以前就有人问过,而且已经有了答案。 - guideline: - name: - other: 社区特定原因 - desc: - other: 该问题不符合社区准则。 - multiple: - name: - other: 需要细节或澄清 - desc: - other: 该问题目前涵盖多个问题。它应该只集中在一个问题上。 - other: - name: - other: 其他原因 - desc: - other: 该帖子存在上面没有列出的另一个原因。 - operation_type: - asked: - other: 提问于 - answered: - other: 回答于 - modified: - other: 修改于 - deleted_title: - other: 删除的问题 - questions_title: - other: 问题 - tag: - tags_title: - other: 标签 - no_description: - other: 此标签没有描述。 - notification: - action: - update_question: - other: 更新了问题 - answer_the_question: - other: 回答了问题 - update_answer: - other: 更新了答案 - accept_answer: - other: 采纳了答案 - comment_question: - other: 评论了问题 - comment_answer: - other: 评论了答案 - reply_to_you: - other: 回复了你 - mention_you: - other: 提到了你 - your_question_is_closed: - other: 你的问题已被关闭 - your_question_was_deleted: - other: 你的问题已被删除 - your_answer_was_deleted: - other: 你的答案已被删除 - your_comment_was_deleted: - other: 你的评论已被删除 - up_voted_question: - other: 点赞问题 - down_voted_question: - other: 点踩问题 - up_voted_answer: - other: 点赞答案 - down_voted_answer: - other: 点踩回答 - up_voted_comment: - other: 点赞评论 - invited_you_to_answer: - other: 邀请你回答 - earned_badge: - other: 你获得 "{{.BadgeName}}" 徽章 - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] 确认你的新邮箱地址" - body: - other: "请点击以下链接确认你在 {{.SiteName}} 上的新邮箱地址:
        \n{{.ChangeEmailUrl}}

        \n\n如果你没有请求此更改,请忽略此邮件。\n\n--
        \n这是系统自动发送的电子邮件,请勿回复,因为您的回复将不会被看到

        " - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} 回答了你的问题" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \n在 {{.SiteName}} 上查看

        \n\n--
        \n这是系统自动发送的电子邮件,请勿回复,因为您的回复将不会被看到

        \n\n取消订阅" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} 邀请您回答问题" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        我想你可能知道答案。

        \n在 {{.SiteName}} 上查看

        \n\n--
        \n这是系统自动发送的电子邮件,请勿回复,因为您的回复将不会被看到

        \n\n取消订阅" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} 评论了你的帖子" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \n在 {{.SiteName}} 上查看

        \n\n--
        \n这是系统自动发送的电子邮件,请勿回复,因为您的回复将不会被看到

        \n\n取消订阅" - new_question: - title: - other: "[{{.SiteName}}] 新问题: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}

        \n{{.Tags}}

        \n\n--
        \n这是系统自动发送的电子邮件,请勿回复,因为您的回复将不会被看到

        \n\n取消订阅" - pass_reset: - title: - other: "[{{.SiteName }}] 重置密码" - body: - other: "有人要求在 [{{.SiteName}}] 上重置你的密码。

        \n\n如果这不是你的操作,请安心忽略此电子邮件。

        \n\n请点击以下链接设置一个新密码:
        \n{{.PassResetUrl}}\n\n如果你没有请求此更改,请忽略此邮件。\n" - register: - title: - other: "[{{.SiteName}}] 确认你的新账户" - body: - other: "欢迎加入 {{.SiteName}}!

        \n\n请点击以下链接确认并激活你的新账户:
        \n{{.RegisterUrl}}

        \n\n如果上面的链接不能点击,请将其复制并粘贴到你的浏览器地址栏中。\n

        \n\n--
        \n这是系统自动发送的电子邮件,请勿回复,因为您的回复将不会被看到" - test: - title: - other: "[{{.SiteName}}] 测试邮件" - body: - other: "这是测试电子邮件。\n

        \n\n-
        \n注意:这是一个自动的系统电子邮件, 请不要回复此消息,因为您的回复将不会被看到。" - action_activity_type: - upvote: - other: 点赞 - upvoted: - other: 点赞 - downvote: - other: 点踩 - downvoted: - other: 点踩 - accept: - other: 采纳 - accepted: - other: 已采纳 - edit: - other: 编辑 - review: - queued_post: - other: 排队的帖子 - flagged_post: - other: 举报的帖子 - suggested_post_edit: - other: 建议的编辑 - reaction: - tooltip: - other: "{{ .Names }} 以及另外 {{ .Count }} 个..." - badge: - default_badges: - autobiographer: - name: - other: 自传作者 - desc: - other: 填写了 个人资料 信息。 - certified: - name: - other: 已认证 - desc: - other: 完成了我们的新用户教程。 - editor: - name: - other: 编辑者 - desc: - other: 首次帖子编辑。 - first_flag: - name: - other: 第一次举报 - desc: - other: 第一次举报一个帖子 - first_upvote: - name: - other: 第一次投票 - desc: - other: 第一次投票了一个帖子。 - first_link: - name: - other: 第一个链接 - desc: - other: 第一次添加了一个链接到另一个帖子。 - first_reaction: - name: - other: 第一个响应 - desc: - other: 第一次表情回应帖子 - first_share: - name: - other: 首次分享 - desc: - other: 首次分享了一个帖子。 - scholar: - name: - other: 学者 - desc: - other: 问了一个问题并接受了一个答案。 - commentator: - name: - other: 评论员 - desc: - other: 留下5条评论。 - new_user_of_the_month: - name: - other: 月度用户 - desc: - other: 本月杰出用户 - read_guidelines: - name: - other: 阅读指南 - desc: - other: 阅读[社区准则]。 - reader: - name: - other: 读者 - desc: - other: 用10个以上的答案在主题中阅读每个答案。 - welcome: - name: - other: 欢迎 - desc: - other: 获得一个点赞投票 - nice_share: - name: - other: 好分享 - desc: - other: 分享了一个拥有25个唯一访客的帖子。 - good_share: - name: - other: 好分享 - desc: - other: 分享了一个拥有300个唯一访客的帖子。 - great_share: - name: - other: 优秀的分享 - desc: - other: 分享了一个拥有1000个唯一访客的帖子。 - out_of_love: - name: - other: 失去爱好 - desc: - other: 一天内使用了 50 个赞。 - higher_love: - name: - other: 更高的爱好 - desc: - other: 一天内使用了 50 个赞 5 次。 - crazy_in_love: - name: - other: 爱情疯狂的 - desc: - other: 一天内使用了 50 个赞 20 次。 - promoter: - name: - other: 推荐人 - desc: - other: 邀请用户。 - campaigner: - name: - other: 宣传者 - desc: - other: 邀请了3个基本用户。 - champion: - name: - other: 冠军 - desc: - other: 邀请了5个成员。 - thank_you: - name: - other: 谢谢 - desc: - other: 有 20 个赞成票的帖子,并投了 10 个赞成票。 - gives_back: - name: - other: 返回 - desc: - other: 拥有100个投票赞成的职位并放弃了100个投票。 - empathetic: - name: - other: 情随境迁 - desc: - other: 拥有500个投票赞成的职位并放弃了1000个投票。 - enthusiast: - name: - other: 狂热 - desc: - other: 连续访问10天。 - aficionado: - name: - other: Aficionado - desc: - other: 连续访问100天。 - devotee: - name: - other: Devotee - desc: - other: 连续访问365天。 - anniversary: - name: - other: 周年纪念日 - desc: - other: 活跃成员一年至少发布一次。 - appreciated: - name: - other: 欣赏 - desc: - other: 在 20 个帖子中获得 1个投票 - respected: - name: - other: 尊敬 - desc: - other: 100个员额获得2次补票。 - admired: - name: - other: 仰慕 - desc: - other: 300个员额获得5次补票。 - solved: - name: - other: 已解决 - desc: - other: 接受答案。 - guidance_counsellor: - name: - other: 指导顾问 - desc: - other: 接受答案。 - know_it_all: - name: - other: 万事通 - desc: - other: 接受50个答案。 - solution_institution: - name: - other: 解决方案机构 - desc: - other: 有150个答案被接受。 - nice_answer: - name: - other: 好答案 - desc: - other: 回答得分为10或以上。 - good_answer: - name: - other: 好答案 - desc: - other: 回答得分为25或更多。 - great_answer: - name: - other: 优秀答案 - desc: - other: 回答得分为50或以上。 - nice_question: - name: - other: 好问题 - desc: - other: 问题得分为10或以上。 - good_question: - name: - other: 好问题 - desc: - other: 问题得分为25或更多。 - great_question: - name: - other: 很棒的问题 - desc: - other: 问题得分为50或更多。 - popular_question: - name: - other: 热门问题 - desc: - other: 问题有 500 个浏览量。 - notable_question: - name: - other: 值得关注问题 - desc: - other: 问题有 1,000 个浏览量。 - famous_question: - name: - other: 著名的问题 - desc: - other: 问题有 5,000 个浏览量。 - popular_link: - name: - other: 热门链接 - desc: - other: 发布了一个带有50个点击的外部链接。 - hot_link: - name: - other: 热门链接 - desc: - other: 发布了一个带有300个点击的外部链接。 - famous_link: - name: - other: 著名链接 - desc: - other: 发布了一个带有100个点击的外部链接。 - default_badge_groups: - getting_started: - name: - other: 完成初始化 - community: - name: - other: Community 专题 - posting: - name: - other: 发帖 -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: 如何排版 - desc: >- -
        • 引用问题或答案: #4

        • 添加链接

          <https://url.com>

          [标题](https://url.com)
        • 段落之间使用空行分隔

        • _斜体_ 或者 **粗体**

        • 使用 个空格缩进代码

        • 在行首添加 > 表示引用

        • 反引号进行转义 `像 _这样_`

        • 使用 ``` 创建代码块

          ```
          这是代码块
          ```
        - pagination: - prev: 上一页 - next: 下一页 - page_title: - question: 问题 - questions: 问题 - tag: 标签 - tags: 标签 - tag_wiki: 标签维基 - create_tag: 创建标签 - edit_tag: 编辑标签 - ask_a_question: 创建问题 - edit_question: 编辑问题 - edit_answer: 编辑回答 - search: 搜索 - posts_containing: 帖子包含 - settings: 设置 - notifications: 通知 - login: 登录 - sign_up: 注册 - account_recovery: 账号恢复 - account_activation: 账号激活 - confirm_email: 确认电子邮件 - account_suspended: 账号已被封禁 - admin: 后台管理 - change_email: 修改邮箱 - install: Answer 安装 - upgrade: Answer 升级 - maintenance: 网站维护 - users: 用户 - oauth_callback: 处理中 - http_404: HTTP 错误 404 - http_50X: HTTP 错误 500 - http_403: HTTP 错误 403 - logout: 退出 - posts: 帖子 - notifications: - title: 通知 - inbox: 收件箱 - achievement: 成就 - new_alerts: 新通知 - all_read: 全部标记为已读 - show_more: 显示更多 - someone: 有人 - inbox_type: - all: 全部 - posts: 帖子 - invites: 邀请 - votes: 投票 - answer: 回答 - question: 问题 - badge_award: 徽章 - suspended: - title: 你的账号账号已被封禁 - until_time: "你的账号被封禁直到 {{ time }}。" - forever: 你的账号已被永久封禁。 - end: 你违反了我们的社区准则。 - contact_us: 联系我们 - editor: - blockquote: - text: 引用 - bold: - text: 粗体 - chart: - text: 图表 - flow_chart: 流程图 - sequence_diagram: 时序图 - class_diagram: 类图 - state_diagram: 状态图 - entity_relationship_diagram: 实体关系图 - user_defined_diagram: 用户自定义图表 - gantt_chart: 甘特图 - pie_chart: 饼图 - code: - text: 代码块 - add_code: 添加代码块 - form: - fields: - code: - label: 代码块 - msg: - empty: 代码块不能为空 - language: - label: 语言 - placeholder: 自动识别 - btn_cancel: 取消 - btn_confirm: 添加 - formula: - text: 公式 - options: - inline: 行内公式 - block: 块级公式 - heading: - text: 标题 - options: - h1: 标题 1 - h2: 标题 2 - h3: 标题 3 - h4: 标题 4 - h5: 标题 5 - h6: 标题 6 - help: - text: 帮助 - hr: - text: 水平线 - image: - text: 图片 - add_image: 添加图片 - tab_image: 上传图片 - form_image: - fields: - file: - label: 图像文件 - btn: 选择图片 - msg: - empty: 请选择图片文件。 - only_image: 只能上传图片文件。 - max_size: 文件大小不能超过 {{size}} MB。 - desc: - label: 描述 - tab_url: 图片地址 - form_url: - fields: - url: - label: 图片地址 - msg: - empty: 图片地址不能为空 - name: - label: 描述 - btn_cancel: 取消 - btn_confirm: 添加 - uploading: 上传中 - indent: - text: 缩进 - outdent: - text: 减少缩进 - italic: - text: 斜体 - link: - text: 超链接 - add_link: 添加超链接 - form: - fields: - url: - label: 链接 - msg: - empty: 链接不能为空。 - name: - label: 描述 - btn_cancel: 取消 - btn_confirm: 添加 - ordered_list: - text: 有序列表 - unordered_list: - text: 无序列表 - table: - text: 表格 - heading: 表头 - cell: 单元格 - file: - text: 附件 - not_supported: "不支持的文件类型。请尝试上传其他类型的文件如: {{file_type}}。" - max_size: "上传文件超过 {{size}} MB。" - close_modal: - title: 关闭原因是... - btn_cancel: 取消 - btn_submit: 提交 - remark: - empty: 不能为空。 - msg: - empty: 请选择一个原因。 - report_modal: - flag_title: 我举报这篇帖子的原因是... - close_title: 我关闭这篇帖子的原因是... - review_question_title: 审查问题 - review_answer_title: 审查回答 - review_comment_title: 审查评论 - btn_cancel: 取消 - btn_submit: 提交 - remark: - empty: 不能为空 - msg: - empty: 请选择一个原因。 - not_a_url: URL 格式不正确。 - url_not_match: URL 来源与当前网站不匹配。 - tag_modal: - title: 创建新标签 - form: - fields: - display_name: - label: 显示名称 - msg: - empty: 显示名称不能为空。 - range: 显示名称不能超过 35 个字符。 - slug_name: - label: URL 固定链接 - desc: URL 固定链接不能超过 35 个字符。 - msg: - empty: URL 固定链接不能为空。 - range: URL 固定链接不能超过 35 个字符。 - character: URL 固定链接包含非法字符。 - desc: - label: 描述 - revision: - label: 编辑历史 - edit_summary: - label: 编辑备注 - placeholder: >- - 简单描述更改原因(更正拼写、修复语法、改进格式) - btn_cancel: 取消 - btn_submit: 提交 - btn_post: 发布新标签 - tag_info: - created_at: 创建于 - edited_at: 编辑于 - history: 历史 - synonyms: - title: 同义词 - text: 以下标签将被重置到 - empty: 此标签目前没有同义词。 - btn_add: 添加同义词 - btn_edit: 编辑 - btn_save: 保存 - synonyms_text: 以下标签将被重置到 - delete: - title: 删除标签 - tip_with_posts: >- -

        我们不允许 删除带有帖子的标签

        请先从帖子中移除此标签。

        - tip_with_synonyms: >- -

        我们不允许 删除带有同义词的标签

        请先从此标签中删除同义词。

        - tip: 确定要删除吗? - close: 关闭 - merge: - title: 合并标签 - source_tag_title: 源标签 - source_tag_description: 源标签及其相关数据将重新映射到目标标签。 - target_tag_title: 目标标签 - target_tag_description: 合并后将在这两个标签之间将创建一个同义词。 - no_results: 没有匹配的标签 - btn_submit: 提交 - btn_close: 关闭 - edit_tag: - title: 编辑标签 - default_reason: 编辑标签 - default_first_reason: 添加标签 - btn_save_edits: 保存更改 - btn_cancel: 取消 - dates: - long_date: MM 月 DD 日 - long_date_with_year: "YYYY 年 MM 月 DD 日" - long_date_with_time: "YYYY 年 MM 月 DD 日 HH:mm" - now: 刚刚 - x_seconds_ago: "{{count}} 秒前" - x_minutes_ago: "{{count}} 分钟前" - x_hours_ago: "{{count}} 小时前" - hour: 小时 - day: 天 - hours: 小时 - days: 日 - month: 月 - months: 月 - year: 年 - reaction: - heart: 爱心 - smile: 微笑 - frown: 愁 - btn_label: 添加或删除回应。 - undo_emoji: 撤销 {{ emoji }} 回应 - react_emoji: 用 {{ emoji }} 回应 - unreact_emoji: 撤销 {{ emoji }} - comment: - btn_add_comment: 添加评论 - reply_to: 回复 - btn_reply: 回复 - btn_edit: 编辑 - btn_delete: 删除 - btn_flag: 举报 - btn_save_edits: 保存更改 - btn_cancel: 取消 - show_more: "{{count}} 条剩余评论" - tip_question: >- - 使用评论提问更多信息或者提出改进意见。避免在评论里回答问题。 - tip_answer: >- - 使用评论对回答者进行回复,或者通知回答者你已更新了问题的内容。如果要补充或者完善问题的内容,请在原问题中更改。 - tip_vote: 它给帖子添加了一些有用的内容 - edit_answer: - title: 编辑回答 - default_reason: 编辑回答 - default_first_reason: 添加答案 - form: - fields: - revision: - label: 编辑历史 - answer: - label: 回答内容 - feedback: - characters: 内容长度至少 6 个字符 - edit_summary: - label: 编辑摘要 - placeholder: >- - 简单描述更改原因(更正拼写、修复语法、改进格式) - btn_save_edits: 保存更改 - btn_cancel: 取消 - tags: - title: 标签 - sort_buttons: - popular: 热门 - name: 名称 - newest: 最新 - button_follow: 关注 - button_following: 已关注 - tag_label: 个问题 - search_placeholder: 通过标签名称过滤 - no_desc: 此标签无描述。 - more: 更多 - wiki: 维基 - ask: - title: 创建问题 - edit_title: 编辑问题 - default_reason: 编辑问题 - default_first_reason: 创建问题 - similar_questions: 相似问题 - form: - fields: - revision: - label: 修订版本 - title: - label: 标题 - placeholder: 你的主题是什么?请具体说明。 - msg: - empty: 标题不能为空。 - range: 标题最多 150 个字符 - body: - label: 内容 - msg: - empty: 内容不能为空。 - hint: - optional_body: 描述这个问题是什么。 - minimum_characters: "详细描述这个问题,至少需要 {{min_content_length}} 字符。" - tags: - label: 标签 - msg: - empty: 必须选择一个标签 - answer: - label: 回答内容 - msg: - empty: 回答内容不能为空 - edit_summary: - label: 编辑备注 - placeholder: >- - 简单描述更改原因(更正拼写、修复语法、改进格式) - btn_post_question: 提交问题 - btn_save_edits: 保存更改 - answer_question: 回答自己的问题 - post_question&answer: 提交问题和回答 - tag_selector: - add_btn: 添加标签 - create_btn: 创建新标签 - search_tag: 搜索标签 - hint: 描述您的内容是关于什么,至少需要一个标签。 - hint_zero_tags: 描述您的内容与什么有关。 - hint_more_than_one_tag: "描述您的内容是关于什么,至少需要{{min_tags_number}}个标签。" - no_result: 没有匹配的标签 - tag_required_text: 必选标签(至少一个) - header: - nav: - question: 问题 - tag: 标签 - user: 用户 - badges: 徽章 - profile: 用户主页 - setting: 账号设置 - logout: 退出 - admin: 后台管理 - review: 审查 - bookmark: 收藏夹 - moderation: 管理 - search: - placeholder: 搜索 - footer: - build_on: 由 <1>Apache Answer 提供动力 - upload_img: - name: 更改 - loading: 加载中... - pic_auth_code: - title: 验证码 - placeholder: 输入图片中的文字 - msg: - empty: 验证码不能为空。 - inactive: - first: >- - 就差一步!我们发送了一封激活邮件到 {{mail}}。请按照邮件中的说明激活你的账户。 - info: "如果没有收到,请检查你的垃圾邮件文件夹。" - another: >- - 我们向你的邮箱 {{mail}} 发送了另一封激活电子邮件。可能需要几分钟才能到达;请务必检查您的垃圾邮件箱。 - btn_name: 重新发送激活邮件 - change_btn_name: 更改邮箱 - msg: - empty: 不能为空。 - resend_email: - url_label: 确定要重新发送激活邮件吗? - url_text: 你也可以将上面的激活链接给该用户。 - login: - login_to_continue: 登录以继续 - info_sign: 没有账户?<1>注册 - info_login: 已经有账户?<1>登录 - agreements: 登录即表示您同意<1>隐私政策和<3>服务条款。 - forgot_pass: 忘记密码? - name: - label: 名字 - msg: - empty: 名字不能为空 - range: 名称长度必须在 2 至 30 个字符之间。 - character: '只能由 "a-z", "0-9", " - . _" 组成' - email: - label: 邮箱 - msg: - empty: 邮箱不能为空 - password: - label: 密码 - msg: - empty: 密码不能为空 - different: 两次输入密码不一致 - account_forgot: - page_title: 忘记密码 - btn_name: 发送恢复邮件 - send_success: >- - 如果存在邮箱为 {{mail}} 账户,你将很快收到一封重置密码的说明邮件。 - email: - label: 邮箱 - msg: - empty: 邮箱不能为空 - change_email: - btn_cancel: 取消 - btn_update: 更新电子邮件地址 - send_success: >- - 如果存在邮箱为 {{mail}} 的账户,你将很快收到一封重置密码的说明邮件。 - email: - label: 新的电子邮件地址 - msg: - empty: 邮箱不能为空。 - oauth: - connect: 连接到 {{ auth_name }} - remove: 移除 {{ auth_name }} - oauth_bind_email: - subtitle: 向你的账户添加恢复邮件地址。 - btn_update: 更新电子邮件地址 - email: - label: 邮箱 - msg: - empty: 邮箱不能为空。 - modal_title: 邮箱已经存在。 - modal_content: 该电子邮件地址已经注册。你确定要连接到已有账户吗? - modal_cancel: 更改邮箱 - modal_confirm: 连接到已有账户 - password_reset: - page_title: 密码重置 - btn_name: 重置我的密码 - reset_success: >- - 你已经成功更改密码;你将被重定向到登录页面。 - link_invalid: >- - 抱歉,此密码重置链接已失效。也许是你已经重置过密码了? - to_login: 前往登录页面 - password: - label: 密码 - msg: - empty: 密码不能为空。 - length: 密码长度在8-32个字符之间 - different: 两次输入密码不一致 - password_confirm: - label: 确认新密码 - settings: - page_title: 设置 - goto_modify: 前往修改 - nav: - profile: 我的资料 - notification: 通知 - account: 账号 - interface: 界面 - profile: - heading: 个人资料 - btn_name: 保存 - display_name: - label: 显示名称 - msg: 昵称不能为空。 - msg_range: 显示名称长度必须为 2-30 个字符。 - username: - label: 用户名 - caption: 用户可以通过 "@用户名" 来提及你。 - msg: 用户名不能为空 - msg_range: 显示名称长度必须为 2-30 个字符。 - character: '只能由 "a-z", "0-9", " - . _" 组成' - avatar: - label: 头像 - gravatar: Gravatar - gravatar_text: 你可以更改图像在 - custom: 自定义 - custom_text: 你可以上传你的图片。 - default: 系统 - msg: 请上传头像 - bio: - label: 关于我 - website: - label: 网站 - placeholder: "https://example.com" - msg: 网址格式不正确 - location: - label: 位置 - placeholder: "城市,国家" - notification: - heading: 邮件通知 - turn_on: 开启 - inbox: - label: 收件箱通知 - description: 你的提问有新的回答,评论,邀请回答和其他。 - all_new_question: - label: 所有新问题 - description: 获取所有新问题的通知。每周最多有50个问题。 - all_new_question_for_following_tags: - label: 所有关注标签的新问题 - description: 获取关注的标签下新问题通知。 - account: - heading: 账号 - change_email_btn: 更改邮箱 - change_pass_btn: 更改密码 - change_email_info: >- - 邮件已发送。请根据指引完成验证。 - email: - label: 电子邮件地址 - new_email: - label: 新的电子邮件地址 - msg: 新邮箱不能为空。 - pass: - label: 当前密码 - msg: 密码不能为空。 - password_title: 密码 - current_pass: - label: 当前密码 - msg: - empty: 当前密码不能为空 - length: 密码长度必须在 8 至 32 之间 - different: 两次输入的密码不匹配 - new_pass: - label: 新密码 - pass_confirm: - label: 确认新密码 - interface: - heading: 界面 - lang: - label: 界面语言 - text: 设置用户界面语言,在刷新页面后生效。 - my_logins: - title: 我的登录 - label: 使用这些账户登录或注册本网站。 - modal_title: 移除登录 - modal_content: 你确定要从账户里移除该登录? - modal_confirm_btn: 移除 - remove_success: 移除成功 - toast: - update: 更新成功 - update_password: 密码更新成功。 - flag_success: 感谢标记。 - forbidden_operate_self: 禁止对自己执行操作 - review: 您的修订将在审阅通过后显示。 - sent_success: 发送成功 - related_question: - title: 相似 - answers: 个回答 - linked_question: - title: 关联 - description: 帖子关联到 - no_linked_question: 没有与之关联的贴子。 - invite_to_answer: - title: 受邀人 - desc: 邀请你认为可能知道答案的人。 - invite: 邀请回答 - add: 添加人员 - search: 搜索人员 - question_detail: - action: 操作 - created: 创建于 - Asked: 提问于 - asked: 提问于 - update: 修改于 - Edited: 编辑于 - edit: 编辑于 - commented: 评论 - Views: 阅读次数 - Follow: 关注此问题 - Following: 已关注 - follow_tip: 关注此问题以接收通知 - answered: 回答于 - closed_in: 关闭于 - show_exist: 查看类似问题。 - useful: 有用的 - question_useful: 它是有用和明确的 - question_un_useful: 它不明确或没用的 - question_bookmark: 收藏该问题 - answer_useful: 这是有用的 - answer_un_useful: 它是没有用的 - answers: - title: 个回答 - score: 评分 - newest: 最新 - oldest: 最旧 - btn_accept: 采纳 - btn_accepted: 已被采纳 - write_answer: - title: 你的回答 - edit_answer: 编辑我的回答 - btn_name: 提交你的回答 - add_another_answer: 添加另一个回答 - confirm_title: 继续回答 - continue: 继续 - confirm_info: >- -

        你确定要提交一个新的回答吗?

        作为替代,你可以通过编辑来完善和改进之前的回答。

        - empty: 回答内容不能为空。 - characters: 内容长度至少 6 个字符。 - tips: - header_1: 感谢你的回答 - li1_1: 请务必确定在 回答问题。提供详细信息并分享你的研究。 - li1_2: 用参考资料或个人经历来支持你所做的任何陈述。 - header_2: 但是 请避免... - li2_1: 请求帮助,寻求澄清,或答复其他答案。 - reopen: - confirm_btn: 重新打开 - title: 重新打开这个帖子 - content: 确定要重新打开吗? - list: - confirm_btn: 列表显示 - title: 列表中显示这个帖子 - content: 确定要列表中显示这个帖子吗? - unlist: - confirm_btn: 列表隐藏 - title: 从列表中隐藏这个帖子 - content: 确定要从列表中隐藏这个帖子吗? - pin: - title: 置顶该帖子 - content: 你确定要全局置顶吗?这个帖子将出现在所有帖子列表的顶部。 - confirm_btn: 置顶 - delete: - title: 删除 - question: >- - 我们不建议 删除有回答的帖子。因为这样做会使得后来的读者无法从该帖子中获得帮助。

        如果删除过多有回答的帖子,你的账号将会被禁止提问。你确定要删除吗? - answer_accepted: >- -

        我们不建议删除被采纳的回答。因为这样做会使得后来的读者无法从该帖子中获得帮助。

        如果删除过多被采纳的回答,你的账号将会被禁止回答任何提问。你确定要删除吗? - other: 你确定要删除? - tip_answer_deleted: 该回答已被删除 - undelete_title: 撤销删除本帖 - undelete_desc: 你确定你要撤销删除吗? - btns: - confirm: 确认 - cancel: 取消 - edit: 编辑 - save: 保存 - delete: 删除 - undelete: 撤消删除 - list: 列表显示 - unlist: 列表隐藏 - unlisted: 已隐藏 - login: 登录 - signup: 注册 - logout: 退出 - verify: 验证 - create: 创建 - approve: 批准 - reject: 拒绝 - skip: 跳过 - discard_draft: 丢弃草稿 - pinned: 已置顶 - all: 全部 - question: 问题 - answer: 回答 - comment: 评论 - refresh: 刷新 - resend: 重新发送 - deactivate: 取消激活 - active: 激活 - suspend: 封禁 - unsuspend: 解禁 - close: 关闭 - reopen: 重新打开 - ok: 确定 - light: 浅色 - dark: 深色 - system_setting: 跟随系统 - default: 默认 - reset: 重置 - tag: 标签 - post_lowercase: 帖子 - filter: 筛选 - ignore: 忽略 - submit: 提交 - normal: 正常 - closed: 已关闭 - deleted: 已删除 - deleted_permanently: 永久删除 - pending: 等待处理 - more: 更多 - view: 浏览量 - card: 卡片 - compact: 紧凑 - display_below: 在下方显示 - always_display: 总是显示 - or: 或者 - back_sites: 返回网站 - search: - title: 搜索结果 - keywords: 关键词 - options: 选项 - follow: 关注 - following: 已关注 - counts: "{{count}} 个结果" - counts_loading: "... 个结果" - more: 更多 - sort_btns: - relevance: 相关性 - newest: 最新的 - active: 活跃的 - score: 评分 - more: 更多 - tips: - title: 高级搜索提示 - tag: "<1>[tag] 在指定标签中搜索" - user: "<1>user:username 根据作者搜索" - answer: "<1>answers:0 搜索未回答的问题" - score: "<1>score:3 评分 3+ 的帖子" - question: "<1>is:question 搜索问题" - is_answer: "<1>is:answer 搜索回答" - empty: 找不到任何相关的内容。
        请尝试其他关键字,或者减少查找内容的长度。 - share: - name: 分享 - copy: 复制链接 - via: 分享到... - copied: 已复制 - facebook: 分享到 Facebook - twitter: 分享到 X - cannot_vote_for_self: 你不能给自己的帖子投票。 - modal_confirm: - title: 发生错误... - delete_permanently: - title: 永久删除 - content: 您确定要永久删除吗? - account_result: - success: 你的账号已通过验证,即将返回首页。 - link: 返回首页 - oops: 糟糕! - invalid: 您使用的链接不再有效。 - confirm_new_email: 你的电子邮箱已更新 - confirm_new_email_invalid: >- - 抱歉,此验证链接已失效。也许是你的邮箱已经成功更改了? - unsubscribe: - page_title: 退订 - success_title: 退订成功 - success_desc: 您已成功退订,并且将不会再收到我们的邮件。 - link: 更改设置 - question: - following_tags: 已关注的标签 - edit: 编辑 - save: 保存 - follow_tag_tip: 关注标签来筛选你的问题列表。 - hot_questions: 热门问题 - all_questions: 全部问题 - x_questions: "{{ count }} 个问题" - x_answers: "{{ count }} 个回答" - x_posts: "{{ count }} 个帖子" - questions: 问题 - answers: 回答 - newest: 最新 - active: 活跃 - hot: 热门 - frequent: 频繁的 - recommend: 推荐 - score: 评分 - unanswered: 未回答 - modified: 更新于 - answered: 回答于 - asked: 提问于 - closed: 已关闭 - follow_a_tag: 关注一个标签 - more: 更多 - personal: - overview: 概览 - answers: 回答 - answer: 回答 - questions: 问题 - question: 问题 - bookmarks: 收藏 - reputation: 声望 - comments: 评论 - votes: 得票 - badges: 徽章 - newest: 最新 - score: 评分 - edit_profile: 编辑资料 - visited_x_days: "已访问 {{ count }} 天" - viewed: 浏览次数 - joined: 加入于 - comma: "," - last_login: 上次登录 - about_me: 关于我 - about_me_empty: "// Hello, World!" - top_answers: 高分回答 - top_questions: 高分问题 - stats: 状态 - list_empty: 没有找到相关的内容。
        试试看其他选项卡? - content_empty: 未找到帖子。 - accepted: 已采纳 - answered: 回答于 - asked: 提问于 - downvoted: 点踩 - mod_short: 版主 - mod_long: 版主 - x_reputation: 声望 - x_votes: 得票 - x_answers: 个回答 - x_questions: 个问题 - recent_badges: 最近的徽章 - install: - title: 安装 - next: 下一步 - done: 完成 - config_yaml_error: 无法创建 config.yaml 文件。 - lang: - label: 请选择一种语言 - db_type: - label: 数据库引擎 - db_username: - label: 用户名 - placeholder: root - msg: 用户名不能为空 - db_password: - label: 密码 - placeholder: root - msg: 密码不能为空 - db_host: - label: 数据库主机 - placeholder: "db:3306" - msg: 数据库地址不能为空 - db_name: - label: 数据库名 - placeholder: 回答 - msg: 数据库名称不能为空。 - db_file: - label: 数据库文件 - placeholder: /data/answer.db - msg: 数据库文件不能为空。 - ssl_enabled: - label: 启用 SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL 模式 - ssl_root_cert: - placeholder: sslrootcert文件路径 - msg: sslrootcert 文件的路径不能为空 - ssl_cert: - placeholder: sslcert文件路径 - msg: sslcert 文件的路径不能为空 - ssl_key: - placeholder: sslkey 文件路径 - msg: sslcert 文件的路径不能为空 - config_yaml: - title: 创建 config.yaml - label: 已创建 config.yaml 文件。 - desc: >- - 你可以手动在 <1>/var/wwww/xxx/ 目录中创建 <1>config.yaml 文件并粘贴以下文本。 - info: 完成后,点击“下一步”按钮。 - site_information: 站点信息 - admin_account: 管理员账号 - site_name: - label: 站点名称 - msg: 站点名称不能为空。 - msg_max_length: 站点名称长度不得超过 30 个字符。 - site_url: - label: 网站网址 - text: 此网站的网址。 - msg: - empty: 网址不能为空。 - incorrect: 网址格式不正确。 - max_length: 网址长度不得超过 512 个字符。 - contact_email: - label: 联系邮箱 - text: 负责本网站的主要联系人的电子邮件地址。 - msg: - empty: 联系人邮箱不能为空。 - incorrect: 联系人邮箱地址不正确。 - login_required: - label: 私有的 - switch: 需要登录 - text: 只有登录用户才能访问这个社区。 - admin_name: - label: 名字 - msg: 名字不能为空。 - character: '只能由 "a-z", "0-9", " - . _" 组成' - msg_max_length: 名称长度必须在 2 至 30 个字符之间。 - admin_password: - label: 密码 - text: >- - 您需要此密码才能登录。请将其存储在一个安全的位置。 - msg: 密码不能为空。 - msg_min_length: 密码必须至少 8 个字符长。 - msg_max_length: 密码长度不能超过 32 个字符。 - admin_confirm_password: - label: "确认密码" - text: "请重新输入您的密码以确认。" - msg: "确认密码不一致。" - admin_email: - label: 邮箱 - text: 您需要此电子邮件才能登录。 - msg: - empty: 邮箱不能为空。 - incorrect: 邮箱格式不正确。 - ready_title: 您的网站已准备好 - ready_desc: >- - 如果你想改变更多的设置,请访问 <1>管理区域;在网站菜单中找到它。 - good_luck: "玩得愉快,祝你好运!" - warn_title: 警告 - warn_desc: >- - 文件 <1>config.yaml 已存在。如果你要重置该文件中的任何配置项,请先删除它。 - install_now: 您可以尝试 <1>现在安装。 - installed: 已安裝 - installed_desc: >- - 你似乎已经安装过了。如果要重新安装,请先清除旧的数据库表。 - db_failed: 数据连接异常! - db_failed_desc: >- - 这或者意味着数据库信息在 <1>config.yaml 文件不正确,或者无法与数据库服务器建立联系。这可能意味着你的主机数据库服务器故障。 - counts: - views: 次浏览 - votes: 个点赞 - answers: 个回答 - accepted: 已被采纳 - page_error: - http_error: HTTP 错误 {{ code }} - desc_403: 您无权访问此页面。 - desc_404: 很抱歉,此页面不存在。 - desc_50X: 服务器遇到了一个错误,无法完成你的请求。 - back_home: 返回首页 - page_maintenance: - desc: "我们正在进行维护,我们将很快回来。" - nav_menus: - dashboard: 后台管理 - contents: 内容管理 - questions: 问题 - answers: 回答 - users: 用户管理 - badges: 徽章 - flags: 举报管理 - settings: 站点设置 - general: 一般 - interface: 界面 - smtp: SMTP - branding: 品牌 - legal: 法律条款 - write: 撰写 - terms: 服务条款 - tos: 服务条款 - privacy: 隐私政策 - seo: SEO - customize: 自定义 - themes: 主题 - login: 登录 - privileges: 特权 - plugins: 插件 - installed_plugins: 已安装插件 - apperance: 外观 - website_welcome: 欢迎来到 {{site_name}} - user_center: - login: 登录 - qrcode_login_tip: 请使用 {{ agentName }} 扫描二维码并登录。 - login_failed_email_tip: 登录失败,请允许此应用访问您的邮箱信息,然后重试。 - badges: - modal: - title: 恭喜 - content: 你赢得了一个新徽章。 - close: 关闭 - confirm: 查看徽章 - title: 徽章 - awarded: 授予 - earned_×: 以获得 ×{{ number }} - ×_awarded: "{{ number }} 得到" - can_earn_multiple: 你可以多次获得 - earned: 获得 - admin: - admin_header: - title: 后台管理 - dashboard: - title: 后台管理 - welcome: 欢迎来到管理后台! - site_statistics: 站点统计 - questions: "问题:" - resolved: "已解决:" - unanswered: "未回答:" - answers: "回答:" - comments: "评论:" - votes: "投票:" - users: "用户:" - flags: "举报:" - reviews: "审查:" - site_health: 网站健康 - version: "版本" - https: "HTTPS:" - upload_folder: "上传文件夹:" - run_mode: "运行模式:" - private: 私有 - public: 公开 - smtp: "SMTP:" - timezone: "时区:" - system_info: 系统信息 - go_version: "Go版本:" - database: "数据库:" - database_size: "数据库大小:" - storage_used: "已用存储空间:" - uptime: "运行时间:" - links: 链接 - plugins: 插件 - github: GitHub - blog: 博客 - contact: 联系 - forum: 论坛 - documents: 文档 - feedback: 用户反馈 - support: 帮助 - review: 审查 - config: 配置 - update_to: 更新到 - latest: 最新版本 - check_failed: 校验失败 - "yes": "是" - "no": "否" - not_allowed: 拒绝 - allowed: 允许 - enabled: 已启用 - disabled: 停用 - writable: 可写 - not_writable: 不可写 - flags: - title: 举报 - pending: 等待处理 - completed: 已完成 - flagged: 被举报内容 - flagged_type: 标记了 {{ type }} - created: 创建于 - action: 操作 - review: 审查 - user_role_modal: - title: 更改用户状态为... - btn_cancel: 取消 - btn_submit: 提交 - new_password_modal: - title: 设置新密码 - form: - fields: - password: - label: 密码 - text: 用户将被退出,需要再次登录。 - msg: 密码的长度必须是8-32个字符。 - btn_cancel: 取消 - btn_submit: 提交 - edit_profile_modal: - title: 编辑资料 - form: - fields: - display_name: - label: 显示名称 - msg_range: 显示名称长度必须为 2-30 个字符。 - username: - label: 用户名 - msg_range: 用户名长度必须为 2-30 个字符。 - email: - label: 电子邮件地址 - msg_invalid: 无效的邮箱地址 - edit_success: 修改成功 - btn_cancel: 取消 - btn_submit: 提交 - user_modal: - title: 添加新用户 - form: - fields: - users: - label: 批量添加用户 - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: 用逗号分隔“name, email, password”,每行一个用户。 - msg: "请输入用户的邮箱,每行一个。" - display_name: - label: 显示名称 - msg: 显示名称长度必须为 2-30 个字符 - email: - label: 邮箱 - msg: 邮箱无效。 - password: - label: 密码 - msg: 密码的长度必须是8-32个字符。 - btn_cancel: 取消 - btn_submit: 提交 - users: - title: 用户 - name: 名称 - email: 邮箱 - reputation: 声望 - created_at: 创建时间 - delete_at: 删除时间 - suspend_at: 封禁时间 - suspend_until: 封禁到期 - status: 状态 - role: 角色 - action: 操作 - change: 更改 - all: 全部 - staff: 工作人员 - more: 更多 - inactive: 不活跃 - suspended: 已封禁 - deleted: 已删除 - normal: 正常 - Moderator: 版主 - Admin: 管理员 - User: 用户 - filter: - placeholder: "按名称筛选,用户:id" - set_new_password: 设置新密码 - edit_profile: 编辑资料 - change_status: 更改状态 - change_role: 更改角色 - show_logs: 显示日志 - add_user: 添加用户 - deactivate_user: - title: 停用用户 - content: 未激活的用户必须重新验证他们的邮箱。 - delete_user: - title: 删除此用户 - content: 确定要删除此用户?此操作无法撤销! - remove: 移除内容 - label: 删除所有问题、 答案、 评论等 - text: 如果你只想删除用户账户,请不要选中此项。 - suspend_user: - title: 挂起此用户 - content: 被封禁的用户将无法登录。 - label: 用户将被封禁多长时间? - forever: 永久 - questions: - page_title: 问题 - unlisted: 已隐藏 - post: 标题 - votes: 得票数 - answers: 回答数 - created: 创建于 - status: 状态 - action: 操作 - change: 更改 - pending: 等待处理 - filter: - placeholder: "按标题过滤,问题:id" - answers: - page_title: 回答 - post: 标题 - votes: 得票数 - created: 创建于 - status: 状态 - action: 操作 - change: 更改 - filter: - placeholder: "按标题筛选,答案:id" - general: - page_title: 一般 - name: - label: 站点名称 - msg: 不能为空 - text: "站点的名称,作为站点的标题。" - site_url: - label: 网站网址 - msg: 网站网址不能为空。 - validate: 请输入一个有效的 URL。 - text: 此网站的地址。 - short_desc: - label: 简短站点描述 - msg: 简短网站描述不能为空。 - text: "简短的标语,作为网站主页的标题(Html 的 title 标签)。" - desc: - label: 站点描述 - msg: 网站描述不能为空。 - text: "使用一句话描述本站,作为网站的描述(Html 的 meta 标签)。" - contact_email: - label: 联系邮箱 - msg: 联系人邮箱不能为空。 - validate: 联系人邮箱无效。 - text: 本网站的主要联系邮箱地址。 - check_update: - label: 软件更新 - text: 自动检查软件更新 - interface: - page_title: 界面 - language: - label: 界面语言 - msg: 不能为空 - text: 设置用户界面语言,在刷新页面后生效。 - time_zone: - label: 时区 - msg: 时区不能为空。 - text: 选择一个与您相同时区的城市。 - avatar: - label: 默认头像 - text: 没有自定义头像的用户。 - gravatar_base_url: - label: Gravatar 根路径 URL - text: Gravatar 提供商的 API 基础的 URL。当为空时忽略。 - smtp: - page_title: SMTP - from_email: - label: 发件人邮箱 - msg: 发件人邮箱不能为空。 - text: 用于发送邮件的地址。 - from_name: - label: 发件人 - msg: 不能为空 - text: 发件人的名字。 - smtp_host: - label: SMTP 主机 - msg: 不能为空 - text: 邮件服务器 - encryption: - label: 加密 - msg: 不能为空 - text: 对于大多数服务器而言,SSL 是推荐开启的。 - ssl: SSL - tls: TLS - none: 无加密 - smtp_port: - label: SMTP 端口 - msg: SMTP 端口必须在 1 ~ 65535 之间。 - text: 邮件服务器的端口号。 - smtp_username: - label: SMTP 用户名 - msg: 不能为空 - smtp_password: - label: SMTP 密码 - msg: 不能为空 - test_email_recipient: - label: 测试收件邮箱 - text: 提供用于接收测试邮件的邮箱地址。 - msg: 测试收件邮箱无效 - smtp_authentication: - label: 启用身份验证 - title: SMTP 身份验证 - msg: 不能为空 - "yes": "是" - "no": "否" - branding: - page_title: 品牌 - logo: - label: 网站标志(Logo) - msg: 图标不能为空。 - text: 在你的网站左上方的Logo图标。使用一个高度为56,长宽比大于3:1的宽长方形图像。如果留空,将显示网站标题文本。 - mobile_logo: - label: 移动端 Logo - text: 在你的网站的移动版上使用的标志。使用一个高度为56的宽矩形图像。如果留空,将使用 "Logo"设置中的图像。 - square_icon: - label: 方形图标 - msg: 方形图标不能为空。 - text: 用作元数据图标的基础的图像。最好是大于512x512。 - favicon: - label: 收藏夹图标 - text: 网站的图标。要在 CDN 正常工作,它必须是 png。 将调整大小到32x32。如果留空,将使用“方形图标”。 - legal: - page_title: 法律条款 - terms_of_service: - label: 服务条款 - text: "您可以在此添加服务内容的条款。如果您已经在别处托管了文档,请在这里提供完整的URL。" - privacy_policy: - label: 隐私政策 - text: "您可以在此添加隐私政策内容。如果您已经在别处托管了文档,请在这里提供完整的URL。" - external_content_display: - label: 外部内容 - text: "内容包括从外部网站嵌入的图像、视频和媒体。" - always_display: 总是显示外部内容 - ask_before_display: 在显示外部内容之前询问 - write: - page_title: 编辑 - min_content: - label: 最小问题长度 - text: 最小允许的问题内容长度(字符)。 - restrict_answer: - title: 回答编辑 - label: 每个用户对于每个问题只能有一个回答 - text: "用户可以使用编辑按钮优化已有的回答" - min_tags: - label: "问题的最少标签数" - text: "一个问题所需标签的最小数量。" - recommend_tags: - label: 推荐标签 - text: "推荐标签将默认显示在下拉列表中。" - msg: - contain_reserved: "推荐标签不能包含保留标签" - required_tag: - title: 设置必填标签 - label: 设置“推荐标签”为必需的标签 - text: "每个新问题必须至少有一个推荐标签。" - reserved_tags: - label: 保留标签 - text: "只有版主才能使用保留的标签。" - image_size: - label: 最大图像大小 (MB) - text: "最大图像上传大小." - attachment_size: - label: 最大附件大小 (MB) - text: "最大附件文件上传大小。" - image_megapixels: - label: 最大图像兆像素 - text: "允许图像的最大兆位数。" - image_extensions: - label: 允许的图像后缀 - text: "允许图像显示的文件扩展名的列表,用英文逗号分隔。" - attachment_extensions: - label: 允许的附件后缀 - text: "允许上传的文件扩展名列表与英文逗号分开。警告:允许上传可能会导致安全问题。" - seo: - page_title: 搜索引擎优化 - permalink: - label: 固定链接 - text: 自定义URL结构可以提高可用性,以及你的链接的向前兼容性。 - robots: - label: robots.txt - text: 这将永久覆盖任何相关的网站设置。 - themes: - page_title: 主题 - themes: - label: 主题 - text: 选择一个现有主题。 - color_scheme: - label: 配色方案 - navbar_style: - label: 导航栏背景样式 - primary_color: - label: 主色调 - text: 修改您主题使用的颜色 - css_and_html: - page_title: CSS 与 HTML - custom_css: - label: 自定义 CSS - text: > - - head: - label: 头部 - text: > - - header: - label: 页眉 - text: > - - footer: - label: 页脚 - text: 这将在 </body> 之前插入。 - sidebar: - label: 侧边栏 - text: 这将插入侧边栏中。 - login: - page_title: 登录 - membership: - title: 会员 - label: 允许新注册 - text: 关闭以防止任何人创建新账户。 - email_registration: - title: 邮箱注册 - label: 允许邮箱注册 - text: 关闭以阻止任何人通过邮箱创建新账户。 - allowed_email_domains: - title: 允许的邮箱域 - text: 允许注册账户的邮箱域。每行一个域名。留空时忽略。 - private: - title: 非公开的 - label: 需要登录 - text: 只有登录用户才能访问这个社区。 - password_login: - title: 密码登录 - label: 允许使用邮箱和密码登录 - text: "警告:如果您未配置过其他登录方式,关闭密码登录后您则可能无法登录。" - installed_plugins: - title: 已安装插件 - plugin_link: 插件扩展功能。您可以在<1>插件仓库中找到插件。 - filter: - all: 全部 - active: 已启用 - inactive: 未启用 - outdated: 已过期 - plugins: - label: 插件 - text: 选择一个现有的插件。 - name: 名称 - version: 版本 - status: 状态 - action: 操作 - deactivate: 停用 - activate: 启用 - settings: 设置 - settings_users: - title: 用户 - avatar: - label: 默认头像 - text: 没有自定义头像的用户。 - gravatar_base_url: - label: Gravatar 根路径 URL - text: Gravatar 提供商的 API 基础的 URL。当为空时忽略。 - profile_editable: - title: 个人资料可编辑 - allow_update_display_name: - label: 允许用户修改显示名称 - allow_update_username: - label: 允许用户修改用户名 - allow_update_avatar: - label: 允许用户修改个人头像 - allow_update_bio: - label: 允许用户修改个人介绍 - allow_update_website: - label: 允许用户修改个人主页网址 - allow_update_location: - label: 允许用户更改位置 - privilege: - title: 特权 - level: - label: 级别所需声望 - text: 选择特权所需的声望值 - msg: - should_be_number: 输入必须是数字 - number_larger_1: 数字应该大于等于 1 - badges: - action: 操作 - active: 活跃的 - activate: 启用 - all: 全部 - awards: 奖项 - deactivate: 取消激活 - filter: - placeholder: 按名称筛选,或使用 badge:id - group: 组 - inactive: 未启用 - name: 名字 - show_logs: 显示日志 - status: 状态 - title: 徽章 - form: - optional: (选填) - empty: 不能为空 - invalid: 是无效的 - btn_submit: 保存 - not_found_props: "所需属性 {{ key }} 未找到。" - select: 选择 - page_review: - review: 评论 - proposed: 提案 - question_edit: 问题编辑 - answer_edit: 回答编辑 - tag_edit: '标签管理: 编辑标签' - edit_summary: 编辑备注 - edit_question: 编辑问题 - edit_answer: 编辑回答 - edit_tag: 编辑标签 - empty: 没有剩余的审核任务。 - approve_revision_tip: 您是否批准此修订? - approve_flag_tip: 您是否批准此举报? - approve_post_tip: 您是否批准此帖子? - approve_user_tip: 您是否批准此修订? - suggest_edits: 建议的编辑 - flag_post: 举报帖子 - flag_user: 举报用户 - queued_post: 排队的帖子 - queued_user: 排队用户 - filter_label: 类型 - reputation: 声望值 - flag_post_type: 举报这个帖子的类型是 {{ type }} - flag_user_type: 举报这个用户的类型是 {{ type }} - edit_post: 编辑帖子 - list_post: 文章列表 - unlist_post: 隐藏的帖子 - timeline: - undeleted: 取消删除 - deleted: 删除 - downvote: 反对 - upvote: 点赞 - accept: 采纳 - cancelled: 已取消 - commented: '评论:' - rollback: 回滚 - edited: 最后编辑于 - answered: 回答于 - asked: 提问于 - closed: 关闭 - reopened: 重新开启 - created: 创建于 - pin: 已置顶 - unpin: 取消置頂 - show: 已显示 - hide: 已隐藏 - title: "历史记录" - tag_title: "时间线" - show_votes: "显示投票" - n_or_a: N/A - title_for_question: "时间线" - title_for_answer: "{{ title }} 的 {{ author }} 回答时间线" - title_for_tag: "时间线" - datetime: 日期时间 - type: 类型 - by: 由 - comment: 评论 - no_data: "空空如也" - users: - title: 用户 - users_with_the_most_reputation: 本周声望最高的用户 - users_with_the_most_vote: 本周投票最多的用户 - staffs: 我们的社区工作人员 - reputation: 声望值 - votes: 投票 - prompt: - leave_page: 确定要离开此页面? - changes_not_save: 您的更改尚未保存 - draft: - discard_confirm: 您确定要丢弃您的草稿吗? - messages: - post_deleted: 该帖子已被删除。 - post_cancel_deleted: 此帖子已被删除 - post_pin: 该帖子已被置顶。 - post_unpin: 该帖子已被取消置顶。 - post_hide_list: 此帖子已经从列表中隐藏。 - post_show_list: 该帖子已显示到列表中。 - post_reopen: 这个帖子已被重新打开. - post_list: 这个帖子已经被显示 - post_unlist: 这个帖子已经被隐藏 - post_pending: 您的帖子正在等待审核。它将在它获得批准后可见。 - post_closed: 此帖已关闭。 - answer_deleted: 该回答已被删除. - answer_cancel_deleted: 此答案已取消删除。 - change_user_role: 此用户的角色已被更改。 - user_inactive: 此用户已经处于未激活状态。 - user_normal: 此用户已经是正常的。 - user_suspended: 此用户已被封禁。 - user_deleted: 此用户已被删除 - badge_activated: 此徽章已被激活。 - badge_inactivated: 此徽章已被禁用。 - users_deleted: 这些用户已被删除。 - posts_deleted: 这些问题已被删除。 - answers_deleted: 这些答案已被删除。 - copy: 复制到剪贴板 - copied: 已复制 - external_content_warning: 外部图像/媒体未显示。 - - diff --git a/data/i18n/zh_TW.yaml b/data/i18n/zh_TW.yaml deleted file mode 100644 index f0d254de9..000000000 --- a/data/i18n/zh_TW.yaml +++ /dev/null @@ -1,2359 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# The following fields are used for back-end -backend: - base: - success: - other: 成功。 - unknown: - other: 未知的錯誤。 - request_format_error: - other: 要求格式錯誤。 - unauthorized_error: - other: 未授權。 - database_error: - other: 資料伺服器錯誤。 - forbidden_error: - other: 已拒絕存取。 - duplicate_request_error: - other: 重複送出。 - action: - report: - other: 檢舉 - edit: - other: 編輯 - delete: - other: 删除 - close: - other: 關閉 - reopen: - other: 再次開啟。 - forbidden_error: - other: 已拒絕存取。 - pin: - other: 置頂 - hide: - other: 不公開 - unpin: - other: 取消置頂 - show: - other: 清單 - invite_someone_to_answer: - other: 編輯 - undelete: - other: 還原 - merge: - other: 合併 - role: - name: - user: - other: 使用者 - admin: - other: 管理員 - moderator: - other: 版主 - description: - user: - other: 預設沒有特別閱讀權限。 - admin: - other: 擁有存取此網站的全部權限。 - moderator: - other: 可以存取除了管理員設定以外的所有貼文。 - privilege: - level_1: - description: - other: Level 1 (less reputation required for private team, group) - level_2: - description: - other: Level 2 (low reputation required for startup community) - level_3: - description: - other: Level 3 (high reputation required for mature community) - level_custom: - description: - other: Custom Level - rank_question_add_label: - other: Ask question - rank_answer_add_label: - other: Write answer - rank_comment_add_label: - other: 寫留言 - rank_report_add_label: - other: Flag - rank_comment_vote_up_label: - other: Upvote comment - rank_link_url_limit_label: - other: Post more than 2 links at a time - rank_question_vote_up_label: - other: Upvote question - rank_answer_vote_up_label: - other: Upvote answer - rank_question_vote_down_label: - other: Downvote question - rank_answer_vote_down_label: - other: Downvote answer - rank_invite_someone_to_answer_label: - other: Invite someone to answer - rank_tag_add_label: - other: Create new tag - rank_tag_edit_label: - other: Edit tag description (need to review) - rank_question_edit_label: - other: Edit other's question (need to review) - rank_answer_edit_label: - other: Edit other's answer (need to review) - rank_question_edit_without_review_label: - other: Edit other's question without review - rank_answer_edit_without_review_label: - other: Edit other's answer without review - rank_question_audit_label: - other: Review question edits - rank_answer_audit_label: - other: Review answer edits - rank_tag_audit_label: - other: Review tag edits - rank_tag_edit_without_review_label: - other: Edit tag description without review - rank_tag_synonym_label: - other: Manage tag synonyms - email: - other: 電子郵件 - e_mail: - other: 電子郵件 - password: - other: 密碼 - pass: - other: 密碼 - old_pass: - other: 目前密碼 - original_text: - other: 此貼文 - email_or_password_wrong_error: - other: 電郵和密碼不匹配。 - error: - common: - invalid_url: - other: URL 無效。 - status_invalid: - other: 無效狀態。 - password: - space_invalid: - other: 密碼不能包含空白字元。 - admin: - cannot_update_their_password: - other: 你不能修改自己的密码。 - cannot_edit_their_profile: - other: You cannot modify your profile. - cannot_modify_self_status: - other: You cannot modify your status. - email_or_password_wrong: - other: 電郵和密碼不匹配。 - answer: - not_found: - other: 未發現答案。 - cannot_deleted: - other: 沒有刪除權限。 - cannot_update: - other: 沒有更新權限。 - question_closed_cannot_add: - other: Questions are closed and cannot be added. - content_cannot_empty: - other: Answer content cannot be empty. - comment: - edit_without_permission: - other: 不允許編輯留言。 - not_found: - other: 未發現留言。 - cannot_edit_after_deadline: - other: 這則留言時間過久,無法修改。 - content_cannot_empty: - other: Comment content cannot be empty. - email: - duplicate: - other: 這個電子郵件地址已被使用。 - need_to_be_verified: - other: 需驗證電子郵件地址。 - verify_url_expired: - other: 電子郵件地址驗證網址已過期,請重寄電子郵件。 - illegal_email_domain_error: - other: Email is not allowed from that email domain. Please use another one. - lang: - not_found: - other: 未找到語言檔。 - object: - captcha_verification_failed: - other: 驗證碼錯誤。 - disallow_follow: - other: 你不被允許追蹤。 - disallow_vote: - other: 你無法投票。 - disallow_vote_your_self: - other: 你不能為自己的貼文投票。 - not_found: - other: 找不到物件。 - verification_failed: - other: 驗證失敗。 - email_or_password_incorrect: - other: 電子郵件地址和密碼不匹配。 - old_password_verification_failed: - other: 舊密碼驗證失敗 - new_password_same_as_previous_setting: - other: 新密碼與先前的一樣。 - already_deleted: - other: 這則貼文已被刪除。 - meta: - object_not_found: - other: Meta object not found - question: - already_deleted: - other: This post has been deleted. - under_review: - other: Your post is awaiting review. It will be visible after it has been approved. - not_found: - other: 找不到問題。 - cannot_deleted: - other: 無刪除權限。 - cannot_close: - other: 無關閉權限。 - cannot_update: - other: 無更新權限。 - content_cannot_empty: - other: Content cannot be empty. - content_less_than_minimum: - other: Not enough content entered. - rank: - fail_to_meet_the_condition: - other: Reputation rank fail to meet the condition. - vote_fail_to_meet_the_condition: - other: Thanks for the feedback. You need at least {{.Rank}} reputation to cast a vote. - no_enough_rank_to_operate: - other: You need at least {{.Rank}} reputation to do this. - report: - handle_failed: - other: 報告處理失敗。 - not_found: - other: 找不到報告。 - tag: - already_exist: - other: Tag already exists. - not_found: - other: 找不到標籤。 - recommend_tag_not_found: - other: Recommend tag is not exist. - recommend_tag_enter: - other: 請輸入至少一個必需的標籤。 - not_contain_synonym_tags: - other: 不應包含同義詞標籤。 - cannot_update: - other: 沒有權限更新。 - is_used_cannot_delete: - other: You cannot delete a tag that is in use. - cannot_set_synonym_as_itself: - other: 你不能將目前標籤的同義詞設定為本身。 - minimum_count: - other: Not enough tags were entered. - smtp: - config_from_name_cannot_be_email: - other: The from name cannot be a email address. - theme: - not_found: - other: 未找到主題。 - revision: - review_underway: - other: 目前無法編輯,有一個版本在審查佇列中。 - no_permission: - other: No permission to revise. - user: - external_login_missing_user_id: - other: The third-party platform does not provide a unique UserID, so you cannot login, please contact the website administrator. - external_login_unbinding_forbidden: - other: Please set a login password for your account before you remove this login. - email_or_password_wrong: - other: - other: 電子郵箱和密碼不匹配。 - not_found: - other: 未找到使用者。 - suspended: - other: 該使用者已被停權。 - username_invalid: - other: 使用者名稱無效。 - username_duplicate: - other: 使用者名稱已被使用。 - set_avatar: - other: 大頭照設定錯誤。 - cannot_update_your_role: - other: 您不能修改自己的角色。 - not_allowed_registration: - other: Currently the site is not open for registration. - not_allowed_login_via_password: - other: Currently the site is not allowed to login via password. - access_denied: - other: Access denied - page_access_denied: - other: You do not have access to this page. - add_bulk_users_format_error: - other: "Error {{.Field}} format near '{{.Content}}' at line {{.Line}}. {{.ExtraMessage}}" - add_bulk_users_amount_error: - other: "The number of users you add at once should be in the range of 1-{{.MaxAmount}}." - status_suspended_forever: - other: "This user was suspended forever. This user doesn't meet a community guideline." - status_suspended_until: - other: "This user was suspended until {{.SuspendedUntil}}. This user doesn't meet a community guideline." - status_deleted: - other: "This user was deleted." - status_inactive: - other: "This user is inactive." - config: - read_config_failed: - other: 讀取組態失敗 - database: - connection_failed: - other: 資料庫連線失敗 - create_table_failed: - other: 表建立失敗 - install: - create_config_failed: - other: 無法建立 config.yaml 檔。 - upload: - unsupported_file_format: - other: 不支援的檔案格式。 - site_info: - config_not_found: - other: Site config not found. - badge: - object_not_found: - other: Badge object not found - reason: - spam: - name: - other: 垃圾訊息 - desc: - other: This post is an advertisement, or vandalism. It is not useful or relevant to the current topic. - rude_or_abusive: - name: - other: rude or abusive - desc: - other: "A reasonable person would find this content inappropriate for respectful discourse." - a_duplicate: - name: - other: a duplicate - desc: - other: This question has been asked before and already has an answer. - placeholder: - other: Enter the existing question link - not_a_answer: - name: - other: not an answer - desc: - other: "This was posted as an answer, but it does not attempt to answer the question. It should possibly be an edit, a comment, another question,or deleted altogether." - no_longer_needed: - name: - other: no longer needed - desc: - other: This comment is outdated, conversational or not relevant to this post. - something: - name: - other: something else - desc: - other: This post requires staff attention for another reason not listed above. - placeholder: - other: Let us know specifically what you are concerned about - community_specific: - name: - other: a community-specific reason - desc: - other: This question doesn't meet a community guideline. - not_clarity: - name: - other: needs details or clarity - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - looks_ok: - name: - other: looks OK - desc: - other: This post is good as-is and not low quality. - needs_edit: - name: - other: needs edit, and I did it - desc: - other: Improve and correct problems with this post yourself. - needs_close: - name: - other: 需關閉 - desc: - other: A closed question can't answer, but still can edit, vote and comment. - needs_delete: - name: - other: needs delete - desc: - other: This post will be deleted. - question: - close: - duplicate: - name: - other: 垃圾訊息 - desc: - other: 此問題以前就有人問過,而且已經有了答案。 - guideline: - name: - other: 一个社群特定原因 - desc: - other: 此問題不符合社群準則。 - multiple: - name: - other: 需要細節或明晰 - desc: - other: This question currently includes multiple questions in one. It should focus on one problem only. - other: - name: - other: 其他原因 - desc: - other: 這個帖子需要上面沒有列出的另一個原因。 - operation_type: - asked: - other: 提問於 - answered: - other: 回答於 - modified: - other: 修改於 - deleted_title: - other: Deleted question - questions_title: - other: Questions - tag: - tags_title: - other: Tags - no_description: - other: The tag has no description. - notification: - action: - update_question: - other: 更新了問題 - answer_the_question: - other: 回答了問題 - update_answer: - other: 更新了答案 - accept_answer: - other: 已接受的回答 - comment_question: - other: 留言了問題 - comment_answer: - other: 留言了答案 - reply_to_you: - other: 回覆了你 - mention_you: - other: 提到了你 - your_question_is_closed: - other: 你的問題已被關閉 - your_question_was_deleted: - other: 你的問題已被刪除 - your_answer_was_deleted: - other: 你的答案已被刪除 - your_comment_was_deleted: - other: 你的留言已被刪除 - up_voted_question: - other: upvoted question - down_voted_question: - other: downvoted question - up_voted_answer: - other: upvoted answer - down_voted_answer: - other: downvoted answer - up_voted_comment: - other: upvoted comment - invited_you_to_answer: - other: invited you to answer - earned_badge: - other: You've earned the "{{.BadgeName}}" badge - email_tpl: - change_email: - title: - other: "[{{.SiteName}}] Confirm your new email address" - body: - other: "Confirm your new email address for {{.SiteName}} by clicking on the following link:
        \n{{.ChangeEmailUrl}}

        \n\nIf you did not request this change, please ignore this email.

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - new_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} answered your question" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.AnswerSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - invited_you_to_answer: - title: - other: "[{{.SiteName}}] {{.DisplayName}} invited you to answer" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        I think you may know the answer.

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_comment: - title: - other: "[{{.SiteName}}] {{.DisplayName}} commented on your post" - body: - other: "{{.QuestionTitle}}

        \n\n{{.DisplayName}}:
        \n
        {{.CommentSummary}}

        \nView it on {{.SiteName}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - new_question: - title: - other: "[{{.SiteName}}] New question: {{.QuestionTitle}}" - body: - other: "{{.QuestionTitle}}
        \n{{.Tags}}

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen.

        \n\nUnsubscribe" - pass_reset: - title: - other: "[{{.SiteName }}] Password reset" - body: - other: "Somebody asked to reset your password on {{.SiteName}}.

        \n\nIf it was not you, you can safely ignore this email.

        \n\nClick the following link to choose a new password:
        \n{{.PassResetUrl}}\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - register: - title: - other: "[{{.SiteName}}] Confirm your new account" - body: - other: "Welcome to {{.SiteName}}!

        \n\nClick the following link to confirm and activate your new account:
        \n{{.RegisterUrl}}

        \n\nIf the above link is not clickable, try copying and pasting it into the address bar of your web browser.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - test: - title: - other: "[{{.SiteName}}] Test Email" - body: - other: "This is a test email.\n

        \n\n--
        \nNote: This is an automatic system email, please do not reply to this message as your response will not be seen." - action_activity_type: - upvote: - other: upvote - upvoted: - other: upvoted - downvote: - other: downvote - downvoted: - other: downvoted - accept: - other: 採納 - accepted: - other: 已採納 - edit: - other: 編輯 - review: - queued_post: - other: Queued post - flagged_post: - other: Flagged post - suggested_post_edit: - other: Suggested edits - reaction: - tooltip: - other: "{{ .Names }} and {{ .Count }} more..." - badge: - default_badges: - autobiographer: - name: - other: Autobiographer - desc: - other: Filled out profile information. - certified: - name: - other: Certified - desc: - other: Completed our new user tutorial. - editor: - name: - other: 編輯者 - desc: - other: First post edit. - first_flag: - name: - other: First Flag - desc: - other: First flagged a post. - first_upvote: - name: - other: First Upvote - desc: - other: First up voted a post. - first_link: - name: - other: 首個連結 - desc: - other: First added a link to another post. - first_reaction: - name: - other: First Reaction - desc: - other: First reacted to the post. - first_share: - name: - other: First Share - desc: - other: First shared a post. - scholar: - name: - other: Scholar - desc: - other: Asked a question and accepted an answer. - commentator: - name: - other: Commentator - desc: - other: Leave 5 comments. - new_user_of_the_month: - name: - other: New User of the Month - desc: - other: Outstanding contributions in their first month. - read_guidelines: - name: - other: Read Guidelines - desc: - other: Read the [community guidelines]. - reader: - name: - other: 閱讀者 - desc: - other: Read every answers in a topic with more than 10 answers. - welcome: - name: - other: 歡迎 - desc: - other: Received a up vote. - nice_share: - name: - other: Nice Share - desc: - other: Shared a post with 25 unique visitors. - good_share: - name: - other: Good Share - desc: - other: Shared a post with 300 unique visitors. - great_share: - name: - other: Great Share - desc: - other: Shared a post with 1000 unique visitors. - out_of_love: - name: - other: Out of Love - desc: - other: Used 50 up votes in a day. - higher_love: - name: - other: Higher Love - desc: - other: Used 50 up votes in a day 5 times. - crazy_in_love: - name: - other: Crazy in Love - desc: - other: Used 50 up votes in a day 20 times. - promoter: - name: - other: Promoter - desc: - other: Invited a user. - campaigner: - name: - other: Campaigner - desc: - other: Invited 3 basic users. - champion: - name: - other: Champion - desc: - other: Invited 5 members. - thank_you: - name: - other: 感謝 - desc: - other: Has 20 up voted posts and gave 10 up votes. - gives_back: - name: - other: Gives Back - desc: - other: Has 100 up voted posts and gave 100 up votes. - empathetic: - name: - other: Empathetic - desc: - other: Has 500 up voted posts and gave 1000 up votes. - enthusiast: - name: - other: Enthusiast - desc: - other: Visited 10 consecutive days. - aficionado: - name: - other: Aficionado - desc: - other: Visited 100 consecutive days. - devotee: - name: - other: Devotee - desc: - other: Visited 365 consecutive days. - anniversary: - name: - other: Anniversary - desc: - other: Active member for a year, posted at least once. - appreciated: - name: - other: Appreciated - desc: - other: Received 1 up vote on 20 posts. - respected: - name: - other: Respected - desc: - other: Received 2 up votes on 100 posts. - admired: - name: - other: Admired - desc: - other: Received 5 up votes on 300 posts. - solved: - name: - other: Solved - desc: - other: Have an answer be accepted. - guidance_counsellor: - name: - other: Guidance Counsellor - desc: - other: Have 10 answers be accepted. - know_it_all: - name: - other: Know-it-All - desc: - other: Have 50 answers be accepted. - solution_institution: - name: - other: Solution Institution - desc: - other: Have 150 answers be accepted. - nice_answer: - name: - other: Nice Answer - desc: - other: Answer score of 10 or more. - good_answer: - name: - other: Good Answer - desc: - other: Answer score of 25 or more. - great_answer: - name: - other: Great Answer - desc: - other: Answer score of 50 or more. - nice_question: - name: - other: Nice Question - desc: - other: Question score of 10 or more. - good_question: - name: - other: Good Question - desc: - other: Question score of 25 or more. - great_question: - name: - other: Great Question - desc: - other: Question score of 50 or more. - popular_question: - name: - other: Popular Question - desc: - other: Question with 500 views. - notable_question: - name: - other: Notable Question - desc: - other: Question with 1,000 views. - famous_question: - name: - other: Famous Question - desc: - other: Question with 5,000 views. - popular_link: - name: - other: Popular Link - desc: - other: Posted an external link with 50 clicks. - hot_link: - name: - other: Hot Link - desc: - other: Posted an external link with 300 clicks. - famous_link: - name: - other: Famous Link - desc: - other: Posted an external link with 100 clicks. - default_badge_groups: - getting_started: - name: - other: Getting Started - community: - name: - other: Community - posting: - name: - other: Posting -# The following fields are used for interface presentation(Front-end) -ui: - how_to_format: - title: 如何設定文字格式 - desc: >- -
        • mention a post: #post_id

        • to make links

          <https://url.com>

          [Title](https://url.com)
        • put returns between paragraphs

        • _italic_ or **bold**

        • indent code by 4 spaces

        • quote by placing > at start of line

        • backtick escapes `like _this_`

        • create code fences with backticks `

          ```
          code here
          ```
        - pagination: - prev: 上一頁 - next: 下一頁 - page_title: - question: 問題 - questions: 問題 - tag: 標籤 - tags: 標籤 - tag_wiki: 標籤 wiki - create_tag: Create Tag - edit_tag: 編輯標籤 - ask_a_question: Create Question - edit_question: 編輯問題 - edit_answer: 編輯回答 - search: 搜尋 - posts_containing: 包含的貼文 - settings: 設定 - notifications: 通知 - login: 登入 - sign_up: 註冊 - account_recovery: 帳號恢復 - account_activation: 帳號啟用 - confirm_email: 確認電子郵件 - account_suspended: 帳號已被停權 - admin: 後台管理 - change_email: 修改電子郵件 - install: Answer 安裝 - upgrade: Answer 升級 - maintenance: 網站維護 - users: 使用者 - oauth_callback: Processing - http_404: HTTP 錯誤 404 - http_50X: HTTP 錯誤 500 - http_403: HTTP 錯誤 403 - logout: 登出 - posts: Posts - notifications: - title: 通知 - inbox: 收件夾 - achievement: 成就 - new_alerts: New alerts - all_read: 全部標記為已讀 - show_more: 顯示更多 - someone: Someone - inbox_type: - all: 所有 - posts: Posts - invites: Invites - votes: Votes - answer: Answer - question: Question - badge_award: Badge - suspended: - title: 您的帳號已被停權 - until_time: "你的帳號被停權至{{ time }}。" - forever: 你的帳號已被永久停權。 - end: 違反了我們的社群準則。 - contact_us: Contact us - editor: - blockquote: - text: 引用 - bold: - text: 粗體 - chart: - text: 圖表 - flow_chart: 流程圖 - sequence_diagram: 時序圖 - class_diagram: 類圖 - state_diagram: 狀態圖 - entity_relationship_diagram: 實體關係圖 - user_defined_diagram: 用戶自定義圖表 - gantt_chart: 甘特圖 - pie_chart: 圓餅圖 - code: - text: 代碼示例 - add_code: 添加代碼示例 - form: - fields: - code: - label: 代碼塊 - msg: - empty: 代碼不能為空 - language: - label: 語言 - placeholder: 自動偵測 - btn_cancel: 取消 - btn_confirm: 添加 - formula: - text: 公式 - options: - inline: 內聯公式 - block: 公式塊 - heading: - text: 標題 - options: - h1: 標題 1 - h2: 標題 2 - h3: 標題 3 - h4: 標題 4 - h5: 標題 5 - h6: 標題 6 - help: - text: 幫助 - hr: - text: Horizontal rule - image: - text: 圖片 - add_image: 添加圖片 - tab_image: 上傳圖片 - form_image: - fields: - file: - label: 圖檔 - btn: 選擇圖片 - msg: - empty: 文件不能為空。 - only_image: 只能上傳圖片文件。 - max_size: File size cannot exceed {{size}} MB. - desc: - label: 圖片描述 - tab_url: 圖片地址 - form_url: - fields: - url: - label: 圖片地址 - msg: - empty: 圖片地址不能為空 - name: - label: 圖片描述 - btn_cancel: 取消 - btn_confirm: 添加 - uploading: 上傳中... - indent: - text: 增加縮排 - outdent: - text: 減少縮排 - italic: - text: 斜體 - link: - text: 超連結 - add_link: 添加超連結 - form: - fields: - url: - label: 連結 - msg: - empty: 連結不能為空。 - name: - label: 描述 - btn_cancel: 取消 - btn_confirm: 添加 - ordered_list: - text: Numbered list - unordered_list: - text: Bulleted list - table: - text: 表格 - heading: 表頭 - cell: 單元格 - file: - text: Attach files - not_supported: "Don’t support that file type. Try again with {{file_type}}." - max_size: "Attach files size cannot exceed {{size}} MB." - close_modal: - title: 關閉原因是... - btn_cancel: 取消 - btn_submit: 提交 - remark: - empty: 不能為空。 - msg: - empty: 請選擇一個原因。 - report_modal: - flag_title: 報告為... - close_title: 關閉原因是... - review_question_title: 審核問題 - review_answer_title: 審核回答 - review_comment_title: 審核評論 - btn_cancel: 取消 - btn_submit: 提交 - remark: - empty: 不能為空 - msg: - empty: 請選擇一個原因。 - not_a_url: URL format is incorrect. - url_not_match: URL origin does not match the current website. - tag_modal: - title: 創建新標籤 - form: - fields: - display_name: - label: Display name - msg: - empty: 顯示名稱不能為空。 - range: 顯示名稱不能超過 35 個字符。 - slug_name: - label: URL slug - desc: URL slug up to 35 characters. - msg: - empty: URL 固定連結不能為空。 - range: URL 固定連結不能超過 35 個字元。 - character: URL 固定連結包含非法字元。 - desc: - label: 描述 - revision: - label: Revision - edit_summary: - label: Edit summary - placeholder: >- - Briefly explain your changes (corrected spelling, fixed grammar, improved formatting) - btn_cancel: 取消 - btn_submit: 提交 - btn_post: Post new tag - tag_info: - created_at: 創建於 - edited_at: 編輯於 - history: 歷史 - synonyms: - title: 同義詞 - text: 以下標籤等同於 - empty: 此標籤目前沒有同義詞。 - btn_add: 添加同義詞 - btn_edit: 編輯 - btn_save: 儲存 - synonyms_text: 以下標籤等同於 - delete: - title: 刪除標籤 - tip_with_posts: >- -

        We do not allow deleting tag with posts.

        Please remove this tag from the posts first.

        - tip_with_synonyms: >- -

        We do not allow deleting tag with synonyms.

        Please remove the synonyms from this tag first.

        - tip: 你確定要刪除嗎? - close: 關閉 - merge: - title: Merge tag - source_tag_title: Source tag - source_tag_description: The source tag and its associated data will be remapped to the target tag. - target_tag_title: Target tag - target_tag_description: A synonym between these two tags will be created after merging. - no_results: No tags matched - btn_submit: 送出 - btn_close: 關閉 - edit_tag: - title: 編輯標籤 - default_reason: 編輯標籤 - default_first_reason: Add tag - btn_save_edits: 儲存更改 - btn_cancel: 取消 - dates: - long_date: MM月DD日 - long_date_with_year: "YYYY年MM月DD日" - long_date_with_time: "YYYY 年 MM 月 DD 日 HH:mm" - now: 剛剛 - x_seconds_ago: "{{count}} 秒前" - x_minutes_ago: "{{count}} 分鐘前" - x_hours_ago: "{{count}} 小時前" - hour: 小時 - day: 天 - hours: hours - days: days - month: month - months: months - year: year - reaction: - heart: heart - smile: smile - frown: frown - btn_label: add or remove reactions - undo_emoji: undo {{ emoji }} reaction - react_emoji: react with {{ emoji }} - unreact_emoji: unreact with {{ emoji }} - comment: - btn_add_comment: 添加評論 - reply_to: 回復 - btn_reply: 回復 - btn_edit: 編輯 - btn_delete: 刪除 - btn_flag: 舉報 - btn_save_edits: 保存 - btn_cancel: 取消 - show_more: "{{count}} 條剩餘評論" - tip_question: >- - 通过評論询问更多问题或提出改進建議。避免在評論中回答問題。 - tip_answer: >- - 使用評論回復其他用戶或通知他們进行更改。如果你要添加新的信息,請編輯你的帖子,而不是發表評論。 - tip_vote: It adds something useful to the post - edit_answer: - title: 編輯回答 - default_reason: 編輯回答 - default_first_reason: Add answer - form: - fields: - revision: - label: 編輯歷史 - answer: - label: 回答內容 - feedback: - characters: 內容必須至少6個字元長度。 - edit_summary: - label: Edit summary - placeholder: >- - 簡單描述更改原因 (錯別字、文字表達、格式等等) - btn_save_edits: 儲存更改 - btn_cancel: 取消 - tags: - title: 標籤 - sort_buttons: - popular: 熱門 - name: 名稱 - newest: Newest - button_follow: 關注 - button_following: 已關注 - tag_label: 個問題 - search_placeholder: 通過標籤名過濾 - no_desc: 此標籤無描述。 - more: 更多 - wiki: Wiki - ask: - title: Create Question - edit_title: 編輯問題 - default_reason: 編輯問題 - default_first_reason: Create question - similar_questions: 相似的問題 - form: - fields: - revision: - label: 編輯歷史 - title: - label: 標題 - placeholder: What's your topic? Be specific. - msg: - empty: 標題不能為空 - range: 標題最多 150 個字元 - body: - label: 正文 - msg: - empty: 正文不能爲空。 - hint: - optional_body: Describe what the question is about. - minimum_characters: "Describe what the question is about, at least {{min_content_length}} characters are required." - tags: - label: 標籤 - msg: - empty: 標籤不能為空 - answer: - label: 回答內容 - msg: - empty: 回答內容不能為空 - edit_summary: - label: Edit summary - placeholder: >- - 簡單描述更改原因 (錯別字、文字表達、格式等等) - btn_post_question: 提出問題 - btn_save_edits: 儲存更改 - answer_question: 回答您自己的問題 - post_question&answer: 發布您的問題和答案 - tag_selector: - add_btn: 建立標籤 - create_btn: 建立新標籤 - search_tag: 搜尋標籤 - hint: Describe what your content is about, at least one tag is required. - hint_zero_tags: Describe what your content is about. - hint_more_than_one_tag: "Describe what your content is about, at least {{min_tags_number}} tags are required." - no_result: 沒有匹配的標籤 - tag_required_text: 必填標籤 (至少一個) - header: - nav: - question: 問題 - tag: 標籤 - user: 用戶 - badges: Badges - profile: 用戶主頁 - setting: 帳號設置 - logout: 登出 - admin: 後台管理 - review: 審查 - bookmark: Bookmarks - moderation: Moderation - search: - placeholder: 搜尋 - footer: - build_on: Powered by <1> Apache Answer - upload_img: - name: 更改 - loading: 讀取中... - pic_auth_code: - title: 驗證碼 - placeholder: 輸入上面的文字 - msg: - empty: 验证码不能為空 - inactive: - first: >- - 就差一步!我們寄送了一封啟用電子郵件到 {{mail}}。請按照郵件中的說明啟用您的帳戶。 - info: "如果沒有收到,請檢查您的垃圾郵件文件夾。" - another: >- - 我們向您發送了另一封啟用電子郵件,地址為 {{mail}}。它可能需要幾分鐘才能到達;請務必檢查您的垃圾郵件文件夾。 - btn_name: 重新發送啟用郵件 - change_btn_name: 更改郵箱 - msg: - empty: 不能為空 - resend_email: - url_label: Are you sure you want to resend the activation email? - url_text: You can also give the activation link above to the user. - login: - login_to_continue: 登入以繼續 - info_sign: 沒有帳戶?<1>註冊 - info_login: 已經有一個帳號?<1>登入 - agreements: 登入即表示您同意<1>隱私政策和<3>服務條款。 - forgot_pass: 忘記密碼? - name: - label: 名稱 - msg: - empty: 名稱不能為空 - range: Name must be between 2 to 30 characters in length. - character: 'Must use the character set "a-z", "0-9", " - . _"' - email: - label: 郵箱 - msg: - empty: 郵箱不能為空 - password: - label: 密碼 - msg: - empty: 密碼不能為空 - different: 兩次輸入密碼不一致 - account_forgot: - page_title: 忘記密碼 - btn_name: 向我發送恢復郵件 - send_success: >- - 如果帳號與{{mail}}相符,您應該很快就會收到一封電子郵件,說明如何重置您的密碼。 - email: - label: 郵箱 - msg: - empty: 郵箱不能為空 - change_email: - btn_cancel: 取消 - btn_update: 更新電子郵件地址 - send_success: >- - 如果帳號與{{mail}}相符,您應該很快就會收到一封電子郵件,說明如何重置您的密碼。 - email: - label: New email - msg: - empty: 郵箱不能為空 - oauth: - connect: Connect with {{ auth_name }} - remove: Remove {{ auth_name }} - oauth_bind_email: - subtitle: Add a recovery email to your account. - btn_update: Update email address - email: - label: Email - msg: - empty: Email cannot be empty. - modal_title: Email already existes. - modal_content: This email address already registered. Are you sure you want to connect to the existing account? - modal_cancel: Change email - modal_confirm: Connect to the existing account - password_reset: - page_title: 密碼重置 - btn_name: 重置我的密碼 - reset_success: >- - 你已經成功更改密碼,將返回登入頁面 - link_invalid: >- - 抱歉,此密碼重置連結已失效。也許是你已經重置過密碼了? - to_login: 前往登入頁面 - password: - label: 密碼 - msg: - empty: 密碼不能為空 - length: 密碼長度在8-32個字元之間 - different: 兩次輸入密碼不一致 - password_confirm: - label: Confirm new password - settings: - page_title: 設置 - goto_modify: Go to modify - nav: - profile: 我的資料 - notification: 通知 - account: 帳號 - interface: 界面 - profile: - heading: 個人資料 - btn_name: 保存 - display_name: - label: Display name - msg: 顯示名稱不能為空。 - msg_range: Display name must be 2-30 characters in length. - username: - label: 用戶名 - caption: 用戶之間可以通過 "@用戶名" 進行交互。 - msg: 用戶名不能為空 - msg_range: Username must be 2-30 characters in length. - character: 'Must use the character set "a-z", "0-9", "- . _"' - avatar: - label: Profile image - gravatar: 頭像 - gravatar_text: You can change image on - custom: 自定義 - custom_text: 您可以上傳您的圖片。 - default: 系統 - msg: 請上傳頭像 - bio: - label: About me - website: - label: 網站 - placeholder: "https://example.com" - msg: 網站格式不正確 - location: - label: 位置 - placeholder: "城市, 國家" - notification: - heading: 通知 - turn_on: Turn on - inbox: - label: Email notifications - description: Answers to your questions, comments, invites, and more. - all_new_question: - label: All new questions - description: Get notified of all new questions. Up to 50 questions per week. - all_new_question_for_following_tags: - label: All new questions for following tags - description: Get notified of new questions for following tags. - account: - heading: 帳號 - change_email_btn: 更改郵箱 - change_pass_btn: 更改密碼 - change_email_info: >- - 我們已經寄出一封郵件至此電子郵件地址,請遵照說明進行確認。 - email: - label: 電子郵件地址 - new_email: - label: 新電子郵件地址 - msg: 新電子郵件地址不能為空白。 - pass: - label: 目前密碼 - msg: Password cannot be empty. - password_title: 密碼 - current_pass: - label: Current password - msg: - empty: Current password cannot be empty. - length: 密碼長度必須在 8 至 32 之間 - different: 兩次輸入的密碼不匹配 - new_pass: - label: New password - pass_confirm: - label: 確認新密碼 - interface: - heading: 介面 - lang: - label: 介面語言 - text: 設定使用者介面語言,在重新整裡頁面後生效。 - my_logins: - title: 我的登入 - label: 使用這些帳號登入或註冊此網站。 - modal_title: 移除登入 - modal_content: Are you sure you want to remove this login from your account? - modal_confirm_btn: Remove - remove_success: Removed successfully - toast: - update: 更新成功 - update_password: 更改密碼成功。 - flag_success: 感謝您的標記 - forbidden_operate_self: 禁止自己操作 - review: 您的修訂將在審核通過後顯示。 - sent_success: Sent successfully - related_question: - title: Related - answers: 個回答 - linked_question: - title: Linked - description: Posts linked to - no_linked_question: No contents linked from this content. - invite_to_answer: - title: People Asked - desc: Invite people who you think might know the answer. - invite: Invite to answer - add: Add people - search: Search people - question_detail: - action: Action - created: Created - Asked: 提問於 - asked: 提問於 - update: 修改於 - Edited: Edited - edit: 最後編輯於 - commented: commented - Views: 閱讀次數 - Follow: 關注 - Following: 已關注 - follow_tip: Follow this question to receive notifications - answered: 回答於 - closed_in: 關閉於 - show_exist: 顯示現有問題。 - useful: Useful - question_useful: It is useful and clear - question_un_useful: It is unclear or not useful - question_bookmark: Bookmark this question - answer_useful: It is useful - answer_un_useful: It is not useful - answers: - title: 個回答 - score: 評分 - newest: 最新 - oldest: Oldest - btn_accept: 採納 - btn_accepted: 已被採納 - write_answer: - title: 你的回答 - edit_answer: Edit my existing answer - btn_name: 提交你的回答 - add_another_answer: 添加另一個答案 - confirm_title: 繼續回答 - continue: 繼續 - confirm_info: >- -

        您確定要添加一個新的回答嗎?

        您可以使用编辑链接来完善和改进您现有的答案。

        - empty: 回答內容不能為空。 - characters: 內容必須至少6個字元長度。 - tips: - header_1: Thanks for your answer - li1_1: Please be sure to answer the question. Provide details and share your research. - li1_2: Back up any statements you make with references or personal experience. - header_2: But avoid ... - li2_1: Asking for help, seeking clarification, or responding to other answers. - reopen: - confirm_btn: Reopen - title: 重新打開這個貼文 - content: 確定要重新打開嗎? - list: - confirm_btn: List - title: List this post - content: Are you sure you want to list? - unlist: - confirm_btn: Unlist - title: Unlist this post - content: Are you sure you want to unlist? - pin: - title: Pin this post - content: Are you sure you wish to pinned globally? This post will appear at the top of all post lists. - confirm_btn: Pin - delete: - title: 刪除此貼 - question: >- - 我們不建議刪除有回答的貼文。因為這樣做會使得後來的讀者無法從該問題中獲得幫助。

        如果刪除過多有回答的貼文,你的帳號將會被禁止提問。你確定要刪除嗎? - answer_accepted: >- -

        我們不建議刪除被採納的回答。因為這樣做會使得後來的讀者無法從該回答中獲得幫助。

        如果刪除過多被採納的貼文,你的帳號將會被禁止回答任何提問。你確定要刪除嗎? - other: 你確定要刪除? - tip_answer_deleted: 此回答已被刪除 - undelete_title: Undelete this post - undelete_desc: Are you sure you wish to undelete? - btns: - confirm: 確認 - cancel: 取消 - edit: 編輯 - save: 儲存 - delete: 刪除 - undelete: 還原 - list: 清單 - unlist: Unlist - unlisted: Unlisted - login: 登入 - signup: 註冊 - logout: 登出 - verify: 驗證 - create: 建立 - approve: 核准 - reject: 拒絕 - skip: 略過 - discard_draft: Discard draft - pinned: Pinned - all: All - question: Question - answer: Answer - comment: Comment - refresh: Refresh - resend: Resend - deactivate: Deactivate - active: Active - suspend: Suspend - unsuspend: Unsuspend - close: Close - reopen: Reopen - ok: OK - light: Light - dark: Dark - system_setting: System setting - default: Default - reset: Reset - tag: Tag - post_lowercase: post - filter: Filter - ignore: Ignore - submit: Submit - normal: Normal - closed: Closed - deleted: Deleted - deleted_permanently: Deleted permanently - pending: Pending - more: More - view: View - card: Card - compact: Compact - display_below: Display below - always_display: Always display - or: or - back_sites: Back to sites - search: - title: 搜尋結果 - keywords: 關鍵詞 - options: 選項 - follow: 追蹤 - following: 已關注 - counts: "{{count}} 個結果" - counts_loading: "... Results" - more: 更多 - sort_btns: - relevance: 相關性 - newest: 最新的 - active: 活躍的 - score: 評分 - more: 更多 - tips: - title: 高級搜尋提示 - tag: "<1>[tag] 在指定標籤中搜尋" - user: "<1>user:username 根據作者搜尋" - answer: "<1>answers:0 搜尋未回答的問題" - score: "<1>score:3 得分為 3+ 的帖子" - question: "<1>is:question 只搜尋問題" - is_answer: "<1>is:answer 只搜尋回答" - empty: 找不到任何相關的內容。
        請嘗試其他關鍵字,或者減少查找內容的長度。 - share: - name: 分享 - copy: 複製連結 - via: 分享在... - copied: 已複製 - facebook: 分享到 Facebook - twitter: Share to X - cannot_vote_for_self: You can't vote for your own post. - modal_confirm: - title: 發生錯誤... - delete_permanently: - title: Delete permanently - content: Are you sure you want to delete permanently? - account_result: - success: 你的帳號已通過驗證,即將返回首頁。 - link: 繼續訪問主頁 - oops: Oops! - invalid: The link you used no longer works. - confirm_new_email: 你的電子郵箱已更新 - confirm_new_email_invalid: >- - 抱歉,此驗證連結已失效。也許是你的郵箱已經成功更改了? - unsubscribe: - page_title: 退訂 - success_title: 取消訂閱成功 - success_desc: 您已成功從訂閱者清單中移除且不會在收到任何來自我們的郵件。 - link: 更改設置 - question: - following_tags: 已關注的標籤 - edit: 編輯 - save: 儲存 - follow_tag_tip: 按照標籤整理您的問題列表。 - hot_questions: 熱門問題 - all_questions: 全部問題 - x_questions: "{{ count }} 個問題" - x_answers: "{{ count }} 個回答" - x_posts: "{{ count }} Posts" - questions: 個問題 - answers: 回答 - newest: 最新的 - active: 活躍的 - hot: Hot - frequent: Frequent - recommend: Recommend - score: 評分 - unanswered: 未回答 - modified: 修改於 - answered: 回答於 - asked: 提問於 - closed: 已關閉 - follow_a_tag: 關注一個標籤 - more: 更多 - personal: - overview: 概覽 - answers: 回答 - answer: 回答 - questions: 問題 - question: 問題 - bookmarks: 書籤 - reputation: 聲望 - comments: 評論 - votes: 得票 - badges: Badges - newest: 最新 - score: 評分 - edit_profile: Edit profile - visited_x_days: "已造訪 {{ count }} 天" - viewed: 閱讀次數 - joined: 加入於 - comma: "," - last_login: 出現時間 - about_me: 關於我 - about_me_empty: "// 你好, 世界 !" - top_answers: 熱門回答 - top_questions: 熱門問題 - stats: 狀態 - list_empty: 沒有找到相關的內容。
        試試看其他標籤? - content_empty: No posts found. - accepted: 已採納 - answered: 回答於 - asked: 提問於 - downvoted: downvoted - mod_short: MOD - mod_long: 管理員 - x_reputation: 聲望 - x_votes: 得票 - x_answers: 個回答 - x_questions: 個問題 - recent_badges: Recent Badges - install: - title: Installation - next: 下一步 - done: 完成 - config_yaml_error: 無法建立 config.yaml 檔。 - lang: - label: Please choose a language - db_type: - label: Database engine - db_username: - label: 用戶名 - placeholder: 根 - msg: 用戶名不能為空 - db_password: - label: 密碼 - placeholder: root - msg: 密碼不能為空 - db_host: - label: Database host - placeholder: "db: 3306" - msg: Database host cannot be empty. - db_name: - label: Database name - placeholder: 回答 - msg: Database name cannot be empty. - db_file: - label: Database file - placeholder: /data/answer.db - msg: Database file cannot be empty. - ssl_enabled: - label: Enable SSL - ssl_enabled_on: - label: On - ssl_enabled_off: - label: Off - ssl_mode: - label: SSL Mode - ssl_root_cert: - placeholder: sslrootcert file path - msg: Path to sslrootcert file cannot be empty - ssl_cert: - placeholder: sslcert file path - msg: Path to sslcert file cannot be empty - ssl_key: - placeholder: sslkey file path - msg: Path to sslkey file cannot be empty - config_yaml: - title: 創建 config.yaml - label: 已創建 config.yaml 文件。 - desc: >- - 您可以手動在 <1>/var/wwww/xxx/ 目錄中創建<1>config.yaml 文件並粘貼以下文本。 - info: 完成後點擊"下一步"按鈕。 - site_information: 網站資訊 - admin_account: 管理員帳戶 - site_name: - label: Site name - msg: Site name cannot be empty. - msg_max_length: Site name must be at maximum 30 characters in length. - site_url: - label: 網站 URL - text: 此網站的地址。 - msg: - empty: 網站URL不能為空。 - incorrect: 網站URL格式不正確。 - max_length: Site URL must be at maximum 512 characters in length. - contact_email: - label: Contact email - text: 負責本網站的主要聯絡人的電子郵件地址。 - msg: - empty: Contact email cannot be empty. - incorrect: Contact email incorrect format. - login_required: - label: Private - switch: Login required - text: Only logged in users can access this community. - admin_name: - label: 暱稱 - msg: 暱稱不能為空。 - character: 'Must use the character set "a-z", "0-9", " - . _"' - msg_max_length: Name must be between 2 to 30 characters in length. - admin_password: - label: 密碼 - text: >- - 您需要此密碼才能登入。請將其儲存在一個安全的位置。 - msg: 密碼不能為空。 - msg_min_length: Password must be at least 8 characters in length. - msg_max_length: Password must be at maximum 32 characters in length. - admin_confirm_password: - label: "Confirm Password" - text: "Please re-enter your password to confirm." - msg: "Confirm password does not match." - admin_email: - label: 郵箱 - text: 您需要此電子郵件才能登入。 - msg: - empty: 郵箱不能為空。 - incorrect: 郵箱格式不正確。 - ready_title: Your site is ready - ready_desc: >- - 如果你想改變更多的設定,請瀏覽<1>管理員部分;在網站選單中找到它。 - good_luck: "玩得愉快,祝您好運!" - warn_title: 警告 - warn_desc: >- - 檔案<1>config.yaml已存在。如果您需要重置此文件中的任何配置項,請先刪除它。 - install_now: 您可以嘗試<1>現在安裝。 - installed: 已安裝 - installed_desc: >- - 您似乎已經安裝過了。要重新安裝,請先清除舊的資料庫表。 - db_failed: 資料連接異常! - db_failed_desc: >- - This either means that the database information in your <1>config.yaml file is incorrect or that contact with the database server could not be established. This could mean your host's database server is down. - counts: - views: 觀看 - votes: 得票 - answers: 回答 - accepted: 已採納 - page_error: - http_error: HTTP 错误 {{ code }} - desc_403: You don't have permission to access this page. - desc_404: Unfortunately, this page doesn't exist. - desc_50X: The server encountered an error and could not complete your request. - back_home: Back to homepage - page_maintenance: - desc: "我們正在維護中,很快就會回來。" - nav_menus: - dashboard: 後台管理 - contents: 內容 - questions: 問題 - answers: 回答 - users: 使用者管理 - badges: Badges - flags: 檢舉 - settings: 設定 - general: 一般 - interface: 介面 - smtp: SMTP - branding: 品牌 - legal: 法律條款 - write: 撰寫 - terms: Terms - tos: 服務條款 - privacy: 隱私政策 - seo: SEO - customize: 自定義 - themes: 主題 - login: 登入 - privileges: Privileges - plugins: Plugins - installed_plugins: Installed Plugins - apperance: Appearance - website_welcome: Welcome to {{site_name}} - user_center: - login: Login - qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in. - login_failed_email_tip: Login failed, please allow this app to access your email information before try again. - badges: - modal: - title: Congratulations - content: You've earned a new badge. - close: Close - confirm: View badges - title: Badges - awarded: Awarded - earned_×: Earned ×{{ number }} - ×_awarded: "{{ number }} awarded" - can_earn_multiple: You can earn this multiple times. - earned: Earned - admin: - admin_header: - title: 後台管理 - dashboard: - title: 後台管理 - welcome: Welcome to Admin! - site_statistics: Site statistics - questions: "問題:" - resolved: "Resolved:" - unanswered: "Unanswered:" - answers: "回答:" - comments: "評論:" - votes: "投票:" - users: "Users:" - flags: "檢舉:" - reviews: "Reviews:" - site_health: Site health - version: "版本" - https: "HTTPS:" - upload_folder: "Upload folder:" - run_mode: "Running mode:" - private: Private - public: Public - smtp: "SMTP:" - timezone: "時區:" - system_info: System info - go_version: "Go version:" - database: "Database:" - database_size: "Database size:" - storage_used: "已用儲存空間:" - uptime: "運行時間:" - links: Links - plugins: Plugins - github: GitHub - blog: Blog - contact: Contact - forum: Forum - documents: 文件 - feedback: 用戶反饋 - support: 支持 - review: 審核 - config: 配置 - update_to: 更新到 - latest: 最新版本 - check_failed: 校驗失敗 - "yes": "是" - "no": "否" - not_allowed: 不允許 - allowed: 允許 - enabled: 已啟用 - disabled: 停用 - writable: Writable - not_writable: Not writable - flags: - title: 檢舉 - pending: 等待處理 - completed: 已完成 - flagged: 已標記 - flagged_type: Flagged {{ type }} - created: 創建於 - action: 操作 - review: 審核 - user_role_modal: - title: 更改用戶狀態為... - btn_cancel: 取消 - btn_submit: 提交 - new_password_modal: - title: Set new password - form: - fields: - password: - label: Password - text: The user will be logged out and need to login again. - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - edit_profile_modal: - title: Edit profile - form: - fields: - display_name: - label: Display name - msg_range: Display name must be 2-30 characters in length. - username: - label: Username - msg_range: Username must be 2-30 characters in length. - email: - label: Email - msg_invalid: Invalid Email Address. - edit_success: Edited successfully - btn_cancel: Cancel - btn_submit: Submit - user_modal: - title: Add new user - form: - fields: - users: - label: Bulk add user - placeholder: "John Smith, john@example.com, BUSYopr2\nAlice, alice@example.com, fpDntV8q" - text: Separate “name, email, password” with commas. One user per line. - msg: "Please enter the user's email, one per line." - display_name: - label: Display name - msg: Display name must be 2-30 characters in length. - email: - label: Email - msg: Email is not valid. - password: - label: Password - msg: Password must be at 8-32 characters in length. - btn_cancel: Cancel - btn_submit: Submit - users: - title: 用戶 - name: 名稱 - email: 郵箱 - reputation: 聲望 - created_at: Created time - delete_at: Deleted time - suspend_at: Suspended time - suspend_until: Suspend until - status: 狀態 - role: 角色 - action: 操作 - change: 更改 - all: 全部 - staff: 工作人員 - more: More - inactive: 不活躍 - suspended: 已停權 - deleted: 已刪除 - normal: 正常 - Moderator: 版主 - Admin: 管理員 - User: 用戶 - filter: - placeholder: "按名稱篩選,用戶:id" - set_new_password: 設置新密碼 - edit_profile: Edit profile - change_status: 更改狀態 - change_role: 更改角色 - show_logs: 顯示日誌 - add_user: 新增使用者 - deactivate_user: - title: Deactivate user - content: An inactive user must re-validate their email. - delete_user: - title: Delete this user - content: Are you sure you want to delete this user? This is permanent! - remove: Remove their content - label: Remove all questions, answers, comments, etc. - text: Don’t check this if you wish to only delete the user’s account. - suspend_user: - title: Suspend this user - content: A suspended user can't log in. - label: How long will the user be suspended for? - forever: Forever - questions: - page_title: 問題 - unlisted: Unlisted - post: 標題 - votes: 得票數 - answers: 回答 - created: 創建於 - status: 狀態 - action: 操作 - change: 更改 - pending: Pending - filter: - placeholder: "按標題過濾,問題:id" - answers: - page_title: 回答 - post: 發布 - votes: 得票數 - created: 創建於 - status: 狀態 - action: 操作 - change: 更改 - filter: - placeholder: "按名稱篩選,answer:id" - general: - page_title: 一般 - name: - label: Site name - msg: 不能為空 - text: "網站的名稱,如標題標籤中所用。" - site_url: - label: 網站網址 - msg: 網站網址不能為空。 - validate: 請輸入一個有效的 URL。 - text: 此網站的網址。 - short_desc: - label: Short site description - msg: 網站簡短描述不能為空。 - text: "簡短的描述,如主頁上的標題標籤所使用的那样。" - desc: - label: Site description - msg: 網站描述不能為空。 - text: "使用一句話描述本站,作為網站的描述(Html 的 meta 標籤)。" - contact_email: - label: Contact email - msg: 聯絡人信箱不能為空。 - validate: 聯絡人信箱無效。 - text: 負責本網站的主要聯絡人的電子郵件信箱。 - check_update: - label: Software updates - text: Automatically check for updates - interface: - page_title: 介面 - language: - label: Interface language - msg: 界面語言不能為空 - text: 設置用戶界面語言,在刷新頁面后生效。 - time_zone: - label: 時區 - msg: 時區不能為空。 - text: 選擇一個與您相同時區的城市。 - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar base URL - text: URL of the Gravatar provider's API base. Ignored when empty. - smtp: - page_title: SMTP - from_email: - label: From email - msg: 發件人電子郵件不能为空。 - text: 發送郵件的郵箱地址 - from_name: - label: From name - msg: 發件人名稱不能为空。 - text: 發件人的名稱 - smtp_host: - label: SMTP host - msg: SMTP 主機名稱不能為空。 - text: 郵件服務器 - encryption: - label: 加密 - msg: 加密不能為空。 - text: 對於大多數服務器,SSL 是推薦的選項。 - ssl: SSL - tls: TLS - none: 無 - smtp_port: - label: SMTP port - msg: SMTP 埠必須在 1 ~ 65535 之間。 - text: 郵件服務器的端口號。 - smtp_username: - label: SMTP username - msg: SMTP 用戶名不能為空。 - smtp_password: - label: SMTP password - msg: SMTP 密碼不能為空。 - test_email_recipient: - label: Test email recipients - text: 提供用於接收測試郵件的郵箱地址。 - msg: 測試郵件收件人無效 - smtp_authentication: - label: 啟用身份驗證 - title: SMTP authentication - msg: SMTP 身份驗證不能為空。 - "yes": "是" - "no": "否" - branding: - page_title: 品牌 - logo: - label: 標誌 - msg: 圖標不能為空。 - text: 在你的網站左上方的Logo圖標。使用一個高度為56,長寬比大於3:1的寬長方形圖像。如果留空,將顯示網站標題文本。 - mobile_logo: - label: Mobile logo - text: 在您網站的移動版本上使用的徽標。 使用高度為 56 的寬矩形圖像。如果留空,將使用“徽標”設置中的圖像。 - square_icon: - label: Square icon - msg: 方形圖示不能為空。 - text: 用作元數據圖標的基礎的圖像。最好是大於512x512。 - favicon: - label: 網站圖示 - text: 您網站的圖標。 要在 CDN 上正常工作,它必須是 png。 將調整為 32x32的大小。 如果留空,將使用“方形圖標”。 - legal: - page_title: 法律條款 - terms_of_service: - label: Terms of service - text: "您可以在此加入服務內容的條款。如果您已經在別處托管了文檔,請在這裡提供完整的URL。" - privacy_policy: - label: Privacy policy - text: "您可以在此加入隱私政策內容。如果您已經在別處托管了文檔,請在這裡提供完整的URL。" - external_content_display: - label: External content - text: "Content includes images, videos, and media embedded from external websites." - always_display: Always display external content - ask_before_display: Ask before displaying external content - write: - page_title: 編輯 - min_content: - label: Minimum question body length - text: Minimum allowed question body length in characters. - restrict_answer: - title: Answer write - label: Each user can only write one answer for each question - text: "Turn off to allow users to write multiple answers to the same question, which may cause answers to be unfocused." - min_tags: - label: "Minimum tags per question" - text: "Minimum number of tags required in a question." - recommend_tags: - label: Recommend tags - text: "Recommend tags will show in the dropdown list by default." - msg: - contain_reserved: "recommended tags cannot contain reserved tags" - required_tag: - title: Set required tags - label: Set “Recommend tags” as required tags - text: "每個新問題必須至少有一個推薦標籤。" - reserved_tags: - label: Reserved tags - text: "Reserved tags can only be used by moderator." - image_size: - label: Max image size (MB) - text: "The maximum image upload size." - attachment_size: - label: Max attachment size (MB) - text: "The maximum attachment files upload size." - image_megapixels: - label: Max image megapixels - text: "Maximum number of megapixels allowed for an image." - image_extensions: - label: Authorized image extensions - text: "A list of file extensions allowed for image display, separate with commas." - attachment_extensions: - label: Authorized attachment extensions - text: "A list of file extensions allowed for upload, separate with commas. WARNING: Allowing uploads may cause security issues." - seo: - page_title: 搜尋引擎優化 - permalink: - label: 固定連結 - text: 自定義URL結構可以提高可用性,以及你的連結的向前相容性。 - robots: - label: robots.txt - text: 這將永久覆蓋任何相關的網站設置。 - themes: - page_title: 主題 - themes: - label: 主題 - text: 選擇一個現有主題。 - color_scheme: - label: Color scheme - navbar_style: - label: Navbar background style - primary_color: - label: 主色調 - text: 修改您主題使用的顏色 - css_and_html: - page_title: CSS 與 HTML - custom_css: - label: 自定義CSS - text: > - - head: - label: 頭部 - text: > - - header: - label: 標題 - text: > - - footer: - label: 頁尾 - text: This will insert before </body>. - sidebar: - label: Sidebar - text: This will insert in sidebar. - login: - page_title: 登入 - membership: - title: 會員 - label: 允許新註冊 - text: 關閉以防止任何人創建新帳戶。 - email_registration: - title: Email registration - label: Allow email registration - text: Turn off to prevent anyone creating new account through email. - allowed_email_domains: - title: Allowed email domains - text: Email domains that users must register accounts with. One domain per line. Ignored when empty. - private: - title: 非公開的 - label: 需要登入 - text: 只有登入使用者才能訪問這個社群。 - password_login: - title: Password login - label: Allow email and password login - text: "WARNING: If turn off, you may be unable to log in if you have not previously configured other login method." - installed_plugins: - title: Installed Plugins - plugin_link: Plugins extend and expand the functionality. You may find plugins in the <1>Plugin Repository. - filter: - all: All - active: Active - inactive: Inactive - outdated: Outdated - plugins: - label: Plugins - text: Select an existing plugin. - name: Name - version: Version - status: Status - action: Action - deactivate: Deactivate - activate: Activate - settings: Settings - settings_users: - title: Users - avatar: - label: Default avatar - text: For users without a custom avatar of their own. - gravatar_base_url: - label: Gravatar 基礎網址 - text: URL of the Gravatar provider's API base. Ignored when empty. - profile_editable: - title: Profile editable - allow_update_display_name: - label: Allow users to change their display name - allow_update_username: - label: Allow users to change their username - allow_update_avatar: - label: Allow users to change their profile image - allow_update_bio: - label: Allow users to change their about me - allow_update_website: - label: Allow users to change their website - allow_update_location: - label: Allow users to change their location - privilege: - title: Privileges - level: - label: Reputation required level - text: Choose the reputation required for the privileges - msg: - should_be_number: the input should be number - number_larger_1: number should be equal or larger than 1 - badges: - action: Action - active: Active - activate: Activate - all: All - awards: Awards - deactivate: Deactivate - filter: - placeholder: Filter by name, badge:id - group: Group - inactive: Inactive - name: Name - show_logs: Show logs - status: Status - title: Badges - form: - optional: (選填) - empty: 不能為空 - invalid: 是無效的 - btn_submit: 儲存 - not_found_props: "所需屬性 {{ key }} 未找到。" - select: Select - page_review: - review: 審核 - proposed: 提案 - question_edit: 問題編輯 - answer_edit: 回答編輯 - tag_edit: '標籤管理: 編輯標籤' - edit_summary: 編輯摘要 - edit_question: 編輯問題 - edit_answer: 編輯回答 - edit_tag: 編輯標籤 - empty: 沒有剩餘的審核任務。 - approve_revision_tip: Do you approve this revision? - approve_flag_tip: Do you approve this flag? - approve_post_tip: Do you approve this post? - approve_user_tip: Do you approve this user? - suggest_edits: Suggested edits - flag_post: Flag post - flag_user: Flag user - queued_post: Queued post - queued_user: Queued user - filter_label: Type - reputation: reputation - flag_post_type: Flagged this post as {{ type }}. - flag_user_type: Flagged this user as {{ type }}. - edit_post: Edit post - list_post: List post - unlist_post: Unlist post - timeline: - undeleted: 未刪除的 - deleted: 刪除 - downvote: 反對 - upvote: 贊同 - accept: 採納 - cancelled: 已取消 - commented: '評論:' - rollback: 回滾 - edited: 最後編輯於 - answered: 回答於 - asked: 提問於 - closed: 關閉 - reopened: 重新開啟 - created: 創建於 - pin: pinned - unpin: unpinned - show: listed - hide: unlisted - title: "歷史記錄" - tag_title: "時間線" - show_votes: "顯示投票" - n_or_a: N/A - title_for_question: "時間線" - title_for_answer: "{{ title }} 的 {{ author }} 回答時間線" - title_for_tag: "標籤的時間線" - datetime: 日期時間 - type: 類型 - by: 由 - comment: 評論 - no_data: "我們找不到任何東西。" - users: - title: 用戶 - users_with_the_most_reputation: Users with the highest reputation scores this week - users_with_the_most_vote: Users who voted the most this week - staffs: 我們的社區工作人員 - reputation: 聲望值 - votes: 選票 - prompt: - leave_page: 你確定要離開此頁面? - changes_not_save: 你所做的變更可能不會儲存。 - draft: - discard_confirm: Are you sure you want to discard your draft? - messages: - post_deleted: This post has been deleted. - post_cancel_deleted: This post has been undeleted. - post_pin: This post has been pinned. - post_unpin: This post has been unpinned. - post_hide_list: This post has been hidden from list. - post_show_list: This post has been shown to list. - post_reopen: This post has been reopened. - post_list: This post has been listed. - post_unlist: This post has been unlisted. - post_pending: Your post is awaiting review. This is a preview, it will be visible after it has been approved. - post_closed: This post has been closed. - answer_deleted: This answer has been deleted. - answer_cancel_deleted: This answer has been undeleted. - change_user_role: This user's role has been changed. - user_inactive: This user is already inactive. - user_normal: This user is already normal. - user_suspended: This user has been suspended. - user_deleted: This user has been deleted. - badge_activated: This badge has been activated. - badge_inactivated: This badge has been inactivated. - users_deleted: These users have been deleted. - posts_deleted: These questions have been deleted. - answers_deleted: These answers have been deleted. - copy: Copy to clipboard - copied: Copied - external_content_warning: External images/media are not displayed. - - From f6d30a5b57044bb9d7b1e6a269c8fe502e6fd4b8 Mon Sep 17 00:00:00 2001 From: maishivamhoo123 Date: Thu, 25 Dec 2025 12:50:01 +0530 Subject: [PATCH 53/92] chore: revert documentation changes in README --- README.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/README.md b/README.md index ffa171694..6e96c516a 100644 --- a/README.md +++ b/README.md @@ -46,15 +46,6 @@ You can also check out the [plugins here](https://answer.apache.org/plugins). - [mockgen](https://github.com/uber-go/mock?tab=readme-ov-file#installation) >= 0.6.0 - [wire](https://github.com/google/wire/) >= 0.5.0 -### Environment Configuration - - You may create a `.env` file in the project root. - Copy `.env.example` and fill required values. - - ```bash - cp .env.example .env - - ### Build ```bash From 3d5465334cb74bef2a14fabb71f5fd833ede6093 Mon Sep 17 00:00:00 2001 From: maishivamhoo123 Date: Thu, 8 Jan 2026 00:12:56 +0530 Subject: [PATCH 54/92] fix: added the init fuction in install_main.go --- internal/install/install_main.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/internal/install/install_main.go b/internal/install/install_main.go index 41ccdcf40..eae914af0 100644 --- a/internal/install/install_main.go +++ b/internal/install/install_main.go @@ -25,13 +25,20 @@ import ( "github.com/apache/answer/internal/base/path" "github.com/apache/answer/internal/base/translator" + "github.com/joho/godotenv" ) var ( - port = os.Getenv("INSTALL_PORT") + port string confPath = "" ) +func init() { + _ = godotenv.Load() + port = os.Getenv("INSTALL_PORT") + +} + func Run(configPath string) { confPath = configPath // initialize translator for return internationalization error when installing. From 5be6ec9e71f74995b6c48377d42a12292f34abca Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Wed, 14 Jan 2026 11:30:50 +0800 Subject: [PATCH 55/92] docs(lic): add MIT license file and clean up init function in install_main.go --- .../licenses/LICENSE-joho-godotenv.txt | 22 +++++++++++++++++++ internal/install/install_main.go | 1 - 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 docs/release/licenses/LICENSE-joho-godotenv.txt diff --git a/docs/release/licenses/LICENSE-joho-godotenv.txt b/docs/release/licenses/LICENSE-joho-godotenv.txt new file mode 100644 index 000000000..9390caf66 --- /dev/null +++ b/docs/release/licenses/LICENSE-joho-godotenv.txt @@ -0,0 +1,22 @@ +Copyright (c) 2013 John Barton + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/internal/install/install_main.go b/internal/install/install_main.go index eae914af0..30fc6ddcb 100644 --- a/internal/install/install_main.go +++ b/internal/install/install_main.go @@ -36,7 +36,6 @@ var ( func init() { _ = godotenv.Load() port = os.Getenv("INSTALL_PORT") - } func Run(configPath string) { From 29ec29bde770542efe2a0f299f00d7466f4fb8c9 Mon Sep 17 00:00:00 2001 From: kumfo Date: Tue, 20 Jan 2026 14:54:52 +0800 Subject: [PATCH 56/92] feat(menu): update admin menu settings to include questions, tags, and advanced options --- cmd/wire_gen.go | 74 +++----- go.mod | 2 +- internal/base/constant/site_type.go | 3 + internal/controller/answer_controller.go | 2 +- internal/controller/siteinfo_controller.go | 10 +- .../controller_admin/siteinfo_controller.go | 94 ++++++++-- internal/migrations/migrations.go | 1 + internal/migrations/v30.go | 173 ++++++++++++++++++ internal/router/answer_api_router.go | 10 +- internal/schema/siteinfo_schema.go | 41 ++++- internal/service/mock/siteinfo_repo_mock.go | 81 ++++++-- internal/service/question_common/question.go | 2 +- internal/service/siteinfo/siteinfo_service.go | 51 ++++-- .../siteinfo_common/siteinfo_service.go | 30 +++ internal/service/tag_common/tag_common.go | 8 +- internal/service/uploader/upload.go | 32 ++-- 16 files changed, 490 insertions(+), 124 deletions(-) create mode 100644 internal/migrations/v30.go diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index 22a70f29d..2808619b3 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -1,28 +1,8 @@ -//go:build !wireinject -// +build !wireinject - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - // Code generated by Wire. DO NOT EDIT. -//go:generate go run github.com/google/wire/cmd/wire +//go:generate go run -mod=mod github.com/google/wire/cmd/wire +//go:build !wireinject +// +build !wireinject package answercmd @@ -172,29 +152,29 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, tagRepo := tag.NewTagRepo(dataData, uniqueIDRepo) revisionRepo := revision.NewRevisionRepo(dataData, uniqueIDRepo) revisionService := revision_common.NewRevisionService(revisionRepo, userRepo) - v := activityqueue.NewService() - tagCommonService := tag_common2.NewTagCommonService(tagCommonRepo, tagRelRepo, tagRepo, revisionService, siteInfoCommonService, v) + service := activityqueue.NewService() + tagCommonService := tag_common2.NewTagCommonService(tagCommonRepo, tagRelRepo, tagRepo, revisionService, siteInfoCommonService, service) collectionRepo := collection.NewCollectionRepo(dataData, uniqueIDRepo) collectionCommon := collectioncommon.NewCollectionCommon(collectionRepo) answerCommon := answercommon.NewAnswerCommon(answerRepo) metaRepo := meta.NewMetaRepo(dataData) metaCommonService := metacommon.NewMetaCommonService(metaRepo) - questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaCommonService, configService, v, revisionRepo, siteInfoCommonService, dataData) - v2 := eventqueue.NewService() + questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaCommonService, configService, service, revisionRepo, siteInfoCommonService, dataData) + eventqueueService := eventqueue.NewService() fileRecordRepo := file_record.NewFileRecordRepo(dataData) fileRecordService := file_record2.NewFileRecordService(fileRecordRepo, revisionRepo, serviceConf, siteInfoCommonService, userCommon) - userService := content.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo, userNotificationConfigService, questionCommon, v2, fileRecordService) + userService := content.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo, userNotificationConfigService, questionCommon, eventqueueService, fileRecordService) captchaRepo := captcha.NewCaptchaRepo(dataData) captchaService := action.NewCaptchaService(captchaRepo) userController := controller.NewUserController(authService, userService, captchaService, emailService, siteInfoCommonService, userNotificationConfigService) commentRepo := comment.NewCommentRepo(dataData, uniqueIDRepo) commentCommonRepo := comment.NewCommentCommonRepo(dataData, uniqueIDRepo) objService := object_info.NewObjService(answerRepo, questionRepo, commentCommonRepo, tagCommonRepo, tagCommonService) - v3 := noticequeue.NewService() - v4 := noticequeue.NewExternalService() + noticequeueService := noticequeue.NewService() + externalService := noticequeue.NewExternalService() reviewRepo := review.NewReviewRepo(dataData) - reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, v4, tagCommonService, questionCommon, v3, siteInfoCommonService, commentCommonRepo) - commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, v3, v4, v, v2, reviewService) + reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, externalService, tagCommonService, questionCommon, noticequeueService, siteInfoCommonService, commentCommonRepo) + commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, noticequeueService, externalService, service, eventqueueService, reviewService) rolePowerRelRepo := role.NewRolePowerRelRepo(dataData) rolePowerRelService := role2.NewRolePowerRelService(rolePowerRelRepo, userRoleRelService) rankService := rank2.NewRankService(userCommon, userRankRepo, objService, userRoleRelService, rolePowerRelService, configService) @@ -202,17 +182,17 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, rateLimitMiddleware := middleware.NewRateLimitMiddleware(limitRepo) commentController := controller.NewCommentController(commentService, rankService, captchaService, rateLimitMiddleware) reportRepo := report.NewReportRepo(dataData, uniqueIDRepo) - tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, v) - answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, v3) + tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, service) + answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, noticequeueService) answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, configService) - externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, v4, userExternalLoginRepo, siteInfoCommonService) - questionService := content.NewQuestionService(activityRepo, questionRepo, answerRepo, tagCommonService, tagService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, v3, v4, v, siteInfoCommonService, externalNotificationService, reviewService, configService, v2, reviewRepo) - answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, v3, v4, v, reviewService, v2) + externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, externalService, userExternalLoginRepo, siteInfoCommonService) + questionService := content.NewQuestionService(activityRepo, questionRepo, answerRepo, tagCommonService, tagService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, noticequeueService, externalService, service, siteInfoCommonService, externalNotificationService, reviewService, configService, eventqueueService, reviewRepo) + answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, noticequeueService, externalService, service, reviewService, eventqueueService) reportHandle := report_handle.NewReportHandle(questionService, answerService, commentService) - reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, v2) + reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, eventqueueService) reportController := controller.NewReportController(reportService, rankService, captchaService) - contentVoteRepo := activity.NewVoteRepo(dataData, activityRepo, userRankRepo, v3) - voteService := content.NewVoteService(contentVoteRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService, v2) + contentVoteRepo := activity.NewVoteRepo(dataData, activityRepo, userRankRepo, noticequeueService) + voteService := content.NewVoteService(contentVoteRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService, eventqueueService) voteController := controller.NewVoteController(voteService, rankService, captchaService) tagController := controller.NewTagController(tagService, tagCommonService, rankService) followFollowRepo := activity.NewFollowRepo(dataData, uniqueIDRepo, activityRepo) @@ -228,7 +208,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, searchService := content.NewSearchService(searchParser, searchRepo) searchController := controller.NewSearchController(searchService, captchaService) reviewActivityRepo := activity.NewReviewActivityRepo(dataData, activityRepo, userRankRepo, configService) - contentRevisionService := content.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService, v3, v, reportRepo, reviewService, reviewActivityRepo) + contentRevisionService := content.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService, noticequeueService, service, reportRepo, reviewService, reviewActivityRepo) revisionController := controller.NewRevisionController(contentRevisionService, rankService) rankController := controller.NewRankController(rankService) userAdminRepo := user.NewUserAdminRepo(dataData, authRepo) @@ -244,7 +224,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, siteInfoService := siteinfo.NewSiteInfoService(siteInfoRepo, siteInfoCommonService, emailService, tagCommonService, configService, questionCommon, fileRecordService) siteInfoController := controller_admin.NewSiteInfoController(siteInfoService) controllerSiteInfoController := controller.NewSiteInfoController(siteInfoCommonService) - notificationCommon := notificationcommon.NewNotificationCommon(dataData, notificationRepo, userCommon, activityRepo, followRepo, objService, v3, userExternalLoginRepo, siteInfoCommonService) + notificationCommon := notificationcommon.NewNotificationCommon(dataData, notificationRepo, userCommon, activityRepo, followRepo, objService, noticequeueService, userExternalLoginRepo, siteInfoCommonService) badgeRepo := badge.NewBadgeRepo(dataData, uniqueIDRepo) notificationService := notification.NewNotificationService(dataData, notificationRepo, notificationCommon, revisionService, userRepo, reportRepo, reviewService, badgeRepo) notificationController := controller.NewNotificationController(notificationService, rankService) @@ -253,7 +233,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, uploaderService := uploader.NewUploaderService(serviceConf, siteInfoCommonService, fileRecordService) uploadController := controller.NewUploadController(uploaderService) activityActivityRepo := activity.NewActivityRepo(dataData, configService) - activityCommon := activity_common2.NewActivityCommon(activityRepo, v) + activityCommon := activity_common2.NewActivityCommon(activityRepo, service) commentCommonService := comment_common.NewCommentCommonService(commentCommonRepo) activityService := activity2.NewActivityService(activityActivityRepo, userCommon, activityCommon, tagCommonService, objService, commentCommonService, revisionService, metaCommonService, configService) activityController := controller.NewActivityController(activityService) @@ -265,12 +245,12 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, permissionController := controller.NewPermissionController(rankService) userPluginController := controller.NewUserPluginController(pluginCommonService) reviewController := controller.NewReviewController(reviewService, rankService, captchaService) - metaService := meta2.NewMetaService(metaCommonService, userCommon, answerRepo, questionRepo, v2) + metaService := meta2.NewMetaService(metaCommonService, userCommon, answerRepo, questionRepo, eventqueueService) metaController := controller.NewMetaController(metaService) badgeGroupRepo := badge_group.NewBadgeGroupRepo(dataData, uniqueIDRepo) eventRuleRepo := badge.NewEventRuleRepo(dataData) - badgeAwardService := badge2.NewBadgeAwardService(badgeAwardRepo, badgeRepo, userCommon, objService, v3) - badgeEventService := badge2.NewBadgeEventService(dataData, v2, badgeRepo, eventRuleRepo, badgeAwardService) + badgeAwardService := badge2.NewBadgeAwardService(badgeAwardRepo, badgeRepo, userCommon, objService, noticequeueService) + badgeEventService := badge2.NewBadgeEventService(dataData, eventqueueService, badgeRepo, eventRuleRepo, badgeAwardService) badgeService := badge2.NewBadgeService(badgeRepo, badgeGroupRepo, badgeAwardRepo, badgeEventService, siteInfoCommonService) badgeController := controller.NewBadgeController(badgeService, badgeAwardService) controller_adminBadgeController := controller_admin.NewBadgeController(badgeService) @@ -281,7 +261,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, avatarMiddleware := middleware.NewAvatarMiddleware(serviceConf, uploaderService) shortIDMiddleware := middleware.NewShortIDMiddleware(siteInfoCommonService) templateRenderController := templaterender.NewTemplateRenderController(questionService, userService, tagService, answerService, commentService, siteInfoCommonService, questionRepo) - templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService, v2, userService, questionService) + templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService, eventqueueService, userService, questionService) templateRouter := router.NewTemplateRouter(templateController, templateRenderController, siteInfoController, authUserMiddleware) connectorController := controller.NewConnectorController(siteInfoCommonService, emailService, userExternalLoginService) userCenterLoginService := user_external_login2.NewUserCenterLoginService(userRepo, userCommon, userExternalLoginRepo, userActiveActivityRepo, siteInfoCommonService) diff --git a/go.mod b/go.mod index 52d64c738..d24302954 100644 --- a/go.mod +++ b/go.mod @@ -37,6 +37,7 @@ require ( github.com/grokify/html-strip-tags-go v0.1.0 github.com/jinzhu/copier v0.4.0 github.com/jinzhu/now v1.1.5 + github.com/joho/godotenv v1.5.1 github.com/lib/pq v1.10.9 github.com/microcosm-cc/bluemonday v1.0.27 github.com/mozillazg/go-pinyin v0.20.0 @@ -117,7 +118,6 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/joho/godotenv v1.5.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect diff --git a/internal/base/constant/site_type.go b/internal/base/constant/site_type.go index 65b487c5d..6106b190c 100644 --- a/internal/base/constant/site_type.go +++ b/internal/base/constant/site_type.go @@ -31,4 +31,7 @@ const ( SiteTypeTheme = "theme" SiteTypePrivileges = "privileges" SiteTypeUsers = "users" + SiteTypeAdvanced = "advanced" + SiteTypeQuestions = "questions" + SiteTypeTags = "tags" ) diff --git a/internal/controller/answer_controller.go b/internal/controller/answer_controller.go index e76b02ccc..99c89b778 100644 --- a/internal/controller/answer_controller.go +++ b/internal/controller/answer_controller.go @@ -242,7 +242,7 @@ func (ac *AnswerController) AddAnswer(ctx *gin.Context) { return } - write, err := ac.siteInfoCommonService.GetSiteWrite(ctx) + write, err := ac.siteInfoCommonService.GetSiteQuestion(ctx) if err != nil { handler.HandleResponse(ctx, err, nil) return diff --git a/internal/controller/siteinfo_controller.go b/internal/controller/siteinfo_controller.go index a336fb242..8035275a6 100644 --- a/internal/controller/siteinfo_controller.go +++ b/internal/controller/siteinfo_controller.go @@ -87,7 +87,15 @@ func (sc *SiteInfoController) GetSiteInfo(ctx *gin.Context) { if err != nil { log.Error(err) } - resp.Write, err = sc.siteInfoService.GetSiteWrite(ctx) + resp.Questions, err = sc.siteInfoService.GetSiteQuestion(ctx) + if err != nil { + log.Error(err) + } + resp.Tags, err = sc.siteInfoService.GetSiteTag(ctx) + if err != nil { + log.Error(err) + } + resp.Advanced, err = sc.siteInfoService.GetSiteAdvanced(ctx) if err != nil { log.Error(err) } diff --git a/internal/controller_admin/siteinfo_controller.go b/internal/controller_admin/siteinfo_controller.go index 8a92daba3..bbab97942 100644 --- a/internal/controller_admin/siteinfo_controller.go +++ b/internal/controller_admin/siteinfo_controller.go @@ -82,16 +82,42 @@ func (sc *SiteInfoController) GetSiteBranding(ctx *gin.Context) { handler.HandleResponse(ctx, err, resp) } -// GetSiteWrite get site interface -// @Summary get site interface -// @Description get site interface +// GetSiteTag get site tags setting +// @Summary get site tags setting +// @Description get site tags setting +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=schema.SiteTagsResp} +// @Router /answer/admin/api/siteinfo/tag [get] +func (sc *SiteInfoController) GetSiteTag(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteTag(ctx) + handler.HandleResponse(ctx, err, resp) +} + +// GetSiteQuestion get site questions setting +// @Summary get site questions setting +// @Description get site questions setting +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=schema.SiteQuestionsResp} +// @Router /answer/admin/api/siteinfo/question [get] +func (sc *SiteInfoController) GetSiteQuestion(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteQuestion(ctx) + handler.HandleResponse(ctx, err, resp) +} + +// GetSiteAdvanced get site advanced setting +// @Summary get site advanced setting +// @Description get site advanced setting // @Security ApiKeyAuth // @Tags admin // @Produce json -// @Success 200 {object} handler.RespBody{data=schema.SiteWriteResp} -// @Router /answer/admin/api/siteinfo/write [get] -func (sc *SiteInfoController) GetSiteWrite(ctx *gin.Context) { - resp, err := sc.siteInfoService.GetSiteWrite(ctx) +// @Success 200 {object} handler.RespBody{data=schema.SiteAdvancedResp} +// @Router /answer/admin/api/siteinfo/advanced [get] +func (sc *SiteInfoController) GetSiteAdvanced(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteAdvanced(ctx) handler.HandleResponse(ctx, err, resp) } @@ -288,23 +314,61 @@ func (sc *SiteInfoController) UpdateBranding(ctx *gin.Context) { handler.HandleResponse(ctx, saveErr, nil) } -// UpdateSiteWrite update site write info -// @Summary update site write info -// @Description update site write info +// UpdateSiteQuestion update site question settings +// @Summary update site question settings +// @Description update site question settings +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Param data body schema.SiteQuestionsReq true "questions settings" +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/siteinfo/question [put] +func (sc *SiteInfoController) UpdateSiteQuestion(ctx *gin.Context) { + req := &schema.SiteQuestionsReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + resp, err := sc.siteInfoService.SaveSiteQuestions(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// UpdateSiteTag update site tag settings +// @Summary update site tag settings +// @Description update site tag settings // @Security ApiKeyAuth // @Tags admin // @Produce json -// @Param data body schema.SiteWriteReq true "write info" +// @Param data body schema.SiteTagsReq true "tags settings" // @Success 200 {object} handler.RespBody{} -// @Router /answer/admin/api/siteinfo/write [put] -func (sc *SiteInfoController) UpdateSiteWrite(ctx *gin.Context) { - req := &schema.SiteWriteReq{} +// @Router /answer/admin/api/siteinfo/tag [put] +func (sc *SiteInfoController) UpdateSiteTag(ctx *gin.Context) { + req := &schema.SiteTagsReq{} if handler.BindAndCheck(ctx, req) { return } req.UserID = middleware.GetLoginUserIDFromContext(ctx) - resp, err := sc.siteInfoService.SaveSiteWrite(ctx, req) + resp, err := sc.siteInfoService.SaveSiteTags(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// UpdateSiteAdvanced update site advanced info +// @Summary update site advanced info +// @Description update site advanced info +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Param data body schema.SiteAdvancedReq true "advanced settings" +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/siteinfo/advanced [put] +func (sc *SiteInfoController) UpdateSiteAdvanced(ctx *gin.Context) { + req := &schema.SiteAdvancedReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + resp, err := sc.siteInfoService.SaveSiteAdvanced(ctx, req) handler.HandleResponse(ctx, err, resp) } diff --git a/internal/migrations/migrations.go b/internal/migrations/migrations.go index 9fda8c34d..783332df9 100644 --- a/internal/migrations/migrations.go +++ b/internal/migrations/migrations.go @@ -105,6 +105,7 @@ var migrations = []Migration{ NewMigration("v1.6.0", "move user config to interface", moveUserConfigToInterface, true), NewMigration("v1.7.0", "add optional tags", addOptionalTags, true), NewMigration("v1.7.2", "expand avatar column length", expandAvatarColumnLength, false), + NewMigration("v1.8.0", "change admin menu", updateAdminMenuSettings, true), } func GetMigrations() []Migration { diff --git a/internal/migrations/v30.go b/internal/migrations/v30.go new file mode 100644 index 000000000..5d5d5223f --- /dev/null +++ b/internal/migrations/v30.go @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package migrations + +import ( + "context" + "encoding/json" + + "github.com/apache/answer/internal/base/constant" + "github.com/apache/answer/internal/base/reason" + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/schema" + "github.com/segmentfault/pacman/errors" + "xorm.io/builder" + "xorm.io/xorm" +) + +func updateAdminMenuSettings(ctx context.Context, x *xorm.Engine) (err error) { + err = splitWriteMenu(ctx, x) + if err != nil { + return + } + return +} + +// splitWriteMenu splits the site write settings into advanced, questions, and tags settings +func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { + var ( + siteInfo = &entity.SiteInfo{} + siteInfoAdvanced = &entity.SiteInfo{} + siteInfoQuestions = &entity.SiteInfo{} + siteInfoTags = &entity.SiteInfo{} + ) + exist, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeWrite}).Get(siteInfo) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + return err + } + if !exist { + return nil + } + siteWrite := &schema.SiteWriteResp{} + if err := json.Unmarshal([]byte(siteInfo.Content), siteWrite); err != nil { + return err + } + // site advanced settings + siteAdvanced := &schema.SiteAdvancedResp{ + MaxImageSize: siteWrite.MaxImageSize, + MaxAttachmentSize: siteWrite.MaxAttachmentSize, + MaxImageMegapixel: siteWrite.MaxImageMegapixel, + AuthorizedImageExtensions: siteWrite.AuthorizedImageExtensions, + AuthorizedAttachmentExtensions: siteWrite.AuthorizedAttachmentExtensions, + } + // site questions settings + siteQuestions := &schema.SiteQuestionsResp{ + MinimumContent: siteWrite.MinimumContent, + RestrictAnswer: siteWrite.RestrictAnswer, + } + // site tags settings + siteTags := &schema.SiteTagsResp{ + ReservedTags: siteWrite.ReservedTags, + RecommendTags: siteWrite.RecommendTags, + MinimumTags: siteWrite.MinimumTags, + RequiredTag: siteWrite.RequiredTag, + } + + // save site settings + // save advanced settings + existsAdvanced, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeWrite}).Get(siteInfoAdvanced) + if err != nil { + return err + } + advancedContent, err := json.Marshal(siteAdvanced) + if err != nil { + return err + } + if existsAdvanced { + _, err = x.Context(ctx).ID(siteInfoAdvanced.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeAdvanced, + Content: string(advancedContent), + Status: 1, + }) + if err != nil { + return err + } + } else { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ + Type: constant.SiteTypeAdvanced, + Content: string(advancedContent), + Status: 1, + }) + if err != nil { + return err + } + } + + // save questions settings + existsQuestions, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeQuestions}).Get(siteInfoQuestions) + if err != nil { + return err + } + questionsContent, err := json.Marshal(siteQuestions) + if err != nil { + return err + } + if existsQuestions { + _, err = x.Context(ctx).ID(siteInfoQuestions.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeQuestions, + Content: string(questionsContent), + Status: 1, + }) + if err != nil { + return err + } + } else { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ + Type: constant.SiteTypeQuestions, + Content: string(questionsContent), + Status: 1, + }) + if err != nil { + return err + } + } + + // save tags settings + existsTags, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeTags}).Get(siteInfoTags) + if err != nil { + return err + } + tagsContent, err := json.Marshal(siteTags) + if err != nil { + return err + } + if existsTags { + _, err = x.Context(ctx).ID(siteInfoTags.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeTags, + Content: string(tagsContent), + Status: 1, + }) + if err != nil { + return err + } + } else { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ + Type: constant.SiteTypeTags, + Content: string(tagsContent), + Status: 1, + }) + if err != nil { + return err + } + } + + return nil +} diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go index 1191492b9..d717bc9d3 100644 --- a/internal/router/answer_api_router.go +++ b/internal/router/answer_api_router.go @@ -347,8 +347,14 @@ func (a *AnswerAPIRouter) RegisterAnswerAdminAPIRouter(r *gin.RouterGroup) { r.PUT("/siteinfo/interface", a.adminSiteInfoController.UpdateInterface) r.GET("/siteinfo/branding", a.adminSiteInfoController.GetSiteBranding) r.PUT("/siteinfo/branding", a.adminSiteInfoController.UpdateBranding) - r.GET("/siteinfo/write", a.adminSiteInfoController.GetSiteWrite) - r.PUT("/siteinfo/write", a.adminSiteInfoController.UpdateSiteWrite) + + r.GET("/siteinfo/question", a.adminSiteInfoController.GetSiteQuestion) + r.PUT("/siteinfo/question", a.adminSiteInfoController.UpdateSiteQuestion) + r.GET("/siteinfo/tag", a.adminSiteInfoController.GetSiteTag) + r.PUT("/siteinfo/tag", a.adminSiteInfoController.UpdateSiteTag) + r.GET("/siteinfo/advanced", a.adminSiteInfoController.GetSiteAdvanced) + r.PUT("/siteinfo/advanced", a.adminSiteInfoController.UpdateSiteAdvanced) + r.GET("/siteinfo/legal", a.adminSiteInfoController.GetSiteLegal) r.PUT("/siteinfo/legal", a.adminSiteInfoController.UpdateSiteLegal) r.GET("/siteinfo/seo", a.adminSiteInfoController.GetSeo) diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index 7ab657512..daf49146c 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -89,21 +89,47 @@ type SiteWriteReq struct { UserID string `json:"-"` } -func (s *SiteWriteResp) GetMaxImageSize() int64 { +type SiteWriteResp SiteWriteReq + +// SiteQuestionsReq site questions settings request +type SiteQuestionsReq struct { + MinimumContent int `validate:"omitempty,gte=0,lte=65535" json:"min_content"` + RestrictAnswer bool `validate:"omitempty" json:"restrict_answer"` +} + +// SiteAdvancedReq site advanced settings request +type SiteAdvancedReq struct { + MaxImageSize int `validate:"omitempty,gt=0" json:"max_image_size"` + MaxAttachmentSize int `validate:"omitempty,gt=0" json:"max_attachment_size"` + MaxImageMegapixel int `validate:"omitempty,gt=0" json:"max_image_megapixel"` + AuthorizedImageExtensions []string `validate:"omitempty" json:"authorized_image_extensions"` + AuthorizedAttachmentExtensions []string `validate:"omitempty" json:"authorized_attachment_extensions"` +} + +// SiteTagsReq site tags settings request +type SiteTagsReq struct { + ReservedTags []*SiteWriteTag `validate:"omitempty,dive" json:"reserved_tags"` + RecommendTags []*SiteWriteTag `validate:"omitempty,dive" json:"recommend_tags"` + MinimumTags int `validate:"omitempty,gte=0,lte=5" json:"min_tags"` + RequiredTag bool `validate:"omitempty" json:"required_tag"` + UserID string `json:"-"` +} + +func (s *SiteAdvancedResp) GetMaxImageSize() int64 { if s.MaxImageSize <= 0 { return constant.DefaultMaxImageSize } return int64(s.MaxImageSize) * 1024 * 1024 } -func (s *SiteWriteResp) GetMaxAttachmentSize() int64 { +func (s *SiteAdvancedResp) GetMaxAttachmentSize() int64 { if s.MaxAttachmentSize <= 0 { return constant.DefaultMaxAttachmentSize } return int64(s.MaxAttachmentSize) * 1024 * 1024 } -func (s *SiteWriteResp) GetMaxImageMegapixel() int { +func (s *SiteAdvancedResp) GetMaxImageMegapixel() int { if s.MaxImageMegapixel <= 0 { return constant.DefaultMaxImageMegapixel } @@ -236,8 +262,9 @@ type ThemeOption struct { Value string `json:"value"` } -// SiteWriteResp site write response -type SiteWriteResp SiteWriteReq +type SiteQuestionsResp SiteQuestionsReq +type SiteAdvancedResp SiteAdvancedReq +type SiteTagsResp SiteTagsReq // SiteLegalResp site write response type SiteLegalResp SiteLegalReq @@ -260,7 +287,9 @@ type SiteInfoResp struct { CustomCssHtml *SiteCustomCssHTMLResp `json:"custom_css_html"` SiteSeo *SiteSeoResp `json:"site_seo"` SiteUsers *SiteUsersResp `json:"site_users"` - Write *SiteWriteResp `json:"site_write"` + Advanced *SiteAdvancedResp `json:"site_advanced"` + Questions *SiteQuestionsResp `json:"site_questions"` + Tags *SiteTagsResp `json:"site_tags"` Legal *SiteLegalSimpleResp `json:"site_legal"` Version string `json:"version"` Revision string `json:"revision"` diff --git a/internal/service/mock/siteinfo_repo_mock.go b/internal/service/mock/siteinfo_repo_mock.go index a98ceb68c..5d5429ba4 100644 --- a/internal/service/mock/siteinfo_repo_mock.go +++ b/internal/service/mock/siteinfo_repo_mock.go @@ -41,7 +41,6 @@ import ( type MockSiteInfoRepo struct { ctrl *gomock.Controller recorder *MockSiteInfoRepoMockRecorder - isgomock struct{} } // MockSiteInfoRepoMockRecorder is the mock recorder for MockSiteInfoRepo. @@ -72,7 +71,7 @@ func (m *MockSiteInfoRepo) GetByType(ctx context.Context, siteType string) (*ent } // GetByType indicates an expected call of GetByType. -func (mr *MockSiteInfoRepoMockRecorder) GetByType(ctx, siteType any) *gomock.Call { +func (mr *MockSiteInfoRepoMockRecorder) GetByType(ctx, siteType interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByType", reflect.TypeOf((*MockSiteInfoRepo)(nil).GetByType), ctx, siteType) } @@ -87,7 +86,7 @@ func (m *MockSiteInfoRepo) IsBrandingFileUsed(ctx context.Context, filePath stri } // IsBrandingFileUsed indicates an expected call of IsBrandingFileUsed. -func (mr *MockSiteInfoRepoMockRecorder) IsBrandingFileUsed(ctx, filePath any) *gomock.Call { +func (mr *MockSiteInfoRepoMockRecorder) IsBrandingFileUsed(ctx, filePath interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsBrandingFileUsed", reflect.TypeOf((*MockSiteInfoRepo)(nil).IsBrandingFileUsed), ctx, filePath) } @@ -101,7 +100,7 @@ func (m *MockSiteInfoRepo) SaveByType(ctx context.Context, siteType string, data } // SaveByType indicates an expected call of SaveByType. -func (mr *MockSiteInfoRepoMockRecorder) SaveByType(ctx, siteType, data any) *gomock.Call { +func (mr *MockSiteInfoRepoMockRecorder) SaveByType(ctx, siteType, data interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveByType", reflect.TypeOf((*MockSiteInfoRepo)(nil).SaveByType), ctx, siteType, data) } @@ -110,7 +109,6 @@ func (mr *MockSiteInfoRepoMockRecorder) SaveByType(ctx, siteType, data any) *gom type MockSiteInfoCommonService struct { ctrl *gomock.Controller recorder *MockSiteInfoCommonServiceMockRecorder - isgomock struct{} } // MockSiteInfoCommonServiceMockRecorder is the mock recorder for MockSiteInfoCommonService. @@ -139,7 +137,7 @@ func (m *MockSiteInfoCommonService) FormatAvatar(ctx context.Context, originalAv } // FormatAvatar indicates an expected call of FormatAvatar. -func (mr *MockSiteInfoCommonServiceMockRecorder) FormatAvatar(ctx, originalAvatarData, email, userStatus any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) FormatAvatar(ctx, originalAvatarData, email, userStatus interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FormatAvatar", reflect.TypeOf((*MockSiteInfoCommonService)(nil).FormatAvatar), ctx, originalAvatarData, email, userStatus) } @@ -153,11 +151,26 @@ func (m *MockSiteInfoCommonService) FormatListAvatar(ctx context.Context, userLi } // FormatListAvatar indicates an expected call of FormatListAvatar. -func (mr *MockSiteInfoCommonServiceMockRecorder) FormatListAvatar(ctx, userList any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) FormatListAvatar(ctx, userList interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FormatListAvatar", reflect.TypeOf((*MockSiteInfoCommonService)(nil).FormatListAvatar), ctx, userList) } +// GetSiteAdvanced mocks base method. +func (m *MockSiteInfoCommonService) GetSiteAdvanced(ctx context.Context) (*schema.SiteAdvancedResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteAdvanced", ctx) + ret0, _ := ret[0].(*schema.SiteAdvancedResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteAdvanced indicates an expected call of GetSiteAdvanced. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteAdvanced(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteAdvanced", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteAdvanced), ctx) +} + // GetSiteBranding mocks base method. func (m *MockSiteInfoCommonService) GetSiteBranding(ctx context.Context) (*schema.SiteBrandingResp, error) { m.ctrl.T.Helper() @@ -168,7 +181,7 @@ func (m *MockSiteInfoCommonService) GetSiteBranding(ctx context.Context) (*schem } // GetSiteBranding indicates an expected call of GetSiteBranding. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteBranding(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteBranding(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteBranding", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteBranding), ctx) } @@ -183,7 +196,7 @@ func (m *MockSiteInfoCommonService) GetSiteCustomCssHTML(ctx context.Context) (* } // GetSiteCustomCssHTML indicates an expected call of GetSiteCustomCssHTML. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteCustomCssHTML(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteCustomCssHTML(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteCustomCssHTML", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteCustomCssHTML), ctx) } @@ -198,7 +211,7 @@ func (m *MockSiteInfoCommonService) GetSiteGeneral(ctx context.Context) (*schema } // GetSiteGeneral indicates an expected call of GetSiteGeneral. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteGeneral(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteGeneral(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteGeneral", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteGeneral), ctx) } @@ -212,7 +225,7 @@ func (m *MockSiteInfoCommonService) GetSiteInfoByType(ctx context.Context, siteT } // GetSiteInfoByType indicates an expected call of GetSiteInfoByType. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInfoByType(ctx, siteType, resp any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInfoByType(ctx, siteType, resp interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteInfoByType", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteInfoByType), ctx, siteType, resp) } @@ -227,7 +240,7 @@ func (m *MockSiteInfoCommonService) GetSiteInterface(ctx context.Context) (*sche } // GetSiteInterface indicates an expected call of GetSiteInterface. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInterface(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInterface(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteInterface", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteInterface), ctx) } @@ -242,7 +255,7 @@ func (m *MockSiteInfoCommonService) GetSiteLegal(ctx context.Context) (*schema.S } // GetSiteLegal indicates an expected call of GetSiteLegal. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLegal(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLegal(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLegal", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLegal), ctx) } @@ -257,11 +270,26 @@ func (m *MockSiteInfoCommonService) GetSiteLogin(ctx context.Context) (*schema.S } // GetSiteLogin indicates an expected call of GetSiteLogin. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLogin", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLogin), ctx) } +// GetSiteQuestion mocks base method. +func (m *MockSiteInfoCommonService) GetSiteQuestion(ctx context.Context) (*schema.SiteQuestionsResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteQuestion", ctx) + ret0, _ := ret[0].(*schema.SiteQuestionsResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteQuestion indicates an expected call of GetSiteQuestion. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteQuestion(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteQuestion", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteQuestion), ctx) +} + // GetSiteSeo mocks base method. func (m *MockSiteInfoCommonService) GetSiteSeo(ctx context.Context) (*schema.SiteSeoResp, error) { m.ctrl.T.Helper() @@ -272,11 +300,26 @@ func (m *MockSiteInfoCommonService) GetSiteSeo(ctx context.Context) (*schema.Sit } // GetSiteSeo indicates an expected call of GetSiteSeo. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteSeo(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteSeo(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteSeo", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteSeo), ctx) } +// GetSiteTag mocks base method. +func (m *MockSiteInfoCommonService) GetSiteTag(ctx context.Context) (*schema.SiteTagsResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteTag", ctx) + ret0, _ := ret[0].(*schema.SiteTagsResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteTag indicates an expected call of GetSiteTag. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteTag(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteTag", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteTag), ctx) +} + // GetSiteTheme mocks base method. func (m *MockSiteInfoCommonService) GetSiteTheme(ctx context.Context) (*schema.SiteThemeResp, error) { m.ctrl.T.Helper() @@ -287,7 +330,7 @@ func (m *MockSiteInfoCommonService) GetSiteTheme(ctx context.Context) (*schema.S } // GetSiteTheme indicates an expected call of GetSiteTheme. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteTheme(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteTheme(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteTheme", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteTheme), ctx) } @@ -302,7 +345,7 @@ func (m *MockSiteInfoCommonService) GetSiteUsers(ctx context.Context) (*schema.S } // GetSiteUsers indicates an expected call of GetSiteUsers. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsers(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsers(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteUsers", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteUsers), ctx) } @@ -317,7 +360,7 @@ func (m *MockSiteInfoCommonService) GetSiteWrite(ctx context.Context) (*schema.S } // GetSiteWrite indicates an expected call of GetSiteWrite. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteWrite(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteWrite(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteWrite", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteWrite), ctx) } @@ -331,7 +374,7 @@ func (m *MockSiteInfoCommonService) IsBrandingFileUsed(ctx context.Context, file } // IsBrandingFileUsed indicates an expected call of IsBrandingFileUsed. -func (mr *MockSiteInfoCommonServiceMockRecorder) IsBrandingFileUsed(ctx, filePath any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) IsBrandingFileUsed(ctx, filePath interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsBrandingFileUsed", reflect.TypeOf((*MockSiteInfoCommonService)(nil).IsBrandingFileUsed), ctx, filePath) } diff --git a/internal/service/question_common/question.go b/internal/service/question_common/question.go index 557a5db15..3a7306342 100644 --- a/internal/service/question_common/question.go +++ b/internal/service/question_common/question.go @@ -900,7 +900,7 @@ func (qs *QuestionCommon) tryToGetQuestionIDFromMsg(ctx context.Context, closeMs } func (qs *QuestionCommon) GetMinimumContentLength(ctx context.Context) (int, error) { - siteInfo, err := qs.siteInfoService.GetSiteWrite(ctx) + siteInfo, err := qs.siteInfoService.GetSiteQuestion(ctx) if err != nil { return 6, err } diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index f355d09f4..b633ed421 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -103,17 +103,14 @@ func (s *SiteInfoService) GetSiteUsers(ctx context.Context) (resp *schema.SiteUs return s.siteInfoCommonService.GetSiteUsers(ctx) } -// GetSiteWrite get site info write -func (s *SiteInfoService) GetSiteWrite(ctx context.Context) (resp *schema.SiteWriteResp, err error) { - resp = &schema.SiteWriteResp{} - siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeWrite) +// GetSiteTag get site info write +func (s *SiteInfoService) GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error) { + resp = &schema.SiteTagsResp{} + _, err = s.siteInfoCommonService.GetSiteTag(ctx) if err != nil { log.Error(err) return resp, nil } - if exist { - _ = json.Unmarshal([]byte(siteInfo.Content), resp) - } resp.RecommendTags, err = s.tagCommonService.GetSiteWriteRecommendTag(ctx) if err != nil { @@ -126,6 +123,16 @@ func (s *SiteInfoService) GetSiteWrite(ctx context.Context) (resp *schema.SiteWr return resp, nil } +// GetSiteQuestion get site questions settings +func (s *SiteInfoService) GetSiteQuestion(ctx context.Context) (resp *schema.SiteQuestionsResp, err error) { + return s.siteInfoCommonService.GetSiteQuestion(ctx) +} + +// GetSiteAdvanced get site advanced settings +func (s *SiteInfoService) GetSiteAdvanced(ctx context.Context) (resp *schema.SiteAdvancedResp, err error) { + return s.siteInfoCommonService.GetSiteAdvanced(ctx) +} + // GetSiteLegal get site legal info func (s *SiteInfoService) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) { return s.siteInfoCommonService.GetSiteLegal(ctx) @@ -182,8 +189,30 @@ func (s *SiteInfoService) SaveSiteBranding(ctx context.Context, req *schema.Site return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeBranding, data) } -// SaveSiteWrite save site configuration about write -func (s *SiteInfoService) SaveSiteWrite(ctx context.Context, req *schema.SiteWriteReq) (resp any, err error) { +// SaveSiteAdvanced save site advanced configuration +func (s *SiteInfoService) SaveSiteAdvanced(ctx context.Context, req *schema.SiteAdvancedReq) (resp any, err error) { + content, _ := json.Marshal(req) + data := &entity.SiteInfo{ + Type: constant.SiteTypeAdvanced, + Content: string(content), + Status: 1, + } + return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeAdvanced, data) +} + +// SaveSiteQuestions save site questions configuration +func (s *SiteInfoService) SaveSiteQuestions(ctx context.Context, req *schema.SiteQuestionsReq) (resp any, err error) { + content, _ := json.Marshal(req) + data := &entity.SiteInfo{ + Type: constant.SiteTypeQuestions, + Content: string(content), + Status: 1, + } + return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeQuestions, data) +} + +// SaveSiteTags save site tags configuration +func (s *SiteInfoService) SaveSiteTags(ctx context.Context, req *schema.SiteTagsReq) (resp any, err error) { recommendTags, reservedTags := make([]string, 0), make([]string, 0) recommendTagMapping, reservedTagMapping := make(map[string]bool), make(map[string]bool) for _, tag := range req.ReservedTags { @@ -210,11 +239,11 @@ func (s *SiteInfoService) SaveSiteWrite(ctx context.Context, req *schema.SiteWri content, _ := json.Marshal(req) data := &entity.SiteInfo{ - Type: constant.SiteTypeWrite, + Type: constant.SiteTypeTags, Content: string(content), Status: 1, } - return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeWrite, data) + return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeTags, data) } // SaveSiteLegal save site legal configuration diff --git a/internal/service/siteinfo_common/siteinfo_service.go b/internal/service/siteinfo_common/siteinfo_service.go index fda117229..87bc7ee15 100644 --- a/internal/service/siteinfo_common/siteinfo_service.go +++ b/internal/service/siteinfo_common/siteinfo_service.go @@ -51,6 +51,9 @@ type SiteInfoCommonService interface { FormatAvatar(ctx context.Context, originalAvatarData, email string, userStatus int) *schema.AvatarInfo FormatListAvatar(ctx context.Context, userList []*entity.User) (userID2AvatarMapping map[string]*schema.AvatarInfo) GetSiteWrite(ctx context.Context) (resp *schema.SiteWriteResp, err error) + GetSiteAdvanced(ctx context.Context) (resp *schema.SiteAdvancedResp, err error) + GetSiteQuestion(ctx context.Context) (resp *schema.SiteQuestionsResp, err error) + GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) GetSiteLogin(ctx context.Context) (resp *schema.SiteLoginResp, err error) GetSiteCustomCssHTML(ctx context.Context) (resp *schema.SiteCustomCssHTMLResp, err error) @@ -167,6 +170,33 @@ func (s *siteInfoCommonService) GetSiteWrite(ctx context.Context) (resp *schema. return resp, nil } +// GetSiteAdvanced get site info advanced +func (s *siteInfoCommonService) GetSiteAdvanced(ctx context.Context) (resp *schema.SiteAdvancedResp, err error) { + resp = &schema.SiteAdvancedResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeAdvanced, resp); err != nil { + return nil, err + } + return resp, nil +} + +// GetSiteQuestion get site info question +func (s *siteInfoCommonService) GetSiteQuestion(ctx context.Context) (resp *schema.SiteQuestionsResp, err error) { + resp = &schema.SiteQuestionsResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeQuestions, resp); err != nil { + return nil, err + } + return resp, nil +} + +// GetSiteTag get site info tag +func (s *siteInfoCommonService) GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error) { + resp = &schema.SiteTagsResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeTags, resp); err != nil { + return nil, err + } + return resp, nil +} + // GetSiteLegal get site info write func (s *siteInfoCommonService) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) { resp = &schema.SiteLegalResp{} diff --git a/internal/service/tag_common/tag_common.go b/internal/service/tag_common/tag_common.go index 9ca8e100f..0da9f6fd5 100644 --- a/internal/service/tag_common/tag_common.go +++ b/internal/service/tag_common/tag_common.go @@ -270,7 +270,7 @@ func (ts *TagCommonService) GetTagListByNames(ctx context.Context, tagNames []st } func (ts *TagCommonService) ExistRecommend(ctx context.Context, tags []*schema.TagItem) (bool, error) { - taginfo, err := ts.siteInfoService.GetSiteWrite(ctx) + taginfo, err := ts.siteInfoService.GetSiteTag(ctx) if err != nil { return false, err } @@ -295,7 +295,7 @@ func (ts *TagCommonService) ExistRecommend(ctx context.Context, tags []*schema.T } func (ts *TagCommonService) GetMinimumTags(ctx context.Context) (int, error) { - siteInfo, err := ts.siteInfoService.GetSiteWrite(ctx) + siteInfo, err := ts.siteInfoService.GetSiteTag(ctx) if err != nil { return 1, err } @@ -469,7 +469,7 @@ func (ts *TagCommonService) TagsFormatRecommendAndReserved(ctx context.Context, if len(tagList) == 0 { return } - tagConfig, err := ts.siteInfoService.GetSiteWrite(ctx) + tagConfig, err := ts.siteInfoService.GetSiteTag(ctx) if err != nil { log.Error(err) return @@ -485,7 +485,7 @@ func (ts *TagCommonService) tagFormatRecommendAndReserved(ctx context.Context, t if tag == nil { return } - tagConfig, err := ts.siteInfoService.GetSiteWrite(ctx) + tagConfig, err := ts.siteInfoService.GetSiteTag(ctx) if err != nil { log.Error(err) return diff --git a/internal/service/uploader/upload.go b/internal/service/uploader/upload.go index 8dea746ce..58f808468 100644 --- a/internal/service/uploader/upload.go +++ b/internal/service/uploader/upload.go @@ -109,12 +109,12 @@ func (us *uploaderService) UploadAvatarFile(ctx *gin.Context, userID string) (ur return url, nil } - siteWrite, err := us.siteInfoService.GetSiteWrite(ctx) + siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx) if err != nil { return "", err } - ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteWrite.GetMaxImageSize()) + ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteAdvanced.GetMaxImageSize()) file, fileHeader, err := ctx.Request.FormFile("file") if err != nil { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) @@ -201,12 +201,12 @@ func (us *uploaderService) UploadPostFile(ctx *gin.Context, userID string) ( return url, nil } - siteWrite, err := us.siteInfoService.GetSiteWrite(ctx) + siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx) if err != nil { return "", err } - ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteWrite.GetMaxImageSize()) + ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteAdvanced.GetMaxImageSize()) file, fileHeader, err := ctx.Request.FormFile("file") if err != nil { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) @@ -214,7 +214,7 @@ func (us *uploaderService) UploadPostFile(ctx *gin.Context, userID string) ( defer func() { _ = file.Close() }() - if checker.IsUnAuthorizedExtension(fileHeader.Filename, siteWrite.AuthorizedImageExtensions) { + if checker.IsUnAuthorizedExtension(fileHeader.Filename, siteAdvanced.AuthorizedImageExtensions) { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) } @@ -239,7 +239,7 @@ func (us *uploaderService) UploadPostAttachment(ctx *gin.Context, userID string) return url, nil } - resp, err := us.siteInfoService.GetSiteWrite(ctx) + resp, err := us.siteInfoService.GetSiteAdvanced(ctx) if err != nil { return "", err } @@ -277,12 +277,12 @@ func (us *uploaderService) UploadBrandingFile(ctx *gin.Context, userID string) ( return url, nil } - siteWrite, err := us.siteInfoService.GetSiteWrite(ctx) + siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx) if err != nil { return "", err } - ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteWrite.GetMaxImageSize()) + ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteAdvanced.GetMaxImageSize()) file, fileHeader, err := ctx.Request.FormFile("file") if err != nil { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) @@ -311,7 +311,7 @@ func (us *uploaderService) uploadImageFile(ctx *gin.Context, file *multipart.Fil if err != nil { return "", err } - siteWrite, err := us.siteInfoService.GetSiteWrite(ctx) + siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx) if err != nil { return "", err } @@ -328,7 +328,7 @@ func (us *uploaderService) uploadImageFile(ctx *gin.Context, file *multipart.Fil _ = src.Close() }() - if !checker.DecodeAndCheckImageFile(filePath, siteWrite.GetMaxImageMegapixel()) { + if !checker.DecodeAndCheckImageFile(filePath, siteAdvanced.GetMaxImageMegapixel()) { return "", errors.BadRequest(reason.UploadFileUnsupportedFileFormat) } @@ -364,17 +364,17 @@ func (us *uploaderService) uploadAttachmentFile(ctx *gin.Context, file *multipar func (us *uploaderService) tryToUploadByPlugin(ctx *gin.Context, source plugin.UploadSource) ( url string, err error) { - siteWrite, err := us.siteInfoService.GetSiteWrite(ctx) + siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx) if err != nil { return "", err } cond := plugin.UploadFileCondition{ Source: source, - MaxImageSize: siteWrite.MaxImageSize, - MaxAttachmentSize: siteWrite.MaxAttachmentSize, - MaxImageMegapixel: siteWrite.MaxImageMegapixel, - AuthorizedImageExtensions: siteWrite.AuthorizedImageExtensions, - AuthorizedAttachmentExtensions: siteWrite.AuthorizedAttachmentExtensions, + MaxImageSize: siteAdvanced.MaxImageSize, + MaxAttachmentSize: siteAdvanced.MaxAttachmentSize, + MaxImageMegapixel: siteAdvanced.MaxImageMegapixel, + AuthorizedImageExtensions: siteAdvanced.AuthorizedImageExtensions, + AuthorizedAttachmentExtensions: siteAdvanced.AuthorizedAttachmentExtensions, } _ = plugin.CallStorage(func(fn plugin.Storage) error { resp := fn.UploadFile(ctx, cond) From 3cd3e4a888dca7829b3489efc7cf844e8f0403e5 Mon Sep 17 00:00:00 2001 From: kumfo Date: Tue, 20 Jan 2026 15:32:45 +0800 Subject: [PATCH 57/92] feat(menu): update admin menu settings to include questions, tags, and advanced options --- docs/docs.go | 457 ++++++++++++++++++++++++++++++---------------- docs/swagger.json | 438 ++++++++++++++++++++++++++++++-------------- docs/swagger.yaml | 315 ++++++++++++++++++++------------ 3 files changed, 804 insertions(+), 406 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index 5e9d5b39d..73d85436c 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,22 +1,3 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - // Package docs Code generated by swaggo/swag. DO NOT EDIT package docs @@ -875,6 +856,77 @@ const docTemplate = `{ } } }, + "/answer/admin/api/siteinfo/advanced": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site advanced setting", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site advanced setting", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteAdvancedResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site advanced info", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site advanced info", + "parameters": [ + { + "description": "advanced settings", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteAdvancedReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/branding": { "get": { "security": [ @@ -1301,6 +1353,77 @@ const docTemplate = `{ } } }, + "/answer/admin/api/siteinfo/question": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site questions setting", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site questions setting", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteQuestionsResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site question settings", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site question settings", + "parameters": [ + { + "description": "questions settings", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteQuestionsReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/seo": { "get": { "security": [ @@ -1372,21 +1495,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/theme": { + "/answer/admin/api/siteinfo/tag": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site info theme config", + "description": "get site tags setting", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site info theme config", + "summary": "get site tags setting", "responses": { "200": { "description": "OK", @@ -1399,7 +1522,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteThemeResp" + "$ref": "#/definitions/schema.SiteTagsResp" } } } @@ -1414,22 +1537,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site custom css html config", + "description": "update site tag settings", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site custom css html config", + "summary": "update site tag settings", "parameters": [ { - "description": "login info", + "description": "tags settings", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteThemeReq" + "$ref": "#/definitions/schema.SiteTagsReq" } } ], @@ -1443,21 +1566,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/users": { + "/answer/admin/api/siteinfo/theme": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site user config", + "description": "get site info theme config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site user config", + "summary": "get site info theme config", "responses": { "200": { "description": "OK", @@ -1470,7 +1593,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteUsersResp" + "$ref": "#/definitions/schema.SiteThemeResp" } } } @@ -1485,22 +1608,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site info config about users", + "description": "update site custom css html config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site info config about users", + "summary": "update site custom css html config", "parameters": [ { - "description": "users info", + "description": "login info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteUsersReq" + "$ref": "#/definitions/schema.SiteThemeReq" } } ], @@ -1514,21 +1637,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/write": { + "/answer/admin/api/siteinfo/users": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site interface", + "description": "get site user config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site interface", + "summary": "get site user config", "responses": { "200": { "description": "OK", @@ -1541,7 +1664,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteWriteResp" + "$ref": "#/definitions/schema.SiteUsersResp" } } } @@ -1556,22 +1679,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site write info", + "description": "update site info config about users", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site write info", + "summary": "update site info config about users", "parameters": [ { - "description": "write info", + "description": "users info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteWriteReq" + "$ref": "#/definitions/schema.SiteUsersReq" } } ], @@ -10497,6 +10620,58 @@ const docTemplate = `{ } } }, + "schema.SiteAdvancedReq": { + "type": "object", + "properties": { + "authorized_attachment_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "authorized_image_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "max_attachment_size": { + "type": "integer" + }, + "max_image_megapixel": { + "type": "integer" + }, + "max_image_size": { + "type": "integer" + } + } + }, + "schema.SiteAdvancedResp": { + "type": "object", + "properties": { + "authorized_attachment_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "authorized_image_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "max_attachment_size": { + "type": "integer" + }, + "max_image_megapixel": { + "type": "integer" + }, + "max_image_size": { + "type": "integer" + } + } + }, "schema.SiteBrandingReq": { "type": "object", "properties": { @@ -10676,18 +10851,24 @@ const docTemplate = `{ "revision": { "type": "string" }, + "site_advanced": { + "$ref": "#/definitions/schema.SiteAdvancedResp" + }, "site_legal": { "$ref": "#/definitions/schema.SiteLegalSimpleResp" }, + "site_questions": { + "$ref": "#/definitions/schema.SiteQuestionsResp" + }, "site_seo": { "$ref": "#/definitions/schema.SiteSeoResp" }, + "site_tags": { + "$ref": "#/definitions/schema.SiteTagsResp" + }, "site_users": { "$ref": "#/definitions/schema.SiteUsersResp" }, - "site_write": { - "$ref": "#/definitions/schema.SiteWriteResp" - }, "theme": { "$ref": "#/definitions/schema.SiteThemeResp" }, @@ -10867,6 +11048,32 @@ const docTemplate = `{ } } }, + "schema.SiteQuestionsReq": { + "type": "object", + "properties": { + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "restrict_answer": { + "type": "boolean" + } + } + }, + "schema.SiteQuestionsResp": { + "type": "object", + "properties": { + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "restrict_answer": { + "type": "boolean" + } + } + }, "schema.SiteSeoReq": { "type": "object", "required": [ @@ -10901,6 +11108,56 @@ const docTemplate = `{ } } }, + "schema.SiteTagsReq": { + "type": "object", + "properties": { + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, + "recommend_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + }, + "required_tag": { + "type": "boolean" + }, + "reserved_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + } + } + }, + "schema.SiteTagsResp": { + "type": "object", + "properties": { + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, + "recommend_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + }, + "required_tag": { + "type": "boolean" + }, + "reserved_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + } + } + }, "schema.SiteThemeReq": { "type": "object", "required": [ @@ -11014,114 +11271,6 @@ const docTemplate = `{ } } }, - "schema.SiteWriteReq": { - "type": "object", - "properties": { - "authorized_attachment_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "authorized_image_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "max_attachment_size": { - "type": "integer" - }, - "max_image_megapixel": { - "type": "integer" - }, - "max_image_size": { - "type": "integer" - }, - "min_content": { - "type": "integer", - "maximum": 65535, - "minimum": 0 - }, - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, - "recommend_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "required_tag": { - "type": "boolean" - }, - "reserved_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "restrict_answer": { - "type": "boolean" - } - } - }, - "schema.SiteWriteResp": { - "type": "object", - "properties": { - "authorized_attachment_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "authorized_image_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "max_attachment_size": { - "type": "integer" - }, - "max_image_megapixel": { - "type": "integer" - }, - "max_image_size": { - "type": "integer" - }, - "min_content": { - "type": "integer", - "maximum": 65535, - "minimum": 0 - }, - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, - "recommend_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "required_tag": { - "type": "boolean" - }, - "reserved_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "restrict_answer": { - "type": "boolean" - } - } - }, "schema.SiteWriteTag": { "type": "object", "required": [ diff --git a/docs/swagger.json b/docs/swagger.json index e0f6378e4..6dbecc50a 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -848,6 +848,77 @@ } } }, + "/answer/admin/api/siteinfo/advanced": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site advanced setting", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site advanced setting", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteAdvancedResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site advanced info", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site advanced info", + "parameters": [ + { + "description": "advanced settings", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteAdvancedReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/branding": { "get": { "security": [ @@ -1274,6 +1345,77 @@ } } }, + "/answer/admin/api/siteinfo/question": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site questions setting", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site questions setting", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteQuestionsResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site question settings", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site question settings", + "parameters": [ + { + "description": "questions settings", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteQuestionsReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/seo": { "get": { "security": [ @@ -1345,21 +1487,21 @@ } } }, - "/answer/admin/api/siteinfo/theme": { + "/answer/admin/api/siteinfo/tag": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site info theme config", + "description": "get site tags setting", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site info theme config", + "summary": "get site tags setting", "responses": { "200": { "description": "OK", @@ -1372,7 +1514,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteThemeResp" + "$ref": "#/definitions/schema.SiteTagsResp" } } } @@ -1387,22 +1529,22 @@ "ApiKeyAuth": [] } ], - "description": "update site custom css html config", + "description": "update site tag settings", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site custom css html config", + "summary": "update site tag settings", "parameters": [ { - "description": "login info", + "description": "tags settings", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteThemeReq" + "$ref": "#/definitions/schema.SiteTagsReq" } } ], @@ -1416,21 +1558,21 @@ } } }, - "/answer/admin/api/siteinfo/users": { + "/answer/admin/api/siteinfo/theme": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site user config", + "description": "get site info theme config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site user config", + "summary": "get site info theme config", "responses": { "200": { "description": "OK", @@ -1443,7 +1585,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteUsersResp" + "$ref": "#/definitions/schema.SiteThemeResp" } } } @@ -1458,22 +1600,22 @@ "ApiKeyAuth": [] } ], - "description": "update site info config about users", + "description": "update site custom css html config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site info config about users", + "summary": "update site custom css html config", "parameters": [ { - "description": "users info", + "description": "login info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteUsersReq" + "$ref": "#/definitions/schema.SiteThemeReq" } } ], @@ -1487,21 +1629,21 @@ } } }, - "/answer/admin/api/siteinfo/write": { + "/answer/admin/api/siteinfo/users": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site interface", + "description": "get site user config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site interface", + "summary": "get site user config", "responses": { "200": { "description": "OK", @@ -1514,7 +1656,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteWriteResp" + "$ref": "#/definitions/schema.SiteUsersResp" } } } @@ -1529,22 +1671,22 @@ "ApiKeyAuth": [] } ], - "description": "update site write info", + "description": "update site info config about users", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site write info", + "summary": "update site info config about users", "parameters": [ { - "description": "write info", + "description": "users info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteWriteReq" + "$ref": "#/definitions/schema.SiteUsersReq" } } ], @@ -10470,6 +10612,58 @@ } } }, + "schema.SiteAdvancedReq": { + "type": "object", + "properties": { + "authorized_attachment_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "authorized_image_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "max_attachment_size": { + "type": "integer" + }, + "max_image_megapixel": { + "type": "integer" + }, + "max_image_size": { + "type": "integer" + } + } + }, + "schema.SiteAdvancedResp": { + "type": "object", + "properties": { + "authorized_attachment_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "authorized_image_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "max_attachment_size": { + "type": "integer" + }, + "max_image_megapixel": { + "type": "integer" + }, + "max_image_size": { + "type": "integer" + } + } + }, "schema.SiteBrandingReq": { "type": "object", "properties": { @@ -10649,18 +10843,24 @@ "revision": { "type": "string" }, + "site_advanced": { + "$ref": "#/definitions/schema.SiteAdvancedResp" + }, "site_legal": { "$ref": "#/definitions/schema.SiteLegalSimpleResp" }, + "site_questions": { + "$ref": "#/definitions/schema.SiteQuestionsResp" + }, "site_seo": { "$ref": "#/definitions/schema.SiteSeoResp" }, + "site_tags": { + "$ref": "#/definitions/schema.SiteTagsResp" + }, "site_users": { "$ref": "#/definitions/schema.SiteUsersResp" }, - "site_write": { - "$ref": "#/definitions/schema.SiteWriteResp" - }, "theme": { "$ref": "#/definitions/schema.SiteThemeResp" }, @@ -10840,6 +11040,32 @@ } } }, + "schema.SiteQuestionsReq": { + "type": "object", + "properties": { + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "restrict_answer": { + "type": "boolean" + } + } + }, + "schema.SiteQuestionsResp": { + "type": "object", + "properties": { + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "restrict_answer": { + "type": "boolean" + } + } + }, "schema.SiteSeoReq": { "type": "object", "required": [ @@ -10874,6 +11100,56 @@ } } }, + "schema.SiteTagsReq": { + "type": "object", + "properties": { + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, + "recommend_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + }, + "required_tag": { + "type": "boolean" + }, + "reserved_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + } + } + }, + "schema.SiteTagsResp": { + "type": "object", + "properties": { + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, + "recommend_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + }, + "required_tag": { + "type": "boolean" + }, + "reserved_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + } + } + }, "schema.SiteThemeReq": { "type": "object", "required": [ @@ -10987,114 +11263,6 @@ } } }, - "schema.SiteWriteReq": { - "type": "object", - "properties": { - "authorized_attachment_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "authorized_image_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "max_attachment_size": { - "type": "integer" - }, - "max_image_megapixel": { - "type": "integer" - }, - "max_image_size": { - "type": "integer" - }, - "min_content": { - "type": "integer", - "maximum": 65535, - "minimum": 0 - }, - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, - "recommend_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "required_tag": { - "type": "boolean" - }, - "reserved_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "restrict_answer": { - "type": "boolean" - } - } - }, - "schema.SiteWriteResp": { - "type": "object", - "properties": { - "authorized_attachment_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "authorized_image_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "max_attachment_size": { - "type": "integer" - }, - "max_image_megapixel": { - "type": "integer" - }, - "max_image_size": { - "type": "integer" - }, - "min_content": { - "type": "integer", - "maximum": 65535, - "minimum": 0 - }, - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, - "recommend_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "required_tag": { - "type": "boolean" - }, - "reserved_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "restrict_answer": { - "type": "boolean" - } - } - }, "schema.SiteWriteTag": { "type": "object", "required": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index e0244083b..f4107cd6b 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,20 +1,3 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - basePath: / definitions: constant.NotificationChannelKey: @@ -2072,6 +2055,40 @@ definitions: required: - user_id type: object + schema.SiteAdvancedReq: + properties: + authorized_attachment_extensions: + items: + type: string + type: array + authorized_image_extensions: + items: + type: string + type: array + max_attachment_size: + type: integer + max_image_megapixel: + type: integer + max_image_size: + type: integer + type: object + schema.SiteAdvancedResp: + properties: + authorized_attachment_extensions: + items: + type: string + type: array + authorized_image_extensions: + items: + type: string + type: array + max_attachment_size: + type: integer + max_image_megapixel: + type: integer + max_image_size: + type: integer + type: object schema.SiteBrandingReq: properties: favicon: @@ -2200,14 +2217,18 @@ definitions: $ref: '#/definitions/schema.SiteLoginResp' revision: type: string + site_advanced: + $ref: '#/definitions/schema.SiteAdvancedResp' site_legal: $ref: '#/definitions/schema.SiteLegalSimpleResp' + site_questions: + $ref: '#/definitions/schema.SiteQuestionsResp' site_seo: $ref: '#/definitions/schema.SiteSeoResp' + site_tags: + $ref: '#/definitions/schema.SiteTagsResp' site_users: $ref: '#/definitions/schema.SiteUsersResp' - site_write: - $ref: '#/definitions/schema.SiteWriteResp' theme: $ref: '#/definitions/schema.SiteThemeResp' version: @@ -2329,6 +2350,24 @@ definitions: login_required: type: boolean type: object + schema.SiteQuestionsReq: + properties: + min_content: + maximum: 65535 + minimum: 0 + type: integer + restrict_answer: + type: boolean + type: object + schema.SiteQuestionsResp: + properties: + min_content: + maximum: 65535 + minimum: 0 + type: integer + restrict_answer: + type: boolean + type: object schema.SiteSeoReq: properties: permalink: @@ -2353,6 +2392,40 @@ definitions: - permalink - robots type: object + schema.SiteTagsReq: + properties: + min_tags: + maximum: 5 + minimum: 0 + type: integer + recommend_tags: + items: + $ref: '#/definitions/schema.SiteWriteTag' + type: array + required_tag: + type: boolean + reserved_tags: + items: + $ref: '#/definitions/schema.SiteWriteTag' + type: array + type: object + schema.SiteTagsResp: + properties: + min_tags: + maximum: 5 + minimum: 0 + type: integer + recommend_tags: + items: + $ref: '#/definitions/schema.SiteWriteTag' + type: array + required_tag: + type: boolean + reserved_tags: + items: + $ref: '#/definitions/schema.SiteWriteTag' + type: array + type: object schema.SiteThemeReq: properties: color_scheme: @@ -2429,80 +2502,6 @@ definitions: required: - default_avatar type: object - schema.SiteWriteReq: - properties: - authorized_attachment_extensions: - items: - type: string - type: array - authorized_image_extensions: - items: - type: string - type: array - max_attachment_size: - type: integer - max_image_megapixel: - type: integer - max_image_size: - type: integer - min_content: - maximum: 65535 - minimum: 0 - type: integer - min_tags: - maximum: 5 - minimum: 0 - type: integer - recommend_tags: - items: - $ref: '#/definitions/schema.SiteWriteTag' - type: array - required_tag: - type: boolean - reserved_tags: - items: - $ref: '#/definitions/schema.SiteWriteTag' - type: array - restrict_answer: - type: boolean - type: object - schema.SiteWriteResp: - properties: - authorized_attachment_extensions: - items: - type: string - type: array - authorized_image_extensions: - items: - type: string - type: array - max_attachment_size: - type: integer - max_image_megapixel: - type: integer - max_image_size: - type: integer - min_content: - maximum: 65535 - minimum: 0 - type: integer - min_tags: - maximum: 5 - minimum: 0 - type: integer - recommend_tags: - items: - $ref: '#/definitions/schema.SiteWriteTag' - type: array - required_tag: - type: boolean - reserved_tags: - items: - $ref: '#/definitions/schema.SiteWriteTag' - type: array - restrict_answer: - type: boolean - type: object schema.SiteWriteTag: properties: display_name: @@ -3702,6 +3701,47 @@ paths: summary: update smtp config tags: - admin + /answer/admin/api/siteinfo/advanced: + get: + description: get site advanced setting + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteAdvancedResp' + type: object + security: + - ApiKeyAuth: [] + summary: get site advanced setting + tags: + - admin + put: + description: update site advanced info + parameters: + - description: advanced settings + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteAdvancedReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update site advanced info + tags: + - admin /answer/admin/api/siteinfo/branding: get: description: get site interface @@ -3948,6 +3988,47 @@ paths: summary: update site login tags: - admin + /answer/admin/api/siteinfo/question: + get: + description: get site questions setting + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteQuestionsResp' + type: object + security: + - ApiKeyAuth: [] + summary: get site questions setting + tags: + - admin + put: + description: update site question settings + parameters: + - description: questions settings + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteQuestionsReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update site question settings + tags: + - admin /answer/admin/api/siteinfo/seo: get: description: get site seo information @@ -3989,9 +4070,9 @@ paths: summary: update site seo information tags: - admin - /answer/admin/api/siteinfo/theme: + /answer/admin/api/siteinfo/tag: get: - description: get site info theme config + description: get site tags setting produces: - application/json responses: @@ -4002,22 +4083,22 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteThemeResp' + $ref: '#/definitions/schema.SiteTagsResp' type: object security: - ApiKeyAuth: [] - summary: get site info theme config + summary: get site tags setting tags: - admin put: - description: update site custom css html config + description: update site tag settings parameters: - - description: login info + - description: tags settings in: body name: data required: true schema: - $ref: '#/definitions/schema.SiteThemeReq' + $ref: '#/definitions/schema.SiteTagsReq' produces: - application/json responses: @@ -4027,12 +4108,12 @@ paths: $ref: '#/definitions/handler.RespBody' security: - ApiKeyAuth: [] - summary: update site custom css html config + summary: update site tag settings tags: - admin - /answer/admin/api/siteinfo/users: + /answer/admin/api/siteinfo/theme: get: - description: get site user config + description: get site info theme config produces: - application/json responses: @@ -4043,22 +4124,22 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteUsersResp' + $ref: '#/definitions/schema.SiteThemeResp' type: object security: - ApiKeyAuth: [] - summary: get site user config + summary: get site info theme config tags: - admin put: - description: update site info config about users + description: update site custom css html config parameters: - - description: users info + - description: login info in: body name: data required: true schema: - $ref: '#/definitions/schema.SiteUsersReq' + $ref: '#/definitions/schema.SiteThemeReq' produces: - application/json responses: @@ -4068,12 +4149,12 @@ paths: $ref: '#/definitions/handler.RespBody' security: - ApiKeyAuth: [] - summary: update site info config about users + summary: update site custom css html config tags: - admin - /answer/admin/api/siteinfo/write: + /answer/admin/api/siteinfo/users: get: - description: get site interface + description: get site user config produces: - application/json responses: @@ -4084,22 +4165,22 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteWriteResp' + $ref: '#/definitions/schema.SiteUsersResp' type: object security: - ApiKeyAuth: [] - summary: get site interface + summary: get site user config tags: - admin put: - description: update site write info + description: update site info config about users parameters: - - description: write info + - description: users info in: body name: data required: true schema: - $ref: '#/definitions/schema.SiteWriteReq' + $ref: '#/definitions/schema.SiteUsersReq' produces: - application/json responses: @@ -4109,7 +4190,7 @@ paths: $ref: '#/definitions/handler.RespBody' security: - ApiKeyAuth: [] - summary: update site write info + summary: update site info config about users tags: - admin /answer/admin/api/theme/options: From 0d7979e901983ae14e97a2404f3e7a83bc51a812 Mon Sep 17 00:00:00 2001 From: kumfo Date: Wed, 21 Jan 2026 09:39:37 +0800 Subject: [PATCH 58/92] feat(siteinfo): add users settings endpoint and update interface settings structure --- docs/docs.go | 127 ++++++++++++++++-- docs/swagger.json | 127 ++++++++++++++++-- docs/swagger.yaml | 81 +++++++++-- internal/base/constant/site_type.go | 18 ++- internal/controller/siteinfo_controller.go | 5 + .../controller_admin/siteinfo_controller.go | 33 ++++- internal/migrations/v30.go | 96 +++++++++++++ internal/router/answer_api_router.go | 4 + internal/schema/siteinfo_schema.go | 58 +++++--- internal/service/siteinfo/siteinfo_service.go | 21 ++- .../siteinfo_common/siteinfo_service.go | 20 ++- 11 files changed, 516 insertions(+), 74 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index 73d85436c..b030c3d3d 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1167,7 +1167,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteInterfaceResp" + "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" } } } @@ -1708,6 +1708,77 @@ const docTemplate = `{ } } }, + "/answer/admin/api/siteinfo/users-settings": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site interface", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site interface", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteUsersSettingsResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site info users settings", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site info users settings", + "parameters": [ + { + "description": "general", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteUsersSettingsReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/theme/options": { "get": { "security": [ @@ -10843,7 +10914,7 @@ const docTemplate = `{ "$ref": "#/definitions/schema.SiteGeneralResp" }, "interface": { - "$ref": "#/definitions/schema.SiteInterfaceResp" + "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { "$ref": "#/definitions/schema.SiteLoginResp" @@ -10872,6 +10943,9 @@ const docTemplate = `{ "theme": { "$ref": "#/definitions/schema.SiteThemeResp" }, + "users_settings": { + "$ref": "#/definitions/schema.SiteUsersSettingsResp" + }, "version": { "type": "string" } @@ -10905,24 +10979,13 @@ const docTemplate = `{ } } }, - "schema.SiteInterfaceResp": { + "schema.SiteInterfaceSettingsResp": { "type": "object", "required": [ - "default_avatar", "language", "time_zone" ], "properties": { - "default_avatar": { - "type": "string", - "enum": [ - "system", - "gravatar" - ] - }, - "gravatar_base_url": { - "type": "string" - }, "language": { "type": "string", "maxLength": 128 @@ -11271,6 +11334,42 @@ const docTemplate = `{ } } }, + "schema.SiteUsersSettingsReq": { + "type": "object", + "required": [ + "default_avatar" + ], + "properties": { + "default_avatar": { + "type": "string", + "enum": [ + "system", + "gravatar" + ] + }, + "gravatar_base_url": { + "type": "string" + } + } + }, + "schema.SiteUsersSettingsResp": { + "type": "object", + "required": [ + "default_avatar" + ], + "properties": { + "default_avatar": { + "type": "string", + "enum": [ + "system", + "gravatar" + ] + }, + "gravatar_base_url": { + "type": "string" + } + } + }, "schema.SiteWriteTag": { "type": "object", "required": [ diff --git a/docs/swagger.json b/docs/swagger.json index 6dbecc50a..879302fa8 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1159,7 +1159,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteInterfaceResp" + "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" } } } @@ -1700,6 +1700,77 @@ } } }, + "/answer/admin/api/siteinfo/users-settings": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site interface", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site interface", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteUsersSettingsResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site info users settings", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site info users settings", + "parameters": [ + { + "description": "general", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteUsersSettingsReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/theme/options": { "get": { "security": [ @@ -10835,7 +10906,7 @@ "$ref": "#/definitions/schema.SiteGeneralResp" }, "interface": { - "$ref": "#/definitions/schema.SiteInterfaceResp" + "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { "$ref": "#/definitions/schema.SiteLoginResp" @@ -10864,6 +10935,9 @@ "theme": { "$ref": "#/definitions/schema.SiteThemeResp" }, + "users_settings": { + "$ref": "#/definitions/schema.SiteUsersSettingsResp" + }, "version": { "type": "string" } @@ -10897,24 +10971,13 @@ } } }, - "schema.SiteInterfaceResp": { + "schema.SiteInterfaceSettingsResp": { "type": "object", "required": [ - "default_avatar", "language", "time_zone" ], "properties": { - "default_avatar": { - "type": "string", - "enum": [ - "system", - "gravatar" - ] - }, - "gravatar_base_url": { - "type": "string" - }, "language": { "type": "string", "maxLength": 128 @@ -11263,6 +11326,42 @@ } } }, + "schema.SiteUsersSettingsReq": { + "type": "object", + "required": [ + "default_avatar" + ], + "properties": { + "default_avatar": { + "type": "string", + "enum": [ + "system", + "gravatar" + ] + }, + "gravatar_base_url": { + "type": "string" + } + } + }, + "schema.SiteUsersSettingsResp": { + "type": "object", + "required": [ + "default_avatar" + ], + "properties": { + "default_avatar": { + "type": "string", + "enum": [ + "system", + "gravatar" + ] + }, + "gravatar_base_url": { + "type": "string" + } + } + }, "schema.SiteWriteTag": { "type": "object", "required": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index f4107cd6b..ce16da75e 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2212,7 +2212,7 @@ definitions: general: $ref: '#/definitions/schema.SiteGeneralResp' interface: - $ref: '#/definitions/schema.SiteInterfaceResp' + $ref: '#/definitions/schema.SiteInterfaceSettingsResp' login: $ref: '#/definitions/schema.SiteLoginResp' revision: @@ -2231,6 +2231,8 @@ definitions: $ref: '#/definitions/schema.SiteUsersResp' theme: $ref: '#/definitions/schema.SiteThemeResp' + users_settings: + $ref: '#/definitions/schema.SiteUsersSettingsResp' version: type: string type: object @@ -2254,15 +2256,8 @@ definitions: - language - time_zone type: object - schema.SiteInterfaceResp: + schema.SiteInterfaceSettingsResp: properties: - default_avatar: - enum: - - system - - gravatar - type: string - gravatar_base_url: - type: string language: maxLength: 128 type: string @@ -2270,7 +2265,6 @@ definitions: maxLength: 128 type: string required: - - default_avatar - language - time_zone type: object @@ -2502,6 +2496,30 @@ definitions: required: - default_avatar type: object + schema.SiteUsersSettingsReq: + properties: + default_avatar: + enum: + - system + - gravatar + type: string + gravatar_base_url: + type: string + required: + - default_avatar + type: object + schema.SiteUsersSettingsResp: + properties: + default_avatar: + enum: + - system + - gravatar + type: string + gravatar_base_url: + type: string + required: + - default_avatar + type: object schema.SiteWriteTag: properties: display_name: @@ -3878,7 +3896,7 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteInterfaceResp' + $ref: '#/definitions/schema.SiteInterfaceSettingsResp' type: object security: - ApiKeyAuth: [] @@ -4193,6 +4211,47 @@ paths: summary: update site info config about users tags: - admin + /answer/admin/api/siteinfo/users-settings: + get: + description: get site interface + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteUsersSettingsResp' + type: object + security: + - ApiKeyAuth: [] + summary: get site interface + tags: + - admin + put: + description: update site info users settings + parameters: + - description: general + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteUsersSettingsReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update site info users settings + tags: + - admin /answer/admin/api/theme/options: get: description: Get theme options diff --git a/internal/base/constant/site_type.go b/internal/base/constant/site_type.go index 6106b190c..9bb4e10af 100644 --- a/internal/base/constant/site_type.go +++ b/internal/base/constant/site_type.go @@ -20,9 +20,11 @@ package constant const ( - SiteTypeGeneral = "general" - SiteTypeInterface = "interface" - SiteTypeBranding = "branding" + SiteTypeGeneral = "general" + // Deprecated: split SiteTypeInterfaceSettings and SiteTypeUsersSettings for better clarity + SiteTypeInterface = "interface" + SiteTypeBranding = "branding" + // Deprecated: use SiteTypeAdvanced, SiteTypeQuestions, and SiteTypeTags instead SiteTypeWrite = "write" SiteTypeLegal = "legal" SiteTypeSeo = "seo" @@ -31,7 +33,11 @@ const ( SiteTypeTheme = "theme" SiteTypePrivileges = "privileges" SiteTypeUsers = "users" - SiteTypeAdvanced = "advanced" - SiteTypeQuestions = "questions" - SiteTypeTags = "tags" + + SiteTypeAdvanced = "advanced" + SiteTypeQuestions = "questions" + SiteTypeTags = "tags" + + SiteTypeUsersSettings = "users_settings" + SiteTypeInterfaceSettings = "interface_settings" ) diff --git a/internal/controller/siteinfo_controller.go b/internal/controller/siteinfo_controller.go index 8035275a6..503bfeb68 100644 --- a/internal/controller/siteinfo_controller.go +++ b/internal/controller/siteinfo_controller.go @@ -60,6 +60,11 @@ func (sc *SiteInfoController) GetSiteInfo(ctx *gin.Context) { log.Error(err) } + resp.UsersSettings, err = sc.siteInfoService.GetSiteUsersSettings(ctx) + if err != nil { + log.Error(err) + } + resp.Branding, err = sc.siteInfoService.GetSiteBranding(ctx) if err != nil { log.Error(err) diff --git a/internal/controller_admin/siteinfo_controller.go b/internal/controller_admin/siteinfo_controller.go index bbab97942..056b01ae2 100644 --- a/internal/controller_admin/siteinfo_controller.go +++ b/internal/controller_admin/siteinfo_controller.go @@ -62,13 +62,26 @@ func (sc *SiteInfoController) GetGeneral(ctx *gin.Context) { // @Security ApiKeyAuth // @Tags admin // @Produce json -// @Success 200 {object} handler.RespBody{data=schema.SiteInterfaceResp} +// @Success 200 {object} handler.RespBody{data=schema.SiteInterfaceSettingsResp} // @Router /answer/admin/api/siteinfo/interface [get] func (sc *SiteInfoController) GetInterface(ctx *gin.Context) { resp, err := sc.siteInfoService.GetSiteInterface(ctx) handler.HandleResponse(ctx, err, resp) } +// GetUsersSettings get site interface +// @Summary get site interface +// @Description get site interface +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=schema.SiteUsersSettingsResp} +// @Router /answer/admin/api/siteinfo/users-settings [get] +func (sc *SiteInfoController) GetUsersSettings(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteUsersSettings(ctx) + handler.HandleResponse(ctx, err, resp) +} + // GetSiteBranding get site interface // @Summary get site interface // @Description get site interface @@ -287,6 +300,24 @@ func (sc *SiteInfoController) UpdateInterface(ctx *gin.Context) { handler.HandleResponse(ctx, err, nil) } +// UpdateUsersSettings update users settings +// @Summary update site info users settings +// @Description update site info users settings +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Param data body schema.SiteUsersSettingsReq true "general" +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/siteinfo/users-settings [put] +func (sc *SiteInfoController) UpdateUsersSettings(ctx *gin.Context) { + req := schema.SiteUsersSettingsReq{} + if handler.BindAndCheck(ctx, &req) { + return + } + err := sc.siteInfoService.SaveSiteUsersSettings(ctx, req) + handler.HandleResponse(ctx, err, nil) +} + // UpdateBranding update site branding // @Summary update site info branding // @Description update site info branding diff --git a/internal/migrations/v30.go b/internal/migrations/v30.go index 5d5d5223f..4d0f11304 100644 --- a/internal/migrations/v30.go +++ b/internal/migrations/v30.go @@ -171,3 +171,99 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { return nil } + +func splitInterfaceMenu(ctx context.Context, x *xorm.Engine) error { + var ( + siteInfo = &entity.SiteInfo{} + siteInfoInterface = &entity.SiteInfo{} + siteInfoUsers = &entity.SiteInfo{} + ) + type SiteInterface struct { + Language string `validate:"required,gt=1,lte=128" form:"language" json:"language"` + TimeZone string `validate:"required,gt=1,lte=128" form:"time_zone" json:"time_zone"` + DefaultAvatar string `validate:"required,oneof=system gravatar" json:"default_avatar"` + GravatarBaseURL string `validate:"omitempty" json:"gravatar_base_url"` + } + + exist, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeInterface}).Get(siteInfo) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + return err + } + if !exist { + return nil + } + oldSiteInterface := &SiteInterface{} + if err := json.Unmarshal([]byte(siteInfo.Content), oldSiteInterface); err != nil { + return err + } + siteUser := &schema.SiteUsersSettingsResp{ + DefaultAvatar: oldSiteInterface.DefaultAvatar, + GravatarBaseURL: oldSiteInterface.GravatarBaseURL, + } + siteInterface := &schema.SiteInterfaceResp{ + Language: oldSiteInterface.Language, + TimeZone: oldSiteInterface.TimeZone, + } + + // save settings + // save user settings + existsUsers, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeUsersSettings}).Get(siteInfoUsers) + if err != nil { + return err + } + userContent, err := json.Marshal(siteUser) + if err != nil { + return err + } + if existsUsers { + _, err = x.Context(ctx).ID(siteInfoUsers.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeUsersSettings, + Content: string(userContent), + Status: 1, + }) + if err != nil { + return err + } + } else { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ + Type: constant.SiteTypeUsersSettings, + Content: string(userContent), + Status: 1, + }) + if err != nil { + return err + } + } + + // save interface settings + existsInterface, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeInterfaceSettings}).Get(siteInfoInterface) + if err != nil { + return err + } + interfaceContent, err := json.Marshal(siteInterface) + if err != nil { + return err + } + if existsInterface { + _, err = x.Context(ctx).ID(siteInfoInterface.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeInterfaceSettings, + Content: string(interfaceContent), + Status: 1, + }) + if err != nil { + return err + } + } else { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ + Type: constant.SiteTypeInterfaceSettings, + Content: string(interfaceContent), + Status: 1, + }) + if err != nil { + return err + } + } + + return nil +} diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go index d717bc9d3..c776b44f0 100644 --- a/internal/router/answer_api_router.go +++ b/internal/router/answer_api_router.go @@ -343,8 +343,12 @@ func (a *AnswerAPIRouter) RegisterAnswerAdminAPIRouter(r *gin.RouterGroup) { // siteinfo r.GET("/siteinfo/general", a.adminSiteInfoController.GetGeneral) r.PUT("/siteinfo/general", a.adminSiteInfoController.UpdateGeneral) + r.GET("/siteinfo/interface", a.adminSiteInfoController.GetInterface) r.PUT("/siteinfo/interface", a.adminSiteInfoController.UpdateInterface) + r.GET("/siteinfo/users-settings", a.adminSiteInfoController.GetUsersSettings) + r.PUT("/siteinfo/users-settings", a.adminSiteInfoController.UpdateUsersSettings) + r.GET("/siteinfo/branding", a.adminSiteInfoController.GetSiteBranding) r.PUT("/siteinfo/branding", a.adminSiteInfoController.UpdateBranding) diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index daf49146c..a060558a9 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -65,6 +65,21 @@ type SiteInterfaceReq struct { GravatarBaseURL string `validate:"omitempty" json:"gravatar_base_url"` } +// SiteInterfaceSettingsReq site interface settings request +type SiteInterfaceSettingsReq struct { + Language string `validate:"required,gt=1,lte=128" json:"language"` + TimeZone string `validate:"required,gt=1,lte=128" json:"time_zone"` +} + +type SiteInterfaceSettingsResp SiteInterfaceSettingsReq + +type SiteUsersSettingsReq struct { + DefaultAvatar string `validate:"required,oneof=system gravatar" json:"default_avatar"` + GravatarBaseURL string `validate:"omitempty" json:"gravatar_base_url"` +} + +type SiteUsersSettingsResp SiteUsersSettingsReq + // SiteBrandingReq site branding request type SiteBrandingReq struct { Logo string `validate:"omitempty,gt=0,lte=512" form:"logo" json:"logo"` @@ -279,27 +294,30 @@ type SiteSeoResp SiteSeoReq // SiteInfoResp get site info response type SiteInfoResp struct { - General *SiteGeneralResp `json:"general"` - Interface *SiteInterfaceResp `json:"interface"` - Branding *SiteBrandingResp `json:"branding"` - Login *SiteLoginResp `json:"login"` - Theme *SiteThemeResp `json:"theme"` - CustomCssHtml *SiteCustomCssHTMLResp `json:"custom_css_html"` - SiteSeo *SiteSeoResp `json:"site_seo"` - SiteUsers *SiteUsersResp `json:"site_users"` - Advanced *SiteAdvancedResp `json:"site_advanced"` - Questions *SiteQuestionsResp `json:"site_questions"` - Tags *SiteTagsResp `json:"site_tags"` - Legal *SiteLegalSimpleResp `json:"site_legal"` - Version string `json:"version"` - Revision string `json:"revision"` -} + General *SiteGeneralResp `json:"general"` + Interface *SiteInterfaceSettingsResp `json:"interface"` + UsersSettings *SiteUsersSettingsResp `json:"users_settings"` + Branding *SiteBrandingResp `json:"branding"` + Login *SiteLoginResp `json:"login"` + Theme *SiteThemeResp `json:"theme"` + CustomCssHtml *SiteCustomCssHTMLResp `json:"custom_css_html"` + SiteSeo *SiteSeoResp `json:"site_seo"` + SiteUsers *SiteUsersResp `json:"site_users"` + Advanced *SiteAdvancedResp `json:"site_advanced"` + Questions *SiteQuestionsResp `json:"site_questions"` + Tags *SiteTagsResp `json:"site_tags"` + Legal *SiteLegalSimpleResp `json:"site_legal"` + Version string `json:"version"` + Revision string `json:"revision"` +} + +// todo: 检查模板使用 type TemplateSiteInfoResp struct { - General *SiteGeneralResp `json:"general"` - Interface *SiteInterfaceResp `json:"interface"` - Branding *SiteBrandingResp `json:"branding"` - SiteSeo *SiteSeoResp `json:"site_seo"` - CustomCssHtml *SiteCustomCssHTMLResp `json:"custom_css_html"` + General *SiteGeneralResp `json:"general"` + Interface *SiteInterfaceSettingsResp `json:"interface"` + Branding *SiteBrandingResp `json:"branding"` + SiteSeo *SiteSeoResp `json:"site_seo"` + CustomCssHtml *SiteCustomCssHTMLResp `json:"custom_css_html"` Title string Year string Canonical string diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index b633ed421..956511cee 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -89,10 +89,15 @@ func (s *SiteInfoService) GetSiteGeneral(ctx context.Context) (resp *schema.Site } // GetSiteInterface get site info interface -func (s *SiteInfoService) GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceResp, err error) { +func (s *SiteInfoService) GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceSettingsResp, err error) { return s.siteInfoCommonService.GetSiteInterface(ctx) } +// GetSiteUsersSettings get site info users settings +func (s *SiteInfoService) GetSiteUsersSettings(ctx context.Context) (resp *schema.SiteUsersSettingsResp, err error) { + return s.siteInfoCommonService.GetSiteUsersSettings(ctx) +} + // GetSiteBranding get site info branding func (s *SiteInfoService) GetSiteBranding(ctx context.Context) (resp *schema.SiteBrandingResp, err error) { return s.siteInfoCommonService.GetSiteBranding(ctx) @@ -172,10 +177,20 @@ func (s *SiteInfoService) SaveSiteInterface(ctx context.Context, req schema.Site content, _ := json.Marshal(req) data := entity.SiteInfo{ - Type: constant.SiteTypeInterface, + Type: constant.SiteTypeInterfaceSettings, + Content: string(content), + } + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeInterfaceSettings, &data) +} + +// SaveSiteUsersSettings save site users settings +func (s *SiteInfoService) SaveSiteUsersSettings(ctx context.Context, req schema.SiteUsersSettingsReq) (err error) { + content, _ := json.Marshal(req) + data := entity.SiteInfo{ + Type: constant.SiteTypeInterfaceSettings, Content: string(content), } - return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeInterface, &data) + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeUsersSettings, &data) } // SaveSiteBranding save site branding information diff --git a/internal/service/siteinfo_common/siteinfo_service.go b/internal/service/siteinfo_common/siteinfo_service.go index 87bc7ee15..dde0114bd 100644 --- a/internal/service/siteinfo_common/siteinfo_service.go +++ b/internal/service/siteinfo_common/siteinfo_service.go @@ -45,7 +45,8 @@ type siteInfoCommonService struct { type SiteInfoCommonService interface { GetSiteGeneral(ctx context.Context) (resp *schema.SiteGeneralResp, err error) - GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceResp, err error) + GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceSettingsResp, err error) + GetSiteUsersSettings(ctx context.Context) (resp *schema.SiteUsersSettingsResp, err error) GetSiteBranding(ctx context.Context) (resp *schema.SiteBrandingResp, err error) GetSiteUsers(ctx context.Context) (resp *schema.SiteUsersResp, err error) FormatAvatar(ctx context.Context, originalAvatarData, email string, userStatus int) *schema.AvatarInfo @@ -81,9 +82,18 @@ func (s *siteInfoCommonService) GetSiteGeneral(ctx context.Context) (resp *schem } // GetSiteInterface get site info interface -func (s *siteInfoCommonService) GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceResp, err error) { - resp = &schema.SiteInterfaceResp{} - if err = s.GetSiteInfoByType(ctx, constant.SiteTypeInterface, resp); err != nil { +func (s *siteInfoCommonService) GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceSettingsResp, err error) { + resp = &schema.SiteInterfaceSettingsResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeInterfaceSettings, resp); err != nil { + return nil, err + } + return resp, nil +} + +// GetSiteUsersSettings get site info interface +func (s *siteInfoCommonService) GetSiteUsersSettings(ctx context.Context) (resp *schema.SiteUsersSettingsResp, err error) { + resp = &schema.SiteUsersSettingsResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeUsersSettings, resp); err != nil { return nil, err } return resp, nil @@ -126,7 +136,7 @@ func (s *siteInfoCommonService) FormatListAvatar(ctx context.Context, userList [ func (s *siteInfoCommonService) getAvatarDefaultConfig(ctx context.Context) (string, string) { gravatarBaseURL, defaultAvatar := constant.DefaultGravatarBaseURL, constant.DefaultAvatar - usersConfig, err := s.GetSiteInterface(ctx) + usersConfig, err := s.GetSiteUsersSettings(ctx) if err != nil { log.Error(err) } From f0636d43693897de38d61d221a972c7d03f187a6 Mon Sep 17 00:00:00 2001 From: kumfo Date: Wed, 21 Jan 2026 16:06:17 +0800 Subject: [PATCH 59/92] feat(siteinfo): refactor site legal and security settings to use new policies and security endpoints --- docs/docs.go | 250 ++++++++++++------ docs/swagger.json | 250 ++++++++++++------ docs/swagger.yaml | 171 +++++++----- internal/base/constant/site_type.go | 6 +- internal/base/middleware/auth.go | 4 +- internal/base/middleware/visit_img_auth.go | 4 +- internal/controller/siteinfo_controller.go | 4 +- internal/controller/template_controller.go | 2 +- .../controller_admin/siteinfo_controller.go | 61 +++-- internal/migrations/init.go | 85 ++++-- internal/migrations/v30.go | 217 +++++++++++---- internal/router/answer_api_router.go | 7 +- internal/schema/siteinfo_schema.go | 21 +- .../service/dashboard/dashboard_service.go | 17 +- internal/service/mock/siteinfo_repo_mock.go | 62 +++-- internal/service/siteinfo/siteinfo_service.go | 34 ++- .../siteinfo_common/siteinfo_service.go | 22 +- 17 files changed, 855 insertions(+), 362 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index b030c3d3d..a70cdab09 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1211,21 +1211,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/legal": { + "/answer/admin/api/siteinfo/login": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "Set the legal information for the site", + "description": "get site info login config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "Set the legal information for the site", + "summary": "get site info login config", "responses": { "200": { "description": "OK", @@ -1238,7 +1238,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteLegalResp" + "$ref": "#/definitions/schema.SiteLoginResp" } } } @@ -1253,22 +1253,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site legal info", + "description": "update site login", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site legal info", + "summary": "update site login", "parameters": [ { - "description": "write info", + "description": "login info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteLegalReq" + "$ref": "#/definitions/schema.SiteLoginReq" } } ], @@ -1282,21 +1282,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/login": { + "/answer/admin/api/siteinfo/polices": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site info login config", + "description": "Get the policies information for the site", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site info login config", + "summary": "Get the policies information for the site", "responses": { "200": { "description": "OK", @@ -1309,7 +1309,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteLoginResp" + "$ref": "#/definitions/schema.SitePoliciesResp" } } } @@ -1324,22 +1324,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site login", + "description": "update site policies configuration", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site login", + "summary": "update site policies configuration", "parameters": [ { - "description": "login info", + "description": "write info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteLoginReq" + "$ref": "#/definitions/schema.SitePoliciesReq" } } ], @@ -1424,6 +1424,77 @@ const docTemplate = `{ } } }, + "/answer/admin/api/siteinfo/security": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Get the security information for the site", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Get the security information for the site", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteSecurityResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site security configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site security configuration", + "parameters": [ + { + "description": "write info", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteSecurityReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/seo": { "get": { "security": [ @@ -10843,9 +10914,6 @@ const docTemplate = `{ "site_url" ], "properties": { - "check_update": { - "type": "boolean" - }, "contact_email": { "type": "string", "maxLength": 512 @@ -10876,9 +10944,6 @@ const docTemplate = `{ "site_url" ], "properties": { - "check_update": { - "type": "boolean" - }, "contact_email": { "type": "string", "maxLength": 512 @@ -10917,7 +10982,12 @@ const docTemplate = `{ "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { - "$ref": "#/definitions/schema.SiteLoginResp" + "description": "todo", + "allOf": [ + { + "$ref": "#/definitions/schema.SiteLoginResp" + } + ] }, "revision": { "type": "string" @@ -10996,60 +11066,6 @@ const docTemplate = `{ } } }, - "schema.SiteLegalReq": { - "type": "object", - "required": [ - "external_content_display" - ], - "properties": { - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "privacy_policy_original_text": { - "type": "string" - }, - "privacy_policy_parsed_text": { - "type": "string" - }, - "terms_of_service_original_text": { - "type": "string" - }, - "terms_of_service_parsed_text": { - "type": "string" - } - } - }, - "schema.SiteLegalResp": { - "type": "object", - "required": [ - "external_content_display" - ], - "properties": { - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "privacy_policy_original_text": { - "type": "string" - }, - "privacy_policy_parsed_text": { - "type": "string" - }, - "terms_of_service_original_text": { - "type": "string" - }, - "terms_of_service_parsed_text": { - "type": "string" - } - } - }, "schema.SiteLegalSimpleResp": { "type": "object", "required": [ @@ -11082,9 +11098,6 @@ const docTemplate = `{ }, "allow_password_login": { "type": "boolean" - }, - "login_required": { - "type": "boolean" } } }, @@ -11105,9 +11118,40 @@ const docTemplate = `{ }, "allow_password_login": { "type": "boolean" + } + } + }, + "schema.SitePoliciesReq": { + "type": "object", + "properties": { + "privacy_policy_original_text": { + "type": "string" }, - "login_required": { - "type": "boolean" + "privacy_policy_parsed_text": { + "type": "string" + }, + "terms_of_service_original_text": { + "type": "string" + }, + "terms_of_service_parsed_text": { + "type": "string" + } + } + }, + "schema.SitePoliciesResp": { + "type": "object", + "properties": { + "privacy_policy_original_text": { + "type": "string" + }, + "privacy_policy_parsed_text": { + "type": "string" + }, + "terms_of_service_original_text": { + "type": "string" + }, + "terms_of_service_parsed_text": { + "type": "string" } } }, @@ -11137,6 +11181,48 @@ const docTemplate = `{ } } }, + "schema.SiteSecurityReq": { + "type": "object", + "required": [ + "external_content_display" + ], + "properties": { + "check_update": { + "type": "boolean" + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "login_required": { + "type": "boolean" + } + } + }, + "schema.SiteSecurityResp": { + "type": "object", + "required": [ + "external_content_display" + ], + "properties": { + "check_update": { + "type": "boolean" + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "login_required": { + "type": "boolean" + } + } + }, "schema.SiteSeoReq": { "type": "object", "required": [ diff --git a/docs/swagger.json b/docs/swagger.json index 879302fa8..05e3302c6 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1203,21 +1203,21 @@ } } }, - "/answer/admin/api/siteinfo/legal": { + "/answer/admin/api/siteinfo/login": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "Set the legal information for the site", + "description": "get site info login config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "Set the legal information for the site", + "summary": "get site info login config", "responses": { "200": { "description": "OK", @@ -1230,7 +1230,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteLegalResp" + "$ref": "#/definitions/schema.SiteLoginResp" } } } @@ -1245,22 +1245,22 @@ "ApiKeyAuth": [] } ], - "description": "update site legal info", + "description": "update site login", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site legal info", + "summary": "update site login", "parameters": [ { - "description": "write info", + "description": "login info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteLegalReq" + "$ref": "#/definitions/schema.SiteLoginReq" } } ], @@ -1274,21 +1274,21 @@ } } }, - "/answer/admin/api/siteinfo/login": { + "/answer/admin/api/siteinfo/polices": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site info login config", + "description": "Get the policies information for the site", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site info login config", + "summary": "Get the policies information for the site", "responses": { "200": { "description": "OK", @@ -1301,7 +1301,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteLoginResp" + "$ref": "#/definitions/schema.SitePoliciesResp" } } } @@ -1316,22 +1316,22 @@ "ApiKeyAuth": [] } ], - "description": "update site login", + "description": "update site policies configuration", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site login", + "summary": "update site policies configuration", "parameters": [ { - "description": "login info", + "description": "write info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteLoginReq" + "$ref": "#/definitions/schema.SitePoliciesReq" } } ], @@ -1416,6 +1416,77 @@ } } }, + "/answer/admin/api/siteinfo/security": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Get the security information for the site", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Get the security information for the site", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteSecurityResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site security configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site security configuration", + "parameters": [ + { + "description": "write info", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteSecurityReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/seo": { "get": { "security": [ @@ -10835,9 +10906,6 @@ "site_url" ], "properties": { - "check_update": { - "type": "boolean" - }, "contact_email": { "type": "string", "maxLength": 512 @@ -10868,9 +10936,6 @@ "site_url" ], "properties": { - "check_update": { - "type": "boolean" - }, "contact_email": { "type": "string", "maxLength": 512 @@ -10909,7 +10974,12 @@ "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { - "$ref": "#/definitions/schema.SiteLoginResp" + "description": "todo", + "allOf": [ + { + "$ref": "#/definitions/schema.SiteLoginResp" + } + ] }, "revision": { "type": "string" @@ -10988,60 +11058,6 @@ } } }, - "schema.SiteLegalReq": { - "type": "object", - "required": [ - "external_content_display" - ], - "properties": { - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "privacy_policy_original_text": { - "type": "string" - }, - "privacy_policy_parsed_text": { - "type": "string" - }, - "terms_of_service_original_text": { - "type": "string" - }, - "terms_of_service_parsed_text": { - "type": "string" - } - } - }, - "schema.SiteLegalResp": { - "type": "object", - "required": [ - "external_content_display" - ], - "properties": { - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "privacy_policy_original_text": { - "type": "string" - }, - "privacy_policy_parsed_text": { - "type": "string" - }, - "terms_of_service_original_text": { - "type": "string" - }, - "terms_of_service_parsed_text": { - "type": "string" - } - } - }, "schema.SiteLegalSimpleResp": { "type": "object", "required": [ @@ -11074,9 +11090,6 @@ }, "allow_password_login": { "type": "boolean" - }, - "login_required": { - "type": "boolean" } } }, @@ -11097,9 +11110,40 @@ }, "allow_password_login": { "type": "boolean" + } + } + }, + "schema.SitePoliciesReq": { + "type": "object", + "properties": { + "privacy_policy_original_text": { + "type": "string" }, - "login_required": { - "type": "boolean" + "privacy_policy_parsed_text": { + "type": "string" + }, + "terms_of_service_original_text": { + "type": "string" + }, + "terms_of_service_parsed_text": { + "type": "string" + } + } + }, + "schema.SitePoliciesResp": { + "type": "object", + "properties": { + "privacy_policy_original_text": { + "type": "string" + }, + "privacy_policy_parsed_text": { + "type": "string" + }, + "terms_of_service_original_text": { + "type": "string" + }, + "terms_of_service_parsed_text": { + "type": "string" } } }, @@ -11129,6 +11173,48 @@ } } }, + "schema.SiteSecurityReq": { + "type": "object", + "required": [ + "external_content_display" + ], + "properties": { + "check_update": { + "type": "boolean" + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "login_required": { + "type": "boolean" + } + } + }, + "schema.SiteSecurityResp": { + "type": "object", + "required": [ + "external_content_display" + ], + "properties": { + "check_update": { + "type": "boolean" + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "login_required": { + "type": "boolean" + } + } + }, "schema.SiteSeoReq": { "type": "object", "required": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index ce16da75e..85a05baf0 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2157,8 +2157,6 @@ definitions: type: object schema.SiteGeneralReq: properties: - check_update: - type: boolean contact_email: maxLength: 512 type: string @@ -2181,8 +2179,6 @@ definitions: type: object schema.SiteGeneralResp: properties: - check_update: - type: boolean contact_email: maxLength: 512 type: string @@ -2214,7 +2210,9 @@ definitions: interface: $ref: '#/definitions/schema.SiteInterfaceSettingsResp' login: - $ref: '#/definitions/schema.SiteLoginResp' + allOf: + - $ref: '#/definitions/schema.SiteLoginResp' + description: todo revision: type: string site_advanced: @@ -2268,42 +2266,6 @@ definitions: - language - time_zone type: object - schema.SiteLegalReq: - properties: - external_content_display: - enum: - - always_display - - ask_before_display - type: string - privacy_policy_original_text: - type: string - privacy_policy_parsed_text: - type: string - terms_of_service_original_text: - type: string - terms_of_service_parsed_text: - type: string - required: - - external_content_display - type: object - schema.SiteLegalResp: - properties: - external_content_display: - enum: - - always_display - - ask_before_display - type: string - privacy_policy_original_text: - type: string - privacy_policy_parsed_text: - type: string - terms_of_service_original_text: - type: string - terms_of_service_parsed_text: - type: string - required: - - external_content_display - type: object schema.SiteLegalSimpleResp: properties: external_content_display: @@ -2326,8 +2288,6 @@ definitions: type: boolean allow_password_login: type: boolean - login_required: - type: boolean type: object schema.SiteLoginResp: properties: @@ -2341,8 +2301,28 @@ definitions: type: boolean allow_password_login: type: boolean - login_required: - type: boolean + type: object + schema.SitePoliciesReq: + properties: + privacy_policy_original_text: + type: string + privacy_policy_parsed_text: + type: string + terms_of_service_original_text: + type: string + terms_of_service_parsed_text: + type: string + type: object + schema.SitePoliciesResp: + properties: + privacy_policy_original_text: + type: string + privacy_policy_parsed_text: + type: string + terms_of_service_original_text: + type: string + terms_of_service_parsed_text: + type: string type: object schema.SiteQuestionsReq: properties: @@ -2362,6 +2342,34 @@ definitions: restrict_answer: type: boolean type: object + schema.SiteSecurityReq: + properties: + check_update: + type: boolean + external_content_display: + enum: + - always_display + - ask_before_display + type: string + login_required: + type: boolean + required: + - external_content_display + type: object + schema.SiteSecurityResp: + properties: + check_update: + type: boolean + external_content_display: + enum: + - always_display + - ask_before_display + type: string + login_required: + type: boolean + required: + - external_content_display + type: object schema.SiteSeoReq: properties: permalink: @@ -3924,9 +3932,9 @@ paths: summary: update site info interface tags: - admin - /answer/admin/api/siteinfo/legal: + /answer/admin/api/siteinfo/login: get: - description: Set the legal information for the site + description: get site info login config produces: - application/json responses: @@ -3937,22 +3945,22 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteLegalResp' + $ref: '#/definitions/schema.SiteLoginResp' type: object security: - ApiKeyAuth: [] - summary: Set the legal information for the site + summary: get site info login config tags: - admin put: - description: update site legal info + description: update site login parameters: - - description: write info + - description: login info in: body name: data required: true schema: - $ref: '#/definitions/schema.SiteLegalReq' + $ref: '#/definitions/schema.SiteLoginReq' produces: - application/json responses: @@ -3962,12 +3970,12 @@ paths: $ref: '#/definitions/handler.RespBody' security: - ApiKeyAuth: [] - summary: update site legal info + summary: update site login tags: - admin - /answer/admin/api/siteinfo/login: + /answer/admin/api/siteinfo/polices: get: - description: get site info login config + description: Get the policies information for the site produces: - application/json responses: @@ -3978,22 +3986,22 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteLoginResp' + $ref: '#/definitions/schema.SitePoliciesResp' type: object security: - ApiKeyAuth: [] - summary: get site info login config + summary: Get the policies information for the site tags: - admin put: - description: update site login + description: update site policies configuration parameters: - - description: login info + - description: write info in: body name: data required: true schema: - $ref: '#/definitions/schema.SiteLoginReq' + $ref: '#/definitions/schema.SitePoliciesReq' produces: - application/json responses: @@ -4003,7 +4011,7 @@ paths: $ref: '#/definitions/handler.RespBody' security: - ApiKeyAuth: [] - summary: update site login + summary: update site policies configuration tags: - admin /answer/admin/api/siteinfo/question: @@ -4047,6 +4055,47 @@ paths: summary: update site question settings tags: - admin + /answer/admin/api/siteinfo/security: + get: + description: Get the security information for the site + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteSecurityResp' + type: object + security: + - ApiKeyAuth: [] + summary: Get the security information for the site + tags: + - admin + put: + description: update site security configuration + parameters: + - description: write info + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteSecurityReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update site security configuration + tags: + - admin /answer/admin/api/siteinfo/seo: get: description: get site seo information diff --git a/internal/base/constant/site_type.go b/internal/base/constant/site_type.go index 9bb4e10af..44cd0abd7 100644 --- a/internal/base/constant/site_type.go +++ b/internal/base/constant/site_type.go @@ -25,7 +25,8 @@ const ( SiteTypeInterface = "interface" SiteTypeBranding = "branding" // Deprecated: use SiteTypeAdvanced, SiteTypeQuestions, and SiteTypeTags instead - SiteTypeWrite = "write" + SiteTypeWrite = "write" + // Deprecated: use SiteTypePolicies and SiteTypeSecurity instead SiteTypeLegal = "legal" SiteTypeSeo = "seo" SiteTypeLogin = "login" @@ -40,4 +41,7 @@ const ( SiteTypeUsersSettings = "users_settings" SiteTypeInterfaceSettings = "interface_settings" + + SiteTypePolicies = "policies" + SiteTypeSecurity = "security" ) diff --git a/internal/base/middleware/auth.go b/internal/base/middleware/auth.go index f21837b60..57bbaae21 100644 --- a/internal/base/middleware/auth.go +++ b/internal/base/middleware/auth.go @@ -80,7 +80,7 @@ func (am *AuthUserMiddleware) Auth() gin.HandlerFunc { func (am *AuthUserMiddleware) EjectUserBySiteInfo() gin.HandlerFunc { return func(ctx *gin.Context) { mustLogin := false - siteInfo, _ := am.siteInfoCommonService.GetSiteLogin(ctx) + siteInfo, _ := am.siteInfoCommonService.GetSiteSecurity(ctx) if siteInfo != nil { mustLogin = siteInfo.LoginRequired } @@ -197,7 +197,7 @@ func (am *AuthUserMiddleware) AdminAuth() gin.HandlerFunc { func (am *AuthUserMiddleware) CheckPrivateMode() gin.HandlerFunc { return func(ctx *gin.Context) { - resp, err := am.siteInfoCommonService.GetSiteLogin(ctx) + resp, err := am.siteInfoCommonService.GetSiteSecurity(ctx) if err != nil { ShowIndexPage(ctx) ctx.Abort() diff --git a/internal/base/middleware/visit_img_auth.go b/internal/base/middleware/visit_img_auth.go index 33b62172f..bfd157a92 100644 --- a/internal/base/middleware/visit_img_auth.go +++ b/internal/base/middleware/visit_img_auth.go @@ -41,11 +41,11 @@ func (am *AuthUserMiddleware) VisitAuth() gin.HandlerFunc { return } - siteLogin, err := am.siteInfoCommonService.GetSiteLogin(ctx) + siteSecurity, err := am.siteInfoCommonService.GetSiteSecurity(ctx) if err != nil { return } - if !siteLogin.LoginRequired { + if !siteSecurity.LoginRequired { ctx.Next() return } diff --git a/internal/controller/siteinfo_controller.go b/internal/controller/siteinfo_controller.go index 503bfeb68..64aa02ce7 100644 --- a/internal/controller/siteinfo_controller.go +++ b/internal/controller/siteinfo_controller.go @@ -104,7 +104,7 @@ func (sc *SiteInfoController) GetSiteInfo(ctx *gin.Context) { if err != nil { log.Error(err) } - if legal, err := sc.siteInfoService.GetSiteLegal(ctx); err == nil { + if legal, err := sc.siteInfoService.GetSiteSecurity(ctx); err == nil { resp.Legal = &schema.SiteLegalSimpleResp{ExternalContentDisplay: legal.ExternalContentDisplay} } @@ -124,7 +124,7 @@ func (sc *SiteInfoController) GetSiteLegalInfo(ctx *gin.Context) { if handler.BindAndCheck(ctx, req) { return } - siteLegal, err := sc.siteInfoService.GetSiteLegal(ctx) + siteLegal, err := sc.siteInfoService.GetSitePolicies(ctx) if err != nil { handler.HandleResponse(ctx, err, nil) return diff --git a/internal/controller/template_controller.go b/internal/controller/template_controller.go index e6b94f4f2..31cc5152a 100644 --- a/internal/controller/template_controller.go +++ b/internal/controller/template_controller.go @@ -656,7 +656,7 @@ func (tc *TemplateController) SitemapPage(ctx *gin.Context) { } func (tc *TemplateController) checkPrivateMode(ctx *gin.Context) bool { - resp, err := tc.siteInfoService.GetSiteLogin(ctx) + resp, err := tc.siteInfoService.GetSiteSecurity(ctx) if err != nil { log.Error(err) return false diff --git a/internal/controller_admin/siteinfo_controller.go b/internal/controller_admin/siteinfo_controller.go index 056b01ae2..339d2caa2 100644 --- a/internal/controller_admin/siteinfo_controller.go +++ b/internal/controller_admin/siteinfo_controller.go @@ -134,16 +134,29 @@ func (sc *SiteInfoController) GetSiteAdvanced(ctx *gin.Context) { handler.HandleResponse(ctx, err, resp) } -// GetSiteLegal Set the legal information for the site -// @Summary Set the legal information for the site -// @Description Set the legal information for the site +// GetSitePolicies Get the policies information for the site +// @Summary Get the policies information for the site +// @Description Get the policies information for the site // @Security ApiKeyAuth // @Tags admin // @Produce json -// @Success 200 {object} handler.RespBody{data=schema.SiteLegalResp} -// @Router /answer/admin/api/siteinfo/legal [get] -func (sc *SiteInfoController) GetSiteLegal(ctx *gin.Context) { - resp, err := sc.siteInfoService.GetSiteLegal(ctx) +// @Success 200 {object} handler.RespBody{data=schema.SitePoliciesResp} +// @Router /answer/admin/api/siteinfo/polices [get] +func (sc *SiteInfoController) GetSitePolicies(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSitePolicies(ctx) + handler.HandleResponse(ctx, err, resp) +} + +// GetSiteSecurity Get the security information for the site +// @Summary Get the security information for the site +// @Description Get the security information for the site +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=schema.SiteSecurityResp} +// @Router /answer/admin/api/siteinfo/security [get] +func (sc *SiteInfoController) GetSiteSecurity(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteSecurity(ctx) handler.HandleResponse(ctx, err, resp) } @@ -403,21 +416,39 @@ func (sc *SiteInfoController) UpdateSiteAdvanced(ctx *gin.Context) { handler.HandleResponse(ctx, err, resp) } -// UpdateSiteLegal update site legal info -// @Summary update site legal info -// @Description update site legal info +// UpdateSitePolices update site policies configuration +// @Summary update site policies configuration +// @Description update site policies configuration +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Param data body schema.SitePoliciesReq true "write info" +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/siteinfo/polices [put] +func (sc *SiteInfoController) UpdateSitePolices(ctx *gin.Context) { + req := &schema.SitePoliciesReq{} + if handler.BindAndCheck(ctx, req) { + return + } + err := sc.siteInfoService.SaveSitePolicies(ctx, req) + handler.HandleResponse(ctx, err, nil) +} + +// UpdateSiteSecurity update site security configuration +// @Summary update site security configuration +// @Description update site security configuration // @Security ApiKeyAuth // @Tags admin // @Produce json -// @Param data body schema.SiteLegalReq true "write info" +// @Param data body schema.SiteSecurityReq true "write info" // @Success 200 {object} handler.RespBody{} -// @Router /answer/admin/api/siteinfo/legal [put] -func (sc *SiteInfoController) UpdateSiteLegal(ctx *gin.Context) { - req := &schema.SiteLegalReq{} +// @Router /answer/admin/api/siteinfo/security [put] +func (sc *SiteInfoController) UpdateSiteSecurity(ctx *gin.Context) { + req := &schema.SiteSecurityReq{} if handler.BindAndCheck(ctx, req) { return } - err := sc.siteInfoService.SaveSiteLegal(ctx, req) + err := sc.siteInfoService.SaveSiteSecurity(ctx, req) handler.HandleResponse(ctx, err, nil) } diff --git a/internal/migrations/init.go b/internal/migrations/init.go index 8a72794fe..97b32a3c8 100644 --- a/internal/migrations/init.go +++ b/internal/migrations/init.go @@ -74,14 +74,17 @@ func (m *Mentor) InitDB() error { m.do("init role power rel", m.initRolePowerRel) m.do("init admin user role rel", m.initAdminUserRoleRel) m.do("init site info interface", m.initSiteInfoInterface) + m.do("init site info users settings", m.initSiteInfoUsersSettings) m.do("init site info general config", m.initSiteInfoGeneralData) m.do("init site info login config", m.initSiteInfoLoginConfig) m.do("init site info theme config", m.initSiteInfoThemeConfig) m.do("init site info seo config", m.initSiteInfoSEOConfig) m.do("init site info user config", m.initSiteInfoUsersConfig) m.do("init site info privilege rank", m.initSiteInfoPrivilegeRank) - m.do("init site info write", m.initSiteInfoWrite) - m.do("init site info legal", m.initSiteInfoLegalConfig) + m.do("init site info write", m.initSiteInfoAdvanced) + m.do("init site info write", m.initSiteInfoQuestions) + m.do("init site info write", m.initSiteInfoTags) + m.do("init site info security", m.initSiteInfoSecurityConfig) m.do("init default content", m.initDefaultContent) m.do("init default badges", m.initDefaultBadges) return m.err @@ -181,19 +184,30 @@ func (m *Mentor) initSiteInfoInterface() { } interfaceData := map[string]string{ - "language": m.userData.Language, - "time_zone": localTimezone, - "default_avatar": "gravatar", - "gravatar_base_url": "https://www.gravatar.com/avatar/", + "language": m.userData.Language, + "time_zone": localTimezone, } interfaceDataBytes, _ := json.Marshal(interfaceData) _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ - Type: "interface", + Type: "interface_settings", Content: string(interfaceDataBytes), Status: 1, }) } +func (m *Mentor) initSiteInfoUsersSettings() { + usersSettings := map[string]any{ + "default_avatar": "gravatar", + "gravatar_base_url": "https://www.gravatar.com/avatar/", + } + usersSettingsDataBytes, _ := json.Marshal(usersSettings) + _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ + Type: "users_settings", + Content: string(usersSettingsDataBytes), + Status: 1, + }) +} + func (m *Mentor) initSiteInfoGeneralData() { generalData := map[string]string{ "name": m.userData.SiteName, @@ -213,7 +227,6 @@ func (m *Mentor) initSiteInfoLoginConfig() { "allow_new_registrations": true, "allow_email_registrations": true, "allow_password_login": true, - "login_required": m.userData.LoginRequired, } loginConfigDataBytes, _ := json.Marshal(loginConfig) _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ @@ -223,14 +236,16 @@ func (m *Mentor) initSiteInfoLoginConfig() { }) } -func (m *Mentor) initSiteInfoLegalConfig() { - legalConfig := map[string]any{ +func (m *Mentor) initSiteInfoSecurityConfig() { + securityConfig := map[string]any{ + "login_required": m.userData.LoginRequired, "external_content_display": m.userData.ExternalContentDisplay, + "check_update": true, } - legalConfigDataBytes, _ := json.Marshal(legalConfig) + securityConfigDataBytes, _ := json.Marshal(securityConfig) _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ - Type: "legal", - Content: string(legalConfigDataBytes), + Type: "security", + Content: string(securityConfigDataBytes), Status: 1, }) } @@ -288,24 +303,46 @@ func (m *Mentor) initSiteInfoPrivilegeRank() { }) } -func (m *Mentor) initSiteInfoWrite() { - writeData := map[string]any{ - "min_content": 6, - "restrict_answer": true, - "min_tags": 1, - "required_tag": false, - "recommend_tags": []string{}, - "reserved_tags": []string{}, +func (m *Mentor) initSiteInfoAdvanced() { + advancedData := map[string]any{ "max_image_size": 4, "max_attachment_size": 8, "max_image_megapixel": 40, "authorized_image_extensions": []string{"jpg", "jpeg", "png", "gif", "webp"}, "authorized_attachment_extensions": []string{}, } - writeDataBytes, _ := json.Marshal(writeData) + advancedDataBytes, _ := json.Marshal(advancedData) + _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ + Type: "advanced", + Content: string(advancedDataBytes), + Status: 1, + }) +} + +func (m *Mentor) initSiteInfoQuestions() { + questionsData := map[string]any{ + "min_tags": 1, + "min_content": 6, + "restrict_answer": true, + } + questionsDataBytes, _ := json.Marshal(questionsData) + _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ + Type: "questions", + Content: string(questionsDataBytes), + Status: 1, + }) +} + +func (m *Mentor) initSiteInfoTags() { + tagsData := map[string]any{ + "required_tag": false, + "recommend_tags": []string{}, + "reserved_tags": []string{}, + } + tagsDataBytes, _ := json.Marshal(tagsData) _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ - Type: "write", - Content: string(writeDataBytes), + Type: "tags", + Content: string(tagsDataBytes), Status: 1, }) } diff --git a/internal/migrations/v30.go b/internal/migrations/v30.go index 4d0f11304..c73f501d5 100644 --- a/internal/migrations/v30.go +++ b/internal/migrations/v30.go @@ -37,6 +37,16 @@ func updateAdminMenuSettings(ctx context.Context, x *xorm.Engine) (err error) { if err != nil { return } + + err = splitInterfaceMenu(ctx, x) + if err != nil { + return + } + + err = splitLegalMenu(ctx, x) + if err != nil { + return + } return } @@ -91,16 +101,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { if err != nil { return err } - if existsAdvanced { - _, err = x.Context(ctx).ID(siteInfoAdvanced.ID).Update(&entity.SiteInfo{ - Type: constant.SiteTypeAdvanced, - Content: string(advancedContent), - Status: 1, - }) - if err != nil { - return err - } - } else { + if !existsAdvanced { _, err = x.Context(ctx).Insert(&entity.SiteInfo{ Type: constant.SiteTypeAdvanced, Content: string(advancedContent), @@ -120,16 +121,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { if err != nil { return err } - if existsQuestions { - _, err = x.Context(ctx).ID(siteInfoQuestions.ID).Update(&entity.SiteInfo{ - Type: constant.SiteTypeQuestions, - Content: string(questionsContent), - Status: 1, - }) - if err != nil { - return err - } - } else { + if !existsQuestions { _, err = x.Context(ctx).Insert(&entity.SiteInfo{ Type: constant.SiteTypeQuestions, Content: string(questionsContent), @@ -149,16 +141,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { if err != nil { return err } - if existsTags { - _, err = x.Context(ctx).ID(siteInfoTags.ID).Update(&entity.SiteInfo{ - Type: constant.SiteTypeTags, - Content: string(tagsContent), - Status: 1, - }) - if err != nil { - return err - } - } else { + if !existsTags { _, err = x.Context(ctx).Insert(&entity.SiteInfo{ Type: constant.SiteTypeTags, Content: string(tagsContent), @@ -172,6 +155,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { return nil } +// splitInterfaceMenu splits the site interface settings into interface and user settings func splitInterfaceMenu(ctx context.Context, x *xorm.Engine) error { var ( siteInfo = &entity.SiteInfo{} @@ -216,16 +200,7 @@ func splitInterfaceMenu(ctx context.Context, x *xorm.Engine) error { if err != nil { return err } - if existsUsers { - _, err = x.Context(ctx).ID(siteInfoUsers.ID).Update(&entity.SiteInfo{ - Type: constant.SiteTypeUsersSettings, - Content: string(userContent), - Status: 1, - }) - if err != nil { - return err - } - } else { + if !existsUsers { _, err = x.Context(ctx).Insert(&entity.SiteInfo{ Type: constant.SiteTypeUsersSettings, Content: string(userContent), @@ -245,8 +220,8 @@ func splitInterfaceMenu(ctx context.Context, x *xorm.Engine) error { if err != nil { return err } - if existsInterface { - _, err = x.Context(ctx).ID(siteInfoInterface.ID).Update(&entity.SiteInfo{ + if !existsInterface { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ Type: constant.SiteTypeInterfaceSettings, Content: string(interfaceContent), Status: 1, @@ -254,10 +229,150 @@ func splitInterfaceMenu(ctx context.Context, x *xorm.Engine) error { if err != nil { return err } - } else { + } + + return nil +} + +// splitLegalMenu splits the site legal settings into policies and security settings +func splitLegalMenu(ctx context.Context, x *xorm.Engine) error { + var ( + siteInfo = &entity.SiteInfo{} + siteInfoPolices = &entity.SiteInfo{} + siteInfoSecurity = &entity.SiteInfo{} + siteInfoLogin = &entity.SiteInfo{} + siteInfoGeneral = &entity.SiteInfo{} + ) + + type SiteLogin struct { + AllowNewRegistrations bool `json:"allow_new_registrations"` + AllowEmailRegistrations bool `json:"allow_email_registrations"` + AllowPasswordLogin bool `json:"allow_password_login"` + LoginRequired bool `json:"login_required"` + AllowEmailDomains []string `json:"allow_email_domains"` + } + + type SiteGeneral struct { + Name string `validate:"required,sanitizer,gt=1,lte=128" form:"name" json:"name"` + ShortDescription string `validate:"omitempty,sanitizer,gt=3,lte=255" form:"short_description" json:"short_description"` + Description string `validate:"omitempty,sanitizer,gt=3,lte=2000" form:"description" json:"description"` + SiteUrl string `validate:"required,sanitizer,gt=1,lte=512,url" form:"site_url" json:"site_url"` + ContactEmail string `validate:"required,sanitizer,gt=1,lte=512,email" form:"contact_email" json:"contact_email"` + CheckUpdate bool `validate:"omitempty,sanitizer" form:"check_update" json:"check_update"` + } + + // find old site legal settings + exist, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeLegal}).Get(siteInfo) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + return err + } + if !exist { + return nil + } + oldSiteLegal := &schema.SiteLegalResp{} + if err := json.Unmarshal([]byte(siteInfo.Content), oldSiteLegal); err != nil { + return err + } + + // find old site login settings + existsLogin, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeLogin}).Get(siteInfoLogin) + if err != nil { + return err + } + oldSiteLogin := &SiteLogin{} + if err := json.Unmarshal([]byte(siteInfoLogin.Content), oldSiteLogin); err != nil { + return err + } + + // find old site general settings + existGeneral, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeGeneral}).Get(siteInfoGeneral) + if err != nil { + return err + } + oldSiteGeneral := &SiteGeneral{} + if err := json.Unmarshal([]byte(siteInfoLogin.Content), oldSiteGeneral); err != nil { + return err + } + + sitePolicies := &schema.SitePoliciesResp{ + TermsOfServiceOriginalText: oldSiteLegal.TermsOfServiceOriginalText, + TermsOfServiceParsedText: oldSiteLegal.TermsOfServiceParsedText, + PrivacyPolicyOriginalText: oldSiteLegal.PrivacyPolicyOriginalText, + PrivacyPolicyParsedText: oldSiteLegal.PrivacyPolicyParsedText, + } + siteLogin := &schema.SiteLoginResp{ + AllowNewRegistrations: oldSiteLogin.AllowNewRegistrations, + AllowEmailRegistrations: oldSiteLogin.AllowEmailRegistrations, + AllowPasswordLogin: oldSiteLogin.AllowPasswordLogin, + AllowEmailDomains: oldSiteLogin.AllowEmailDomains, + } + siteGeneral := &schema.SiteGeneralReq{ + Name: oldSiteGeneral.Name, + ShortDescription: oldSiteGeneral.ShortDescription, + Description: oldSiteGeneral.Description, + SiteUrl: oldSiteGeneral.SiteUrl, + ContactEmail: oldSiteGeneral.ContactEmail, + } + siteSecurity := &schema.SiteSecurityResp{ + LoginRequired: oldSiteLogin.LoginRequired, + ExternalContentDisplay: oldSiteLegal.ExternalContentDisplay, + CheckUpdate: oldSiteGeneral.CheckUpdate, + } + if !existsLogin { + siteSecurity.LoginRequired = false + } + if !existGeneral { + siteSecurity.CheckUpdate = true + } + + // save settings + // save policies settings + existsPolicies, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypePolicies}).Get(siteInfoPolices) + if err != nil { + return err + } + policiesContent, err := json.Marshal(sitePolicies) + if err != nil { + return err + } + if !existsPolicies { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ + Type: constant.SiteTypePolicies, + Content: string(policiesContent), + Status: 1, + }) + if err != nil { + return err + } + } + + // save security settings + existsSecurity, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeSecurity}).Get(siteInfoSecurity) + if err != nil { + return err + } + securityContent, err := json.Marshal(siteSecurity) + if err != nil { + return err + } + if !existsSecurity { _, err = x.Context(ctx).Insert(&entity.SiteInfo{ - Type: constant.SiteTypeInterfaceSettings, - Content: string(interfaceContent), + Type: constant.SiteTypeSecurity, + Content: string(securityContent), + Status: 1, + }) + if err != nil { + return err + } + } + + // save login settings + if existsLogin { + loginContent, err := json.Marshal(siteLogin) + _, err = x.Context(ctx).ID(siteInfoLogin.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeLogin, + Content: string(loginContent), Status: 1, }) if err != nil { @@ -265,5 +380,17 @@ func splitInterfaceMenu(ctx context.Context, x *xorm.Engine) error { } } + // save general settings + if existGeneral { + generalContent, err := json.Marshal(siteGeneral) + _, err = x.Context(ctx).ID(siteInfoGeneral.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeGeneral, + Content: string(generalContent), + Status: 1, + }) + if err != nil { + return err + } + } return nil } diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go index c776b44f0..1fe8bdb14 100644 --- a/internal/router/answer_api_router.go +++ b/internal/router/answer_api_router.go @@ -359,8 +359,11 @@ func (a *AnswerAPIRouter) RegisterAnswerAdminAPIRouter(r *gin.RouterGroup) { r.GET("/siteinfo/advanced", a.adminSiteInfoController.GetSiteAdvanced) r.PUT("/siteinfo/advanced", a.adminSiteInfoController.UpdateSiteAdvanced) - r.GET("/siteinfo/legal", a.adminSiteInfoController.GetSiteLegal) - r.PUT("/siteinfo/legal", a.adminSiteInfoController.UpdateSiteLegal) + r.GET("/siteinfo/polices", a.adminSiteInfoController.GetSitePolicies) + r.PUT("/siteinfo/polices", a.adminSiteInfoController.UpdateSitePolices) + r.GET("/siteinfo/security", a.adminSiteInfoController.GetSiteSecurity) + r.PUT("/siteinfo/security", a.adminSiteInfoController.UpdateSiteSecurity) + r.GET("/siteinfo/seo", a.adminSiteInfoController.GetSeo) r.PUT("/siteinfo/seo", a.adminSiteInfoController.UpdateSeo) r.GET("/siteinfo/login", a.adminSiteInfoController.GetSiteLogin) diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index a060558a9..563b0cc11 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -42,7 +42,6 @@ type SiteGeneralReq struct { Description string `validate:"omitempty,sanitizer,gt=3,lte=2000" form:"description" json:"description"` SiteUrl string `validate:"required,sanitizer,gt=1,lte=512,url" form:"site_url" json:"site_url"` ContactEmail string `validate:"required,sanitizer,gt=1,lte=512,email" form:"contact_email" json:"contact_email"` - CheckUpdate bool `validate:"omitempty,sanitizer" form:"check_update" json:"check_update"` } func (r *SiteGeneralReq) FormatSiteUrl() { @@ -158,6 +157,7 @@ type SiteWriteTag struct { } // SiteLegalReq site branding request +// Deprecated: use SitePoliciesReq and SiteSecurityReq instead type SiteLegalReq struct { TermsOfServiceOriginalText string `json:"terms_of_service_original_text"` TermsOfServiceParsedText string `json:"terms_of_service_parsed_text"` @@ -166,6 +166,22 @@ type SiteLegalReq struct { ExternalContentDisplay string `validate:"required,oneof=always_display ask_before_display" json:"external_content_display"` } +type SitePoliciesReq struct { + TermsOfServiceOriginalText string `json:"terms_of_service_original_text"` + TermsOfServiceParsedText string `json:"terms_of_service_parsed_text"` + PrivacyPolicyOriginalText string `json:"privacy_policy_original_text"` + PrivacyPolicyParsedText string `json:"privacy_policy_parsed_text"` +} + +type SiteSecurityReq struct { + LoginRequired bool `json:"login_required"` + ExternalContentDisplay string `validate:"required,oneof=always_display ask_before_display" json:"external_content_display"` + CheckUpdate bool `validate:"omitempty,sanitizer" form:"check_update" json:"check_update"` +} + +type SitePoliciesResp SitePoliciesReq +type SiteSecurityResp SiteSecurityReq + // GetSiteLegalInfoReq site site legal request type GetSiteLegalInfoReq struct { InfoType string `validate:"required,oneof=tos privacy" form:"info_type"` @@ -204,7 +220,6 @@ type SiteLoginReq struct { AllowNewRegistrations bool `json:"allow_new_registrations"` AllowEmailRegistrations bool `json:"allow_email_registrations"` AllowPasswordLogin bool `json:"allow_password_login"` - LoginRequired bool `json:"login_required"` AllowEmailDomains []string `json:"allow_email_domains"` } @@ -282,6 +297,7 @@ type SiteAdvancedResp SiteAdvancedReq type SiteTagsResp SiteTagsReq // SiteLegalResp site write response +// Deprecated: use SitePoliciesResp and SiteSecurityResp instead type SiteLegalResp SiteLegalReq // SiteLegalSimpleResp site write response @@ -311,7 +327,6 @@ type SiteInfoResp struct { Revision string `json:"revision"` } -// todo: 检查模板使用 type TemplateSiteInfoResp struct { General *SiteGeneralResp `json:"general"` Interface *SiteInterfaceSettingsResp `json:"interface"` diff --git a/internal/service/dashboard/dashboard_service.go b/internal/service/dashboard/dashboard_service.go index 8b08ba02f..a6ac76e63 100644 --- a/internal/service/dashboard/dashboard_service.go +++ b/internal/service/dashboard/dashboard_service.go @@ -101,6 +101,12 @@ type DashboardService interface { func (ds *dashboardService) Statistical(ctx context.Context) (*schema.DashboardInfo, error) { dashboardInfo := ds.getFromCache(ctx) + security, err := ds.siteInfoService.GetSiteSecurity(ctx) + if err != nil { + log.Errorf("get general site info failed: %s", err) + return dashboardInfo, nil + } + if dashboardInfo == nil { dashboardInfo = &schema.DashboardInfo{} dashboardInfo.AnswerCount = ds.answerCount(ctx) @@ -108,12 +114,7 @@ func (ds *dashboardService) Statistical(ctx context.Context) (*schema.DashboardI dashboardInfo.UserCount = ds.userCount(ctx) dashboardInfo.VoteCount = ds.voteCount(ctx) dashboardInfo.OccupyingStorageSpace = ds.calculateStorage() - general, err := ds.siteInfoService.GetSiteGeneral(ctx) - if err != nil { - log.Errorf("get general site info failed: %s", err) - return dashboardInfo, nil - } - if general.CheckUpdate { + if security.CheckUpdate { dashboardInfo.VersionInfo.RemoteVersion = ds.remoteVersion(ctx) } dashboardInfo.DatabaseVersion = ds.getDatabaseInfo() @@ -141,9 +142,7 @@ func (ds *dashboardService) Statistical(ctx context.Context) (*schema.DashboardI dashboardInfo.VersionInfo.Version = constant.Version dashboardInfo.VersionInfo.Revision = constant.Revision dashboardInfo.GoVersion = constant.GoVersion - if siteLogin, err := ds.siteInfoService.GetSiteLogin(ctx); err == nil { - dashboardInfo.LoginRequired = siteLogin.LoginRequired - } + dashboardInfo.LoginRequired = security.LoginRequired ds.setCache(ctx, dashboardInfo) return dashboardInfo, nil diff --git a/internal/service/mock/siteinfo_repo_mock.go b/internal/service/mock/siteinfo_repo_mock.go index 5d5429ba4..a4d9d97b2 100644 --- a/internal/service/mock/siteinfo_repo_mock.go +++ b/internal/service/mock/siteinfo_repo_mock.go @@ -231,10 +231,10 @@ func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInfoByType(ctx, siteType } // GetSiteInterface mocks base method. -func (m *MockSiteInfoCommonService) GetSiteInterface(ctx context.Context) (*schema.SiteInterfaceResp, error) { +func (m *MockSiteInfoCommonService) GetSiteInterface(ctx context.Context) (*schema.SiteInterfaceSettingsResp, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSiteInterface", ctx) - ret0, _ := ret[0].(*schema.SiteInterfaceResp) + ret0, _ := ret[0].(*schema.SiteInterfaceSettingsResp) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -245,34 +245,34 @@ func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInterface(ctx interface{ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteInterface", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteInterface), ctx) } -// GetSiteLegal mocks base method. -func (m *MockSiteInfoCommonService) GetSiteLegal(ctx context.Context) (*schema.SiteLegalResp, error) { +// GetSiteLogin mocks base method. +func (m *MockSiteInfoCommonService) GetSiteLogin(ctx context.Context) (*schema.SiteLoginResp, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSiteLegal", ctx) - ret0, _ := ret[0].(*schema.SiteLegalResp) + ret := m.ctrl.Call(m, "GetSiteLogin", ctx) + ret0, _ := ret[0].(*schema.SiteLoginResp) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetSiteLegal indicates an expected call of GetSiteLegal. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLegal(ctx interface{}) *gomock.Call { +// GetSiteLogin indicates an expected call of GetSiteLogin. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLegal", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLegal), ctx) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLogin", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLogin), ctx) } -// GetSiteLogin mocks base method. -func (m *MockSiteInfoCommonService) GetSiteLogin(ctx context.Context) (*schema.SiteLoginResp, error) { +// GetSitePolicies mocks base method. +func (m *MockSiteInfoCommonService) GetSitePolicies(ctx context.Context) (*schema.SitePoliciesResp, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSiteLogin", ctx) - ret0, _ := ret[0].(*schema.SiteLoginResp) + ret := m.ctrl.Call(m, "GetSitePolicies", ctx) + ret0, _ := ret[0].(*schema.SitePoliciesResp) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetSiteLogin indicates an expected call of GetSiteLogin. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx interface{}) *gomock.Call { +// GetSitePolicies indicates an expected call of GetSitePolicies. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSitePolicies(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLogin", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLogin), ctx) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSitePolicies", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSitePolicies), ctx) } // GetSiteQuestion mocks base method. @@ -290,6 +290,21 @@ func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteQuestion(ctx interface{} return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteQuestion", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteQuestion), ctx) } +// GetSiteSecurity mocks base method. +func (m *MockSiteInfoCommonService) GetSiteSecurity(ctx context.Context) (*schema.SiteSecurityResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteSecurity", ctx) + ret0, _ := ret[0].(*schema.SiteSecurityResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteSecurity indicates an expected call of GetSiteSecurity. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteSecurity(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteSecurity", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteSecurity), ctx) +} + // GetSiteSeo mocks base method. func (m *MockSiteInfoCommonService) GetSiteSeo(ctx context.Context) (*schema.SiteSeoResp, error) { m.ctrl.T.Helper() @@ -350,6 +365,21 @@ func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsers(ctx interface{}) * return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteUsers", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteUsers), ctx) } +// GetSiteUsersSettings mocks base method. +func (m *MockSiteInfoCommonService) GetSiteUsersSettings(ctx context.Context) (*schema.SiteUsersSettingsResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteUsersSettings", ctx) + ret0, _ := ret[0].(*schema.SiteUsersSettingsResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteUsersSettings indicates an expected call of GetSiteUsersSettings. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsersSettings(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteUsersSettings", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteUsersSettings), ctx) +} + // GetSiteWrite mocks base method. func (m *MockSiteInfoCommonService) GetSiteWrite(ctx context.Context) (*schema.SiteWriteResp, error) { m.ctrl.T.Helper() diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index 956511cee..d374008cb 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -138,9 +138,14 @@ func (s *SiteInfoService) GetSiteAdvanced(ctx context.Context) (resp *schema.Sit return s.siteInfoCommonService.GetSiteAdvanced(ctx) } -// GetSiteLegal get site legal info -func (s *SiteInfoService) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) { - return s.siteInfoCommonService.GetSiteLegal(ctx) +// GetSitePolicies get site legal info +func (s *SiteInfoService) GetSitePolicies(ctx context.Context) (resp *schema.SitePoliciesResp, err error) { + return s.siteInfoCommonService.GetSitePolicies(ctx) +} + +// GetSiteSecurity get site security info +func (s *SiteInfoService) GetSiteSecurity(ctx context.Context) (resp *schema.SiteSecurityResp, err error) { + return s.siteInfoCommonService.GetSiteSecurity(ctx) } // GetSiteLogin get site login info @@ -261,15 +266,26 @@ func (s *SiteInfoService) SaveSiteTags(ctx context.Context, req *schema.SiteTags return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeTags, data) } -// SaveSiteLegal save site legal configuration -func (s *SiteInfoService) SaveSiteLegal(ctx context.Context, req *schema.SiteLegalReq) (err error) { +// SaveSitePolicies save site policies configuration +func (s *SiteInfoService) SaveSitePolicies(ctx context.Context, req *schema.SitePoliciesReq) (err error) { + content, _ := json.Marshal(req) + data := &entity.SiteInfo{ + Type: constant.SiteTypePolicies, + Content: string(content), + Status: 1, + } + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypePolicies, data) +} + +// SaveSiteSecurity save site security configuration +func (s *SiteInfoService) SaveSiteSecurity(ctx context.Context, req *schema.SiteSecurityReq) (err error) { content, _ := json.Marshal(req) data := &entity.SiteInfo{ - Type: constant.SiteTypeLegal, + Type: constant.SiteTypeSecurity, Content: string(content), Status: 1, } - return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeLegal, data) + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeSecurity, data) } // SaveSiteLogin save site legal configuration @@ -361,13 +377,13 @@ func (s *SiteInfoService) GetSeo(ctx context.Context) (resp *schema.SiteSeoReq, if err = s.siteInfoCommonService.GetSiteInfoByType(ctx, constant.SiteTypeSeo, resp); err != nil { return resp, err } - loginConfig, err := s.GetSiteLogin(ctx) + siteSecurity, err := s.GetSiteSecurity(ctx) if err != nil { log.Error(err) return resp, nil } // If the site is set to privacy mode, prohibit crawling any page. - if loginConfig.LoginRequired { + if siteSecurity.LoginRequired { resp.Robots = "User-agent: *\nDisallow: /" return resp, nil } diff --git a/internal/service/siteinfo_common/siteinfo_service.go b/internal/service/siteinfo_common/siteinfo_service.go index dde0114bd..5ed399136 100644 --- a/internal/service/siteinfo_common/siteinfo_service.go +++ b/internal/service/siteinfo_common/siteinfo_service.go @@ -55,7 +55,8 @@ type SiteInfoCommonService interface { GetSiteAdvanced(ctx context.Context) (resp *schema.SiteAdvancedResp, err error) GetSiteQuestion(ctx context.Context) (resp *schema.SiteQuestionsResp, err error) GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error) - GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) + GetSitePolicies(ctx context.Context) (resp *schema.SitePoliciesResp, err error) + GetSiteSecurity(ctx context.Context) (resp *schema.SiteSecurityResp, err error) GetSiteLogin(ctx context.Context) (resp *schema.SiteLoginResp, err error) GetSiteCustomCssHTML(ctx context.Context) (resp *schema.SiteCustomCssHTMLResp, err error) GetSiteTheme(ctx context.Context) (resp *schema.SiteThemeResp, err error) @@ -73,7 +74,7 @@ func NewSiteInfoCommonService(siteInfoRepo SiteInfoRepo) SiteInfoCommonService { // GetSiteGeneral get site info general func (s *siteInfoCommonService) GetSiteGeneral(ctx context.Context) (resp *schema.SiteGeneralResp, err error) { - resp = &schema.SiteGeneralResp{CheckUpdate: true} + resp = &schema.SiteGeneralResp{} if err = s.GetSiteInfoByType(ctx, constant.SiteTypeGeneral, resp); err != nil { return nil, err } @@ -207,10 +208,19 @@ func (s *siteInfoCommonService) GetSiteTag(ctx context.Context) (resp *schema.Si return resp, nil } -// GetSiteLegal get site info write -func (s *siteInfoCommonService) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) { - resp = &schema.SiteLegalResp{} - if err = s.GetSiteInfoByType(ctx, constant.SiteTypeLegal, resp); err != nil { +// GetSitePolicies get site info policies +func (s *siteInfoCommonService) GetSitePolicies(ctx context.Context) (resp *schema.SitePoliciesResp, err error) { + resp = &schema.SitePoliciesResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypePolicies, resp); err != nil { + return nil, err + } + return resp, nil +} + +// GetSiteSecurity get site security config +func (s *siteInfoCommonService) GetSiteSecurity(ctx context.Context) (resp *schema.SiteSecurityResp, err error) { + resp = &schema.SiteSecurityResp{CheckUpdate: true} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeSecurity, resp); err != nil { return nil, err } return resp, nil From 94de21361e60c4653c229f0d3ad14fa8f0f58cf9 Mon Sep 17 00:00:00 2001 From: kumfo Date: Wed, 21 Jan 2026 16:29:08 +0800 Subject: [PATCH 60/92] feat(menu): update schema to remove deprecated min_tags and add MinimumTags to SiteQuestionsReq --- docs/docs.go | 27 +++++++++-------------- docs/swagger.json | 27 +++++++++-------------- docs/swagger.yaml | 20 ++++++++--------- internal/migrations/v30.go | 2 +- internal/schema/siteinfo_schema.go | 3 ++- internal/service/tag_common/tag_common.go | 2 +- 6 files changed, 35 insertions(+), 46 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index a70cdab09..c624133bd 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -10982,12 +10982,7 @@ const docTemplate = `{ "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { - "description": "todo", - "allOf": [ - { - "$ref": "#/definitions/schema.SiteLoginResp" - } - ] + "$ref": "#/definitions/schema.SiteLoginResp" }, "revision": { "type": "string" @@ -11163,6 +11158,11 @@ const docTemplate = `{ "maximum": 65535, "minimum": 0 }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "restrict_answer": { "type": "boolean" } @@ -11176,6 +11176,11 @@ const docTemplate = `{ "maximum": 65535, "minimum": 0 }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "restrict_answer": { "type": "boolean" } @@ -11260,11 +11265,6 @@ const docTemplate = `{ "schema.SiteTagsReq": { "type": "object", "properties": { - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, "recommend_tags": { "type": "array", "items": { @@ -11285,11 +11285,6 @@ const docTemplate = `{ "schema.SiteTagsResp": { "type": "object", "properties": { - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, "recommend_tags": { "type": "array", "items": { diff --git a/docs/swagger.json b/docs/swagger.json index 05e3302c6..58f385790 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -10974,12 +10974,7 @@ "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { - "description": "todo", - "allOf": [ - { - "$ref": "#/definitions/schema.SiteLoginResp" - } - ] + "$ref": "#/definitions/schema.SiteLoginResp" }, "revision": { "type": "string" @@ -11155,6 +11150,11 @@ "maximum": 65535, "minimum": 0 }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "restrict_answer": { "type": "boolean" } @@ -11168,6 +11168,11 @@ "maximum": 65535, "minimum": 0 }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "restrict_answer": { "type": "boolean" } @@ -11252,11 +11257,6 @@ "schema.SiteTagsReq": { "type": "object", "properties": { - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, "recommend_tags": { "type": "array", "items": { @@ -11277,11 +11277,6 @@ "schema.SiteTagsResp": { "type": "object", "properties": { - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, "recommend_tags": { "type": "array", "items": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 85a05baf0..39235a336 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2210,9 +2210,7 @@ definitions: interface: $ref: '#/definitions/schema.SiteInterfaceSettingsResp' login: - allOf: - - $ref: '#/definitions/schema.SiteLoginResp' - description: todo + $ref: '#/definitions/schema.SiteLoginResp' revision: type: string site_advanced: @@ -2330,6 +2328,10 @@ definitions: maximum: 65535 minimum: 0 type: integer + min_tags: + maximum: 5 + minimum: 0 + type: integer restrict_answer: type: boolean type: object @@ -2339,6 +2341,10 @@ definitions: maximum: 65535 minimum: 0 type: integer + min_tags: + maximum: 5 + minimum: 0 + type: integer restrict_answer: type: boolean type: object @@ -2396,10 +2402,6 @@ definitions: type: object schema.SiteTagsReq: properties: - min_tags: - maximum: 5 - minimum: 0 - type: integer recommend_tags: items: $ref: '#/definitions/schema.SiteWriteTag' @@ -2413,10 +2415,6 @@ definitions: type: object schema.SiteTagsResp: properties: - min_tags: - maximum: 5 - minimum: 0 - type: integer recommend_tags: items: $ref: '#/definitions/schema.SiteWriteTag' diff --git a/internal/migrations/v30.go b/internal/migrations/v30.go index c73f501d5..aa2f48b36 100644 --- a/internal/migrations/v30.go +++ b/internal/migrations/v30.go @@ -80,6 +80,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { } // site questions settings siteQuestions := &schema.SiteQuestionsResp{ + MinimumTags: siteWrite.MinimumTags, MinimumContent: siteWrite.MinimumContent, RestrictAnswer: siteWrite.RestrictAnswer, } @@ -87,7 +88,6 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { siteTags := &schema.SiteTagsResp{ ReservedTags: siteWrite.ReservedTags, RecommendTags: siteWrite.RecommendTags, - MinimumTags: siteWrite.MinimumTags, RequiredTag: siteWrite.RequiredTag, } diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index 563b0cc11..b2d2c4b31 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -88,6 +88,7 @@ type SiteBrandingReq struct { } // SiteWriteReq site write request +// Deprecated: use SiteQuestionsReq, SiteAdvancedReq and SiteTagsReq instead type SiteWriteReq struct { MinimumContent int `validate:"omitempty,gte=0,lte=65535" json:"min_content"` RestrictAnswer bool `validate:"omitempty" json:"restrict_answer"` @@ -107,6 +108,7 @@ type SiteWriteResp SiteWriteReq // SiteQuestionsReq site questions settings request type SiteQuestionsReq struct { + MinimumTags int `validate:"omitempty,gte=0,lte=5" json:"min_tags"` MinimumContent int `validate:"omitempty,gte=0,lte=65535" json:"min_content"` RestrictAnswer bool `validate:"omitempty" json:"restrict_answer"` } @@ -124,7 +126,6 @@ type SiteAdvancedReq struct { type SiteTagsReq struct { ReservedTags []*SiteWriteTag `validate:"omitempty,dive" json:"reserved_tags"` RecommendTags []*SiteWriteTag `validate:"omitempty,dive" json:"recommend_tags"` - MinimumTags int `validate:"omitempty,gte=0,lte=5" json:"min_tags"` RequiredTag bool `validate:"omitempty" json:"required_tag"` UserID string `json:"-"` } diff --git a/internal/service/tag_common/tag_common.go b/internal/service/tag_common/tag_common.go index 0da9f6fd5..87b53f396 100644 --- a/internal/service/tag_common/tag_common.go +++ b/internal/service/tag_common/tag_common.go @@ -295,7 +295,7 @@ func (ts *TagCommonService) ExistRecommend(ctx context.Context, tags []*schema.T } func (ts *TagCommonService) GetMinimumTags(ctx context.Context) (int, error) { - siteInfo, err := ts.siteInfoService.GetSiteTag(ctx) + siteInfo, err := ts.siteInfoService.GetSiteQuestion(ctx) if err != nil { return 1, err } From 0bb33e7ea43abbe80138942fc6ccef9c551016a7 Mon Sep 17 00:00:00 2001 From: kumfo Date: Wed, 21 Jan 2026 17:21:28 +0800 Subject: [PATCH 61/92] feat(siteinfo): fix GetSiteTag method to correctly assign response from siteInfoCommonService --- internal/service/siteinfo/siteinfo_service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index d374008cb..acd5baed1 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -111,7 +111,7 @@ func (s *SiteInfoService) GetSiteUsers(ctx context.Context) (resp *schema.SiteUs // GetSiteTag get site info write func (s *SiteInfoService) GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error) { resp = &schema.SiteTagsResp{} - _, err = s.siteInfoCommonService.GetSiteTag(ctx) + resp, err = s.siteInfoCommonService.GetSiteTag(ctx) if err != nil { log.Error(err) return resp, nil From 60f8cd1803ed707c87caf9fe394cdaec55511478 Mon Sep 17 00:00:00 2001 From: kumfo Date: Thu, 22 Jan 2026 10:59:28 +0800 Subject: [PATCH 62/92] feat(siteinfo): add site_security to response structure and update related schemas --- docs/docs.go | 3 +++ docs/swagger.json | 3 +++ docs/swagger.yaml | 2 ++ internal/controller/siteinfo_controller.go | 3 +++ internal/schema/siteinfo_schema.go | 1 + 5 files changed, 12 insertions(+) diff --git a/docs/docs.go b/docs/docs.go index c624133bd..23398e509 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -10996,6 +10996,9 @@ const docTemplate = `{ "site_questions": { "$ref": "#/definitions/schema.SiteQuestionsResp" }, + "site_security": { + "$ref": "#/definitions/schema.SiteSecurityResp" + }, "site_seo": { "$ref": "#/definitions/schema.SiteSeoResp" }, diff --git a/docs/swagger.json b/docs/swagger.json index 58f385790..b9dc0b0b1 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -10988,6 +10988,9 @@ "site_questions": { "$ref": "#/definitions/schema.SiteQuestionsResp" }, + "site_security": { + "$ref": "#/definitions/schema.SiteSecurityResp" + }, "site_seo": { "$ref": "#/definitions/schema.SiteSeoResp" }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 39235a336..4a680ec49 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2219,6 +2219,8 @@ definitions: $ref: '#/definitions/schema.SiteLegalSimpleResp' site_questions: $ref: '#/definitions/schema.SiteQuestionsResp' + site_security: + $ref: '#/definitions/schema.SiteSecurityResp' site_seo: $ref: '#/definitions/schema.SiteSeoResp' site_tags: diff --git a/internal/controller/siteinfo_controller.go b/internal/controller/siteinfo_controller.go index 64aa02ce7..320c1b475 100644 --- a/internal/controller/siteinfo_controller.go +++ b/internal/controller/siteinfo_controller.go @@ -107,6 +107,9 @@ func (sc *SiteInfoController) GetSiteInfo(ctx *gin.Context) { if legal, err := sc.siteInfoService.GetSiteSecurity(ctx); err == nil { resp.Legal = &schema.SiteLegalSimpleResp{ExternalContentDisplay: legal.ExternalContentDisplay} } + if security, err := sc.siteInfoService.GetSiteSecurity(ctx); err == nil { + resp.Security = security + } handler.HandleResponse(ctx, nil, resp) } diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index b2d2c4b31..19382d102 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -324,6 +324,7 @@ type SiteInfoResp struct { Questions *SiteQuestionsResp `json:"site_questions"` Tags *SiteTagsResp `json:"site_tags"` Legal *SiteLegalSimpleResp `json:"site_legal"` + Security *SiteSecurityResp `json:"site_security"` Version string `json:"version"` Revision string `json:"revision"` } From 81511e386a36188ef9418fe5521d3ce9c29de3a3 Mon Sep 17 00:00:00 2001 From: kumfo Date: Thu, 22 Jan 2026 11:49:50 +0800 Subject: [PATCH 63/92] feat(menu): deprecate default_avatar and gravatar_base_url in SiteInterfaceReq schema --- docs/docs.go | 11 ----------- docs/swagger.json | 11 ----------- docs/swagger.yaml | 8 -------- internal/schema/siteinfo_schema.go | 10 ++++++---- 4 files changed, 6 insertions(+), 34 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index 23398e509..00eb75ce2 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -11022,21 +11022,10 @@ const docTemplate = `{ "schema.SiteInterfaceReq": { "type": "object", "required": [ - "default_avatar", "language", "time_zone" ], "properties": { - "default_avatar": { - "type": "string", - "enum": [ - "system", - "gravatar" - ] - }, - "gravatar_base_url": { - "type": "string" - }, "language": { "type": "string", "maxLength": 128 diff --git a/docs/swagger.json b/docs/swagger.json index b9dc0b0b1..c181109d2 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -11014,21 +11014,10 @@ "schema.SiteInterfaceReq": { "type": "object", "required": [ - "default_avatar", "language", "time_zone" ], "properties": { - "default_avatar": { - "type": "string", - "enum": [ - "system", - "gravatar" - ] - }, - "gravatar_base_url": { - "type": "string" - }, "language": { "type": "string", "maxLength": 128 diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 4a680ec49..caab11876 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2236,13 +2236,6 @@ definitions: type: object schema.SiteInterfaceReq: properties: - default_avatar: - enum: - - system - - gravatar - type: string - gravatar_base_url: - type: string language: maxLength: 128 type: string @@ -2250,7 +2243,6 @@ definitions: maxLength: 128 type: string required: - - default_avatar - language - time_zone type: object diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index 19382d102..0b5ad0620 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -58,10 +58,12 @@ func (r *SiteGeneralReq) FormatSiteUrl() { // SiteInterfaceReq site interface request type SiteInterfaceReq struct { - Language string `validate:"required,gt=1,lte=128" form:"language" json:"language"` - TimeZone string `validate:"required,gt=1,lte=128" form:"time_zone" json:"time_zone"` - DefaultAvatar string `validate:"required,oneof=system gravatar" json:"default_avatar"` - GravatarBaseURL string `validate:"omitempty" json:"gravatar_base_url"` + Language string `validate:"required,gt=1,lte=128" form:"language" json:"language"` + TimeZone string `validate:"required,gt=1,lte=128" form:"time_zone" json:"time_zone"` + // Deperecated: use SiteUsersSettingsReq instead + DefaultAvatar string `validate:"omitempty" json:"-"` + // Deperecated: use SiteUsersSettingsReq instead + GravatarBaseURL string `validate:"omitempty" json:"-"` } // SiteInterfaceSettingsReq site interface settings request From 8b8550e9ca3b5e85ef1009bb709eb4bedbdd7ab4 Mon Sep 17 00:00:00 2001 From: kumfo Date: Thu, 22 Jan 2026 12:18:57 +0800 Subject: [PATCH 64/92] feat(docs): add Apache License 2.0 header to docs.go and swagger.yaml --- docs/docs.go | 19 +++++++++++++++++++ docs/swagger.yaml | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/docs/docs.go b/docs/docs.go index 00eb75ce2..cfe48366f 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + // Package docs Code generated by swaggo/swag. DO NOT EDIT package docs diff --git a/docs/swagger.yaml b/docs/swagger.yaml index caab11876..13e9575eb 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,3 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + basePath: / definitions: constant.NotificationChannelKey: From d65e257f92f352e08b8457efd9b490312c3fe297 Mon Sep 17 00:00:00 2001 From: kumfo Date: Thu, 22 Jan 2026 12:21:02 +0800 Subject: [PATCH 65/92] feat(docs): add Apache License 2.0 header to wire_gen.go --- cmd/wire_gen.go | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index 2808619b3..5b9990213 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -1,9 +1,29 @@ -// Code generated by Wire. DO NOT EDIT. - -//go:generate go run -mod=mod github.com/google/wire/cmd/wire //go:build !wireinject // +build !wireinject +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// Code generated by Wire. DO NOT EDIT. + +//go:generate go run github.com/google/wire/cmd/wire + package answercmd import ( From f05f1eb80d10124c252b1b3f812aa26e95aad8f8 Mon Sep 17 00:00:00 2001 From: kumfo Date: Tue, 20 Jan 2026 14:54:52 +0800 Subject: [PATCH 66/92] feat(menu): update admin menu settings to include questions, tags, and advanced options --- cmd/wire_gen.go | 24 ++- go.mod | 2 +- internal/base/constant/site_type.go | 3 + internal/controller/answer_controller.go | 2 +- internal/controller/siteinfo_controller.go | 10 +- .../controller_admin/siteinfo_controller.go | 94 ++++++++-- internal/migrations/migrations.go | 1 + internal/migrations/v30.go | 173 ++++++++++++++++++ internal/router/answer_api_router.go | 10 +- internal/schema/siteinfo_schema.go | 41 ++++- internal/service/mock/siteinfo_repo_mock.go | 81 ++++++-- internal/service/question_common/question.go | 2 +- internal/service/siteinfo/siteinfo_service.go | 51 ++++-- .../siteinfo_common/siteinfo_service.go | 30 +++ internal/service/tag_common/tag_common.go | 8 +- internal/service/uploader/upload.go | 32 ++-- 16 files changed, 485 insertions(+), 79 deletions(-) create mode 100644 internal/migrations/v30.go diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index 8435cf310..22a70f29d 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -1,8 +1,28 @@ +//go:build !wireinject +// +build !wireinject + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + // Code generated by Wire. DO NOT EDIT. //go:generate go run github.com/google/wire/cmd/wire -//go:build !wireinject -// +build !wireinject package answercmd diff --git a/go.mod b/go.mod index 52d64c738..d24302954 100644 --- a/go.mod +++ b/go.mod @@ -37,6 +37,7 @@ require ( github.com/grokify/html-strip-tags-go v0.1.0 github.com/jinzhu/copier v0.4.0 github.com/jinzhu/now v1.1.5 + github.com/joho/godotenv v1.5.1 github.com/lib/pq v1.10.9 github.com/microcosm-cc/bluemonday v1.0.27 github.com/mozillazg/go-pinyin v0.20.0 @@ -117,7 +118,6 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/joho/godotenv v1.5.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect diff --git a/internal/base/constant/site_type.go b/internal/base/constant/site_type.go index 65b487c5d..6106b190c 100644 --- a/internal/base/constant/site_type.go +++ b/internal/base/constant/site_type.go @@ -31,4 +31,7 @@ const ( SiteTypeTheme = "theme" SiteTypePrivileges = "privileges" SiteTypeUsers = "users" + SiteTypeAdvanced = "advanced" + SiteTypeQuestions = "questions" + SiteTypeTags = "tags" ) diff --git a/internal/controller/answer_controller.go b/internal/controller/answer_controller.go index e76b02ccc..99c89b778 100644 --- a/internal/controller/answer_controller.go +++ b/internal/controller/answer_controller.go @@ -242,7 +242,7 @@ func (ac *AnswerController) AddAnswer(ctx *gin.Context) { return } - write, err := ac.siteInfoCommonService.GetSiteWrite(ctx) + write, err := ac.siteInfoCommonService.GetSiteQuestion(ctx) if err != nil { handler.HandleResponse(ctx, err, nil) return diff --git a/internal/controller/siteinfo_controller.go b/internal/controller/siteinfo_controller.go index a336fb242..8035275a6 100644 --- a/internal/controller/siteinfo_controller.go +++ b/internal/controller/siteinfo_controller.go @@ -87,7 +87,15 @@ func (sc *SiteInfoController) GetSiteInfo(ctx *gin.Context) { if err != nil { log.Error(err) } - resp.Write, err = sc.siteInfoService.GetSiteWrite(ctx) + resp.Questions, err = sc.siteInfoService.GetSiteQuestion(ctx) + if err != nil { + log.Error(err) + } + resp.Tags, err = sc.siteInfoService.GetSiteTag(ctx) + if err != nil { + log.Error(err) + } + resp.Advanced, err = sc.siteInfoService.GetSiteAdvanced(ctx) if err != nil { log.Error(err) } diff --git a/internal/controller_admin/siteinfo_controller.go b/internal/controller_admin/siteinfo_controller.go index 8a92daba3..bbab97942 100644 --- a/internal/controller_admin/siteinfo_controller.go +++ b/internal/controller_admin/siteinfo_controller.go @@ -82,16 +82,42 @@ func (sc *SiteInfoController) GetSiteBranding(ctx *gin.Context) { handler.HandleResponse(ctx, err, resp) } -// GetSiteWrite get site interface -// @Summary get site interface -// @Description get site interface +// GetSiteTag get site tags setting +// @Summary get site tags setting +// @Description get site tags setting +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=schema.SiteTagsResp} +// @Router /answer/admin/api/siteinfo/tag [get] +func (sc *SiteInfoController) GetSiteTag(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteTag(ctx) + handler.HandleResponse(ctx, err, resp) +} + +// GetSiteQuestion get site questions setting +// @Summary get site questions setting +// @Description get site questions setting +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=schema.SiteQuestionsResp} +// @Router /answer/admin/api/siteinfo/question [get] +func (sc *SiteInfoController) GetSiteQuestion(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteQuestion(ctx) + handler.HandleResponse(ctx, err, resp) +} + +// GetSiteAdvanced get site advanced setting +// @Summary get site advanced setting +// @Description get site advanced setting // @Security ApiKeyAuth // @Tags admin // @Produce json -// @Success 200 {object} handler.RespBody{data=schema.SiteWriteResp} -// @Router /answer/admin/api/siteinfo/write [get] -func (sc *SiteInfoController) GetSiteWrite(ctx *gin.Context) { - resp, err := sc.siteInfoService.GetSiteWrite(ctx) +// @Success 200 {object} handler.RespBody{data=schema.SiteAdvancedResp} +// @Router /answer/admin/api/siteinfo/advanced [get] +func (sc *SiteInfoController) GetSiteAdvanced(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteAdvanced(ctx) handler.HandleResponse(ctx, err, resp) } @@ -288,23 +314,61 @@ func (sc *SiteInfoController) UpdateBranding(ctx *gin.Context) { handler.HandleResponse(ctx, saveErr, nil) } -// UpdateSiteWrite update site write info -// @Summary update site write info -// @Description update site write info +// UpdateSiteQuestion update site question settings +// @Summary update site question settings +// @Description update site question settings +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Param data body schema.SiteQuestionsReq true "questions settings" +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/siteinfo/question [put] +func (sc *SiteInfoController) UpdateSiteQuestion(ctx *gin.Context) { + req := &schema.SiteQuestionsReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + resp, err := sc.siteInfoService.SaveSiteQuestions(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// UpdateSiteTag update site tag settings +// @Summary update site tag settings +// @Description update site tag settings // @Security ApiKeyAuth // @Tags admin // @Produce json -// @Param data body schema.SiteWriteReq true "write info" +// @Param data body schema.SiteTagsReq true "tags settings" // @Success 200 {object} handler.RespBody{} -// @Router /answer/admin/api/siteinfo/write [put] -func (sc *SiteInfoController) UpdateSiteWrite(ctx *gin.Context) { - req := &schema.SiteWriteReq{} +// @Router /answer/admin/api/siteinfo/tag [put] +func (sc *SiteInfoController) UpdateSiteTag(ctx *gin.Context) { + req := &schema.SiteTagsReq{} if handler.BindAndCheck(ctx, req) { return } req.UserID = middleware.GetLoginUserIDFromContext(ctx) - resp, err := sc.siteInfoService.SaveSiteWrite(ctx, req) + resp, err := sc.siteInfoService.SaveSiteTags(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// UpdateSiteAdvanced update site advanced info +// @Summary update site advanced info +// @Description update site advanced info +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Param data body schema.SiteAdvancedReq true "advanced settings" +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/siteinfo/advanced [put] +func (sc *SiteInfoController) UpdateSiteAdvanced(ctx *gin.Context) { + req := &schema.SiteAdvancedReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + resp, err := sc.siteInfoService.SaveSiteAdvanced(ctx, req) handler.HandleResponse(ctx, err, resp) } diff --git a/internal/migrations/migrations.go b/internal/migrations/migrations.go index 9fda8c34d..783332df9 100644 --- a/internal/migrations/migrations.go +++ b/internal/migrations/migrations.go @@ -105,6 +105,7 @@ var migrations = []Migration{ NewMigration("v1.6.0", "move user config to interface", moveUserConfigToInterface, true), NewMigration("v1.7.0", "add optional tags", addOptionalTags, true), NewMigration("v1.7.2", "expand avatar column length", expandAvatarColumnLength, false), + NewMigration("v1.8.0", "change admin menu", updateAdminMenuSettings, true), } func GetMigrations() []Migration { diff --git a/internal/migrations/v30.go b/internal/migrations/v30.go new file mode 100644 index 000000000..5d5d5223f --- /dev/null +++ b/internal/migrations/v30.go @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package migrations + +import ( + "context" + "encoding/json" + + "github.com/apache/answer/internal/base/constant" + "github.com/apache/answer/internal/base/reason" + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/schema" + "github.com/segmentfault/pacman/errors" + "xorm.io/builder" + "xorm.io/xorm" +) + +func updateAdminMenuSettings(ctx context.Context, x *xorm.Engine) (err error) { + err = splitWriteMenu(ctx, x) + if err != nil { + return + } + return +} + +// splitWriteMenu splits the site write settings into advanced, questions, and tags settings +func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { + var ( + siteInfo = &entity.SiteInfo{} + siteInfoAdvanced = &entity.SiteInfo{} + siteInfoQuestions = &entity.SiteInfo{} + siteInfoTags = &entity.SiteInfo{} + ) + exist, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeWrite}).Get(siteInfo) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + return err + } + if !exist { + return nil + } + siteWrite := &schema.SiteWriteResp{} + if err := json.Unmarshal([]byte(siteInfo.Content), siteWrite); err != nil { + return err + } + // site advanced settings + siteAdvanced := &schema.SiteAdvancedResp{ + MaxImageSize: siteWrite.MaxImageSize, + MaxAttachmentSize: siteWrite.MaxAttachmentSize, + MaxImageMegapixel: siteWrite.MaxImageMegapixel, + AuthorizedImageExtensions: siteWrite.AuthorizedImageExtensions, + AuthorizedAttachmentExtensions: siteWrite.AuthorizedAttachmentExtensions, + } + // site questions settings + siteQuestions := &schema.SiteQuestionsResp{ + MinimumContent: siteWrite.MinimumContent, + RestrictAnswer: siteWrite.RestrictAnswer, + } + // site tags settings + siteTags := &schema.SiteTagsResp{ + ReservedTags: siteWrite.ReservedTags, + RecommendTags: siteWrite.RecommendTags, + MinimumTags: siteWrite.MinimumTags, + RequiredTag: siteWrite.RequiredTag, + } + + // save site settings + // save advanced settings + existsAdvanced, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeWrite}).Get(siteInfoAdvanced) + if err != nil { + return err + } + advancedContent, err := json.Marshal(siteAdvanced) + if err != nil { + return err + } + if existsAdvanced { + _, err = x.Context(ctx).ID(siteInfoAdvanced.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeAdvanced, + Content: string(advancedContent), + Status: 1, + }) + if err != nil { + return err + } + } else { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ + Type: constant.SiteTypeAdvanced, + Content: string(advancedContent), + Status: 1, + }) + if err != nil { + return err + } + } + + // save questions settings + existsQuestions, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeQuestions}).Get(siteInfoQuestions) + if err != nil { + return err + } + questionsContent, err := json.Marshal(siteQuestions) + if err != nil { + return err + } + if existsQuestions { + _, err = x.Context(ctx).ID(siteInfoQuestions.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeQuestions, + Content: string(questionsContent), + Status: 1, + }) + if err != nil { + return err + } + } else { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ + Type: constant.SiteTypeQuestions, + Content: string(questionsContent), + Status: 1, + }) + if err != nil { + return err + } + } + + // save tags settings + existsTags, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeTags}).Get(siteInfoTags) + if err != nil { + return err + } + tagsContent, err := json.Marshal(siteTags) + if err != nil { + return err + } + if existsTags { + _, err = x.Context(ctx).ID(siteInfoTags.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeTags, + Content: string(tagsContent), + Status: 1, + }) + if err != nil { + return err + } + } else { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ + Type: constant.SiteTypeTags, + Content: string(tagsContent), + Status: 1, + }) + if err != nil { + return err + } + } + + return nil +} diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go index 1191492b9..d717bc9d3 100644 --- a/internal/router/answer_api_router.go +++ b/internal/router/answer_api_router.go @@ -347,8 +347,14 @@ func (a *AnswerAPIRouter) RegisterAnswerAdminAPIRouter(r *gin.RouterGroup) { r.PUT("/siteinfo/interface", a.adminSiteInfoController.UpdateInterface) r.GET("/siteinfo/branding", a.adminSiteInfoController.GetSiteBranding) r.PUT("/siteinfo/branding", a.adminSiteInfoController.UpdateBranding) - r.GET("/siteinfo/write", a.adminSiteInfoController.GetSiteWrite) - r.PUT("/siteinfo/write", a.adminSiteInfoController.UpdateSiteWrite) + + r.GET("/siteinfo/question", a.adminSiteInfoController.GetSiteQuestion) + r.PUT("/siteinfo/question", a.adminSiteInfoController.UpdateSiteQuestion) + r.GET("/siteinfo/tag", a.adminSiteInfoController.GetSiteTag) + r.PUT("/siteinfo/tag", a.adminSiteInfoController.UpdateSiteTag) + r.GET("/siteinfo/advanced", a.adminSiteInfoController.GetSiteAdvanced) + r.PUT("/siteinfo/advanced", a.adminSiteInfoController.UpdateSiteAdvanced) + r.GET("/siteinfo/legal", a.adminSiteInfoController.GetSiteLegal) r.PUT("/siteinfo/legal", a.adminSiteInfoController.UpdateSiteLegal) r.GET("/siteinfo/seo", a.adminSiteInfoController.GetSeo) diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index 9eb919a0c..deacf08fb 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -89,21 +89,47 @@ type SiteWriteReq struct { UserID string `json:"-"` } -func (s *SiteWriteResp) GetMaxImageSize() int64 { +type SiteWriteResp SiteWriteReq + +// SiteQuestionsReq site questions settings request +type SiteQuestionsReq struct { + MinimumContent int `validate:"omitempty,gte=0,lte=65535" json:"min_content"` + RestrictAnswer bool `validate:"omitempty" json:"restrict_answer"` +} + +// SiteAdvancedReq site advanced settings request +type SiteAdvancedReq struct { + MaxImageSize int `validate:"omitempty,gt=0" json:"max_image_size"` + MaxAttachmentSize int `validate:"omitempty,gt=0" json:"max_attachment_size"` + MaxImageMegapixel int `validate:"omitempty,gt=0" json:"max_image_megapixel"` + AuthorizedImageExtensions []string `validate:"omitempty" json:"authorized_image_extensions"` + AuthorizedAttachmentExtensions []string `validate:"omitempty" json:"authorized_attachment_extensions"` +} + +// SiteTagsReq site tags settings request +type SiteTagsReq struct { + ReservedTags []*SiteWriteTag `validate:"omitempty,dive" json:"reserved_tags"` + RecommendTags []*SiteWriteTag `validate:"omitempty,dive" json:"recommend_tags"` + MinimumTags int `validate:"omitempty,gte=0,lte=5" json:"min_tags"` + RequiredTag bool `validate:"omitempty" json:"required_tag"` + UserID string `json:"-"` +} + +func (s *SiteAdvancedResp) GetMaxImageSize() int64 { if s.MaxImageSize <= 0 { return constant.DefaultMaxImageSize } return int64(s.MaxImageSize) * 1024 * 1024 } -func (s *SiteWriteResp) GetMaxAttachmentSize() int64 { +func (s *SiteAdvancedResp) GetMaxAttachmentSize() int64 { if s.MaxAttachmentSize <= 0 { return constant.DefaultMaxAttachmentSize } return int64(s.MaxAttachmentSize) * 1024 * 1024 } -func (s *SiteWriteResp) GetMaxImageMegapixel() int { +func (s *SiteAdvancedResp) GetMaxImageMegapixel() int { if s.MaxImageMegapixel <= 0 { return constant.DefaultMaxImageMegapixel } @@ -238,8 +264,9 @@ type ThemeOption struct { Value string `json:"value"` } -// SiteWriteResp site write response -type SiteWriteResp SiteWriteReq +type SiteQuestionsResp SiteQuestionsReq +type SiteAdvancedResp SiteAdvancedReq +type SiteTagsResp SiteTagsReq // SiteLegalResp site write response type SiteLegalResp SiteLegalReq @@ -262,7 +289,9 @@ type SiteInfoResp struct { CustomCssHtml *SiteCustomCssHTMLResp `json:"custom_css_html"` SiteSeo *SiteSeoResp `json:"site_seo"` SiteUsers *SiteUsersResp `json:"site_users"` - Write *SiteWriteResp `json:"site_write"` + Advanced *SiteAdvancedResp `json:"site_advanced"` + Questions *SiteQuestionsResp `json:"site_questions"` + Tags *SiteTagsResp `json:"site_tags"` Legal *SiteLegalSimpleResp `json:"site_legal"` Version string `json:"version"` Revision string `json:"revision"` diff --git a/internal/service/mock/siteinfo_repo_mock.go b/internal/service/mock/siteinfo_repo_mock.go index 0a1b31e84..b809d8aef 100644 --- a/internal/service/mock/siteinfo_repo_mock.go +++ b/internal/service/mock/siteinfo_repo_mock.go @@ -22,7 +22,6 @@ import ( type MockSiteInfoRepo struct { ctrl *gomock.Controller recorder *MockSiteInfoRepoMockRecorder - isgomock struct{} } // MockSiteInfoRepoMockRecorder is the mock recorder for MockSiteInfoRepo. @@ -53,7 +52,7 @@ func (m *MockSiteInfoRepo) GetByType(ctx context.Context, siteType string) (*ent } // GetByType indicates an expected call of GetByType. -func (mr *MockSiteInfoRepoMockRecorder) GetByType(ctx, siteType any) *gomock.Call { +func (mr *MockSiteInfoRepoMockRecorder) GetByType(ctx, siteType interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByType", reflect.TypeOf((*MockSiteInfoRepo)(nil).GetByType), ctx, siteType) } @@ -68,7 +67,7 @@ func (m *MockSiteInfoRepo) IsBrandingFileUsed(ctx context.Context, filePath stri } // IsBrandingFileUsed indicates an expected call of IsBrandingFileUsed. -func (mr *MockSiteInfoRepoMockRecorder) IsBrandingFileUsed(ctx, filePath any) *gomock.Call { +func (mr *MockSiteInfoRepoMockRecorder) IsBrandingFileUsed(ctx, filePath interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsBrandingFileUsed", reflect.TypeOf((*MockSiteInfoRepo)(nil).IsBrandingFileUsed), ctx, filePath) } @@ -82,7 +81,7 @@ func (m *MockSiteInfoRepo) SaveByType(ctx context.Context, siteType string, data } // SaveByType indicates an expected call of SaveByType. -func (mr *MockSiteInfoRepoMockRecorder) SaveByType(ctx, siteType, data any) *gomock.Call { +func (mr *MockSiteInfoRepoMockRecorder) SaveByType(ctx, siteType, data interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveByType", reflect.TypeOf((*MockSiteInfoRepo)(nil).SaveByType), ctx, siteType, data) } @@ -91,7 +90,6 @@ func (mr *MockSiteInfoRepoMockRecorder) SaveByType(ctx, siteType, data any) *gom type MockSiteInfoCommonService struct { ctrl *gomock.Controller recorder *MockSiteInfoCommonServiceMockRecorder - isgomock struct{} } // MockSiteInfoCommonServiceMockRecorder is the mock recorder for MockSiteInfoCommonService. @@ -120,7 +118,7 @@ func (m *MockSiteInfoCommonService) FormatAvatar(ctx context.Context, originalAv } // FormatAvatar indicates an expected call of FormatAvatar. -func (mr *MockSiteInfoCommonServiceMockRecorder) FormatAvatar(ctx, originalAvatarData, email, userStatus any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) FormatAvatar(ctx, originalAvatarData, email, userStatus interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FormatAvatar", reflect.TypeOf((*MockSiteInfoCommonService)(nil).FormatAvatar), ctx, originalAvatarData, email, userStatus) } @@ -134,11 +132,26 @@ func (m *MockSiteInfoCommonService) FormatListAvatar(ctx context.Context, userLi } // FormatListAvatar indicates an expected call of FormatListAvatar. -func (mr *MockSiteInfoCommonServiceMockRecorder) FormatListAvatar(ctx, userList any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) FormatListAvatar(ctx, userList interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FormatListAvatar", reflect.TypeOf((*MockSiteInfoCommonService)(nil).FormatListAvatar), ctx, userList) } +// GetSiteAdvanced mocks base method. +func (m *MockSiteInfoCommonService) GetSiteAdvanced(ctx context.Context) (*schema.SiteAdvancedResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteAdvanced", ctx) + ret0, _ := ret[0].(*schema.SiteAdvancedResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteAdvanced indicates an expected call of GetSiteAdvanced. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteAdvanced(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteAdvanced", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteAdvanced), ctx) +} + // GetSiteBranding mocks base method. func (m *MockSiteInfoCommonService) GetSiteBranding(ctx context.Context) (*schema.SiteBrandingResp, error) { m.ctrl.T.Helper() @@ -149,7 +162,7 @@ func (m *MockSiteInfoCommonService) GetSiteBranding(ctx context.Context) (*schem } // GetSiteBranding indicates an expected call of GetSiteBranding. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteBranding(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteBranding(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteBranding", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteBranding), ctx) } @@ -164,7 +177,7 @@ func (m *MockSiteInfoCommonService) GetSiteCustomCssHTML(ctx context.Context) (* } // GetSiteCustomCssHTML indicates an expected call of GetSiteCustomCssHTML. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteCustomCssHTML(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteCustomCssHTML(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteCustomCssHTML", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteCustomCssHTML), ctx) } @@ -179,7 +192,7 @@ func (m *MockSiteInfoCommonService) GetSiteGeneral(ctx context.Context) (*schema } // GetSiteGeneral indicates an expected call of GetSiteGeneral. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteGeneral(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteGeneral(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteGeneral", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteGeneral), ctx) } @@ -193,7 +206,7 @@ func (m *MockSiteInfoCommonService) GetSiteInfoByType(ctx context.Context, siteT } // GetSiteInfoByType indicates an expected call of GetSiteInfoByType. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInfoByType(ctx, siteType, resp any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInfoByType(ctx, siteType, resp interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteInfoByType", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteInfoByType), ctx, siteType, resp) } @@ -208,7 +221,7 @@ func (m *MockSiteInfoCommonService) GetSiteInterface(ctx context.Context) (*sche } // GetSiteInterface indicates an expected call of GetSiteInterface. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInterface(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInterface(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteInterface", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteInterface), ctx) } @@ -223,7 +236,7 @@ func (m *MockSiteInfoCommonService) GetSiteLegal(ctx context.Context) (*schema.S } // GetSiteLegal indicates an expected call of GetSiteLegal. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLegal(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLegal(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLegal", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLegal), ctx) } @@ -238,11 +251,26 @@ func (m *MockSiteInfoCommonService) GetSiteLogin(ctx context.Context) (*schema.S } // GetSiteLogin indicates an expected call of GetSiteLogin. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLogin", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLogin), ctx) } +// GetSiteQuestion mocks base method. +func (m *MockSiteInfoCommonService) GetSiteQuestion(ctx context.Context) (*schema.SiteQuestionsResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteQuestion", ctx) + ret0, _ := ret[0].(*schema.SiteQuestionsResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteQuestion indicates an expected call of GetSiteQuestion. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteQuestion(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteQuestion", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteQuestion), ctx) +} + // GetSiteSeo mocks base method. func (m *MockSiteInfoCommonService) GetSiteSeo(ctx context.Context) (*schema.SiteSeoResp, error) { m.ctrl.T.Helper() @@ -253,11 +281,26 @@ func (m *MockSiteInfoCommonService) GetSiteSeo(ctx context.Context) (*schema.Sit } // GetSiteSeo indicates an expected call of GetSiteSeo. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteSeo(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteSeo(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteSeo", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteSeo), ctx) } +// GetSiteTag mocks base method. +func (m *MockSiteInfoCommonService) GetSiteTag(ctx context.Context) (*schema.SiteTagsResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteTag", ctx) + ret0, _ := ret[0].(*schema.SiteTagsResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteTag indicates an expected call of GetSiteTag. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteTag(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteTag", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteTag), ctx) +} + // GetSiteTheme mocks base method. func (m *MockSiteInfoCommonService) GetSiteTheme(ctx context.Context) (*schema.SiteThemeResp, error) { m.ctrl.T.Helper() @@ -268,7 +311,7 @@ func (m *MockSiteInfoCommonService) GetSiteTheme(ctx context.Context) (*schema.S } // GetSiteTheme indicates an expected call of GetSiteTheme. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteTheme(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteTheme(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteTheme", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteTheme), ctx) } @@ -283,7 +326,7 @@ func (m *MockSiteInfoCommonService) GetSiteUsers(ctx context.Context) (*schema.S } // GetSiteUsers indicates an expected call of GetSiteUsers. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsers(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsers(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteUsers", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteUsers), ctx) } @@ -298,7 +341,7 @@ func (m *MockSiteInfoCommonService) GetSiteWrite(ctx context.Context) (*schema.S } // GetSiteWrite indicates an expected call of GetSiteWrite. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteWrite(ctx any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteWrite(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteWrite", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteWrite), ctx) } @@ -312,7 +355,7 @@ func (m *MockSiteInfoCommonService) IsBrandingFileUsed(ctx context.Context, file } // IsBrandingFileUsed indicates an expected call of IsBrandingFileUsed. -func (mr *MockSiteInfoCommonServiceMockRecorder) IsBrandingFileUsed(ctx, filePath any) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) IsBrandingFileUsed(ctx, filePath interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsBrandingFileUsed", reflect.TypeOf((*MockSiteInfoCommonService)(nil).IsBrandingFileUsed), ctx, filePath) } diff --git a/internal/service/question_common/question.go b/internal/service/question_common/question.go index 557a5db15..3a7306342 100644 --- a/internal/service/question_common/question.go +++ b/internal/service/question_common/question.go @@ -900,7 +900,7 @@ func (qs *QuestionCommon) tryToGetQuestionIDFromMsg(ctx context.Context, closeMs } func (qs *QuestionCommon) GetMinimumContentLength(ctx context.Context) (int, error) { - siteInfo, err := qs.siteInfoService.GetSiteWrite(ctx) + siteInfo, err := qs.siteInfoService.GetSiteQuestion(ctx) if err != nil { return 6, err } diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index 1eb187067..480606633 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -103,17 +103,14 @@ func (s *SiteInfoService) GetSiteUsers(ctx context.Context) (resp *schema.SiteUs return s.siteInfoCommonService.GetSiteUsers(ctx) } -// GetSiteWrite get site info write -func (s *SiteInfoService) GetSiteWrite(ctx context.Context) (resp *schema.SiteWriteResp, err error) { - resp = &schema.SiteWriteResp{} - siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeWrite) +// GetSiteTag get site info write +func (s *SiteInfoService) GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error) { + resp = &schema.SiteTagsResp{} + _, err = s.siteInfoCommonService.GetSiteTag(ctx) if err != nil { log.Error(err) return resp, nil } - if exist { - _ = json.Unmarshal([]byte(siteInfo.Content), resp) - } resp.RecommendTags, err = s.tagCommonService.GetSiteWriteRecommendTag(ctx) if err != nil { @@ -126,6 +123,16 @@ func (s *SiteInfoService) GetSiteWrite(ctx context.Context) (resp *schema.SiteWr return resp, nil } +// GetSiteQuestion get site questions settings +func (s *SiteInfoService) GetSiteQuestion(ctx context.Context) (resp *schema.SiteQuestionsResp, err error) { + return s.siteInfoCommonService.GetSiteQuestion(ctx) +} + +// GetSiteAdvanced get site advanced settings +func (s *SiteInfoService) GetSiteAdvanced(ctx context.Context) (resp *schema.SiteAdvancedResp, err error) { + return s.siteInfoCommonService.GetSiteAdvanced(ctx) +} + // GetSiteLegal get site legal info func (s *SiteInfoService) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) { return s.siteInfoCommonService.GetSiteLegal(ctx) @@ -182,8 +189,30 @@ func (s *SiteInfoService) SaveSiteBranding(ctx context.Context, req *schema.Site return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeBranding, data) } -// SaveSiteWrite save site configuration about write -func (s *SiteInfoService) SaveSiteWrite(ctx context.Context, req *schema.SiteWriteReq) (resp any, err error) { +// SaveSiteAdvanced save site advanced configuration +func (s *SiteInfoService) SaveSiteAdvanced(ctx context.Context, req *schema.SiteAdvancedReq) (resp any, err error) { + content, _ := json.Marshal(req) + data := &entity.SiteInfo{ + Type: constant.SiteTypeAdvanced, + Content: string(content), + Status: 1, + } + return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeAdvanced, data) +} + +// SaveSiteQuestions save site questions configuration +func (s *SiteInfoService) SaveSiteQuestions(ctx context.Context, req *schema.SiteQuestionsReq) (resp any, err error) { + content, _ := json.Marshal(req) + data := &entity.SiteInfo{ + Type: constant.SiteTypeQuestions, + Content: string(content), + Status: 1, + } + return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeQuestions, data) +} + +// SaveSiteTags save site tags configuration +func (s *SiteInfoService) SaveSiteTags(ctx context.Context, req *schema.SiteTagsReq) (resp any, err error) { recommendTags, reservedTags := make([]string, 0), make([]string, 0) recommendTagMapping, reservedTagMapping := make(map[string]bool), make(map[string]bool) for _, tag := range req.ReservedTags { @@ -210,11 +239,11 @@ func (s *SiteInfoService) SaveSiteWrite(ctx context.Context, req *schema.SiteWri content, _ := json.Marshal(req) data := &entity.SiteInfo{ - Type: constant.SiteTypeWrite, + Type: constant.SiteTypeTags, Content: string(content), Status: 1, } - return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeWrite, data) + return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeTags, data) } // SaveSiteLegal save site legal configuration diff --git a/internal/service/siteinfo_common/siteinfo_service.go b/internal/service/siteinfo_common/siteinfo_service.go index 8a4b13669..5c1c790ad 100644 --- a/internal/service/siteinfo_common/siteinfo_service.go +++ b/internal/service/siteinfo_common/siteinfo_service.go @@ -51,6 +51,9 @@ type SiteInfoCommonService interface { FormatAvatar(ctx context.Context, originalAvatarData, email string, userStatus int) *schema.AvatarInfo FormatListAvatar(ctx context.Context, userList []*entity.User) (userID2AvatarMapping map[string]*schema.AvatarInfo) GetSiteWrite(ctx context.Context) (resp *schema.SiteWriteResp, err error) + GetSiteAdvanced(ctx context.Context) (resp *schema.SiteAdvancedResp, err error) + GetSiteQuestion(ctx context.Context) (resp *schema.SiteQuestionsResp, err error) + GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) GetSiteLogin(ctx context.Context) (resp *schema.SiteLoginResp, err error) GetSiteCustomCssHTML(ctx context.Context) (resp *schema.SiteCustomCssHTMLResp, err error) @@ -167,6 +170,33 @@ func (s *siteInfoCommonService) GetSiteWrite(ctx context.Context) (resp *schema. return resp, nil } +// GetSiteAdvanced get site info advanced +func (s *siteInfoCommonService) GetSiteAdvanced(ctx context.Context) (resp *schema.SiteAdvancedResp, err error) { + resp = &schema.SiteAdvancedResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeAdvanced, resp); err != nil { + return nil, err + } + return resp, nil +} + +// GetSiteQuestion get site info question +func (s *siteInfoCommonService) GetSiteQuestion(ctx context.Context) (resp *schema.SiteQuestionsResp, err error) { + resp = &schema.SiteQuestionsResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeQuestions, resp); err != nil { + return nil, err + } + return resp, nil +} + +// GetSiteTag get site info tag +func (s *siteInfoCommonService) GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error) { + resp = &schema.SiteTagsResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeTags, resp); err != nil { + return nil, err + } + return resp, nil +} + // GetSiteLegal get site info write func (s *siteInfoCommonService) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) { resp = &schema.SiteLegalResp{} diff --git a/internal/service/tag_common/tag_common.go b/internal/service/tag_common/tag_common.go index 9ca8e100f..0da9f6fd5 100644 --- a/internal/service/tag_common/tag_common.go +++ b/internal/service/tag_common/tag_common.go @@ -270,7 +270,7 @@ func (ts *TagCommonService) GetTagListByNames(ctx context.Context, tagNames []st } func (ts *TagCommonService) ExistRecommend(ctx context.Context, tags []*schema.TagItem) (bool, error) { - taginfo, err := ts.siteInfoService.GetSiteWrite(ctx) + taginfo, err := ts.siteInfoService.GetSiteTag(ctx) if err != nil { return false, err } @@ -295,7 +295,7 @@ func (ts *TagCommonService) ExistRecommend(ctx context.Context, tags []*schema.T } func (ts *TagCommonService) GetMinimumTags(ctx context.Context) (int, error) { - siteInfo, err := ts.siteInfoService.GetSiteWrite(ctx) + siteInfo, err := ts.siteInfoService.GetSiteTag(ctx) if err != nil { return 1, err } @@ -469,7 +469,7 @@ func (ts *TagCommonService) TagsFormatRecommendAndReserved(ctx context.Context, if len(tagList) == 0 { return } - tagConfig, err := ts.siteInfoService.GetSiteWrite(ctx) + tagConfig, err := ts.siteInfoService.GetSiteTag(ctx) if err != nil { log.Error(err) return @@ -485,7 +485,7 @@ func (ts *TagCommonService) tagFormatRecommendAndReserved(ctx context.Context, t if tag == nil { return } - tagConfig, err := ts.siteInfoService.GetSiteWrite(ctx) + tagConfig, err := ts.siteInfoService.GetSiteTag(ctx) if err != nil { log.Error(err) return diff --git a/internal/service/uploader/upload.go b/internal/service/uploader/upload.go index 8dea746ce..58f808468 100644 --- a/internal/service/uploader/upload.go +++ b/internal/service/uploader/upload.go @@ -109,12 +109,12 @@ func (us *uploaderService) UploadAvatarFile(ctx *gin.Context, userID string) (ur return url, nil } - siteWrite, err := us.siteInfoService.GetSiteWrite(ctx) + siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx) if err != nil { return "", err } - ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteWrite.GetMaxImageSize()) + ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteAdvanced.GetMaxImageSize()) file, fileHeader, err := ctx.Request.FormFile("file") if err != nil { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) @@ -201,12 +201,12 @@ func (us *uploaderService) UploadPostFile(ctx *gin.Context, userID string) ( return url, nil } - siteWrite, err := us.siteInfoService.GetSiteWrite(ctx) + siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx) if err != nil { return "", err } - ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteWrite.GetMaxImageSize()) + ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteAdvanced.GetMaxImageSize()) file, fileHeader, err := ctx.Request.FormFile("file") if err != nil { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) @@ -214,7 +214,7 @@ func (us *uploaderService) UploadPostFile(ctx *gin.Context, userID string) ( defer func() { _ = file.Close() }() - if checker.IsUnAuthorizedExtension(fileHeader.Filename, siteWrite.AuthorizedImageExtensions) { + if checker.IsUnAuthorizedExtension(fileHeader.Filename, siteAdvanced.AuthorizedImageExtensions) { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) } @@ -239,7 +239,7 @@ func (us *uploaderService) UploadPostAttachment(ctx *gin.Context, userID string) return url, nil } - resp, err := us.siteInfoService.GetSiteWrite(ctx) + resp, err := us.siteInfoService.GetSiteAdvanced(ctx) if err != nil { return "", err } @@ -277,12 +277,12 @@ func (us *uploaderService) UploadBrandingFile(ctx *gin.Context, userID string) ( return url, nil } - siteWrite, err := us.siteInfoService.GetSiteWrite(ctx) + siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx) if err != nil { return "", err } - ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteWrite.GetMaxImageSize()) + ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, siteAdvanced.GetMaxImageSize()) file, fileHeader, err := ctx.Request.FormFile("file") if err != nil { return "", errors.BadRequest(reason.RequestFormatError).WithError(err) @@ -311,7 +311,7 @@ func (us *uploaderService) uploadImageFile(ctx *gin.Context, file *multipart.Fil if err != nil { return "", err } - siteWrite, err := us.siteInfoService.GetSiteWrite(ctx) + siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx) if err != nil { return "", err } @@ -328,7 +328,7 @@ func (us *uploaderService) uploadImageFile(ctx *gin.Context, file *multipart.Fil _ = src.Close() }() - if !checker.DecodeAndCheckImageFile(filePath, siteWrite.GetMaxImageMegapixel()) { + if !checker.DecodeAndCheckImageFile(filePath, siteAdvanced.GetMaxImageMegapixel()) { return "", errors.BadRequest(reason.UploadFileUnsupportedFileFormat) } @@ -364,17 +364,17 @@ func (us *uploaderService) uploadAttachmentFile(ctx *gin.Context, file *multipar func (us *uploaderService) tryToUploadByPlugin(ctx *gin.Context, source plugin.UploadSource) ( url string, err error) { - siteWrite, err := us.siteInfoService.GetSiteWrite(ctx) + siteAdvanced, err := us.siteInfoService.GetSiteAdvanced(ctx) if err != nil { return "", err } cond := plugin.UploadFileCondition{ Source: source, - MaxImageSize: siteWrite.MaxImageSize, - MaxAttachmentSize: siteWrite.MaxAttachmentSize, - MaxImageMegapixel: siteWrite.MaxImageMegapixel, - AuthorizedImageExtensions: siteWrite.AuthorizedImageExtensions, - AuthorizedAttachmentExtensions: siteWrite.AuthorizedAttachmentExtensions, + MaxImageSize: siteAdvanced.MaxImageSize, + MaxAttachmentSize: siteAdvanced.MaxAttachmentSize, + MaxImageMegapixel: siteAdvanced.MaxImageMegapixel, + AuthorizedImageExtensions: siteAdvanced.AuthorizedImageExtensions, + AuthorizedAttachmentExtensions: siteAdvanced.AuthorizedAttachmentExtensions, } _ = plugin.CallStorage(func(fn plugin.Storage) error { resp := fn.UploadFile(ctx, cond) From 9efa9471bd841ddcad2f5e97bf5def12ad96756e Mon Sep 17 00:00:00 2001 From: kumfo Date: Tue, 20 Jan 2026 15:32:45 +0800 Subject: [PATCH 67/92] feat(menu): update admin menu settings to include questions, tags, and advanced options --- docs/docs.go | 438 ++++++++++++++++++++++++++++++++-------------- docs/swagger.json | 438 ++++++++++++++++++++++++++++++++-------------- docs/swagger.yaml | 298 ++++++++++++++++++++----------- 3 files changed, 804 insertions(+), 370 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index fc4d9909e..73d85436c 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -856,6 +856,77 @@ const docTemplate = `{ } } }, + "/answer/admin/api/siteinfo/advanced": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site advanced setting", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site advanced setting", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteAdvancedResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site advanced info", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site advanced info", + "parameters": [ + { + "description": "advanced settings", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteAdvancedReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/branding": { "get": { "security": [ @@ -1282,6 +1353,77 @@ const docTemplate = `{ } } }, + "/answer/admin/api/siteinfo/question": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site questions setting", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site questions setting", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteQuestionsResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site question settings", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site question settings", + "parameters": [ + { + "description": "questions settings", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteQuestionsReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/seo": { "get": { "security": [ @@ -1353,21 +1495,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/theme": { + "/answer/admin/api/siteinfo/tag": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site info theme config", + "description": "get site tags setting", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site info theme config", + "summary": "get site tags setting", "responses": { "200": { "description": "OK", @@ -1380,7 +1522,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteThemeResp" + "$ref": "#/definitions/schema.SiteTagsResp" } } } @@ -1395,22 +1537,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site custom css html config", + "description": "update site tag settings", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site custom css html config", + "summary": "update site tag settings", "parameters": [ { - "description": "login info", + "description": "tags settings", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteThemeReq" + "$ref": "#/definitions/schema.SiteTagsReq" } } ], @@ -1424,21 +1566,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/users": { + "/answer/admin/api/siteinfo/theme": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site user config", + "description": "get site info theme config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site user config", + "summary": "get site info theme config", "responses": { "200": { "description": "OK", @@ -1451,7 +1593,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteUsersResp" + "$ref": "#/definitions/schema.SiteThemeResp" } } } @@ -1466,22 +1608,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site info config about users", + "description": "update site custom css html config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site info config about users", + "summary": "update site custom css html config", "parameters": [ { - "description": "users info", + "description": "login info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteUsersReq" + "$ref": "#/definitions/schema.SiteThemeReq" } } ], @@ -1495,21 +1637,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/write": { + "/answer/admin/api/siteinfo/users": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site interface", + "description": "get site user config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site interface", + "summary": "get site user config", "responses": { "200": { "description": "OK", @@ -1522,7 +1664,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteWriteResp" + "$ref": "#/definitions/schema.SiteUsersResp" } } } @@ -1537,22 +1679,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site write info", + "description": "update site info config about users", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site write info", + "summary": "update site info config about users", "parameters": [ { - "description": "write info", + "description": "users info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteWriteReq" + "$ref": "#/definitions/schema.SiteUsersReq" } } ], @@ -10478,6 +10620,58 @@ const docTemplate = `{ } } }, + "schema.SiteAdvancedReq": { + "type": "object", + "properties": { + "authorized_attachment_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "authorized_image_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "max_attachment_size": { + "type": "integer" + }, + "max_image_megapixel": { + "type": "integer" + }, + "max_image_size": { + "type": "integer" + } + } + }, + "schema.SiteAdvancedResp": { + "type": "object", + "properties": { + "authorized_attachment_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "authorized_image_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "max_attachment_size": { + "type": "integer" + }, + "max_image_megapixel": { + "type": "integer" + }, + "max_image_size": { + "type": "integer" + } + } + }, "schema.SiteBrandingReq": { "type": "object", "properties": { @@ -10657,18 +10851,24 @@ const docTemplate = `{ "revision": { "type": "string" }, + "site_advanced": { + "$ref": "#/definitions/schema.SiteAdvancedResp" + }, "site_legal": { "$ref": "#/definitions/schema.SiteLegalSimpleResp" }, + "site_questions": { + "$ref": "#/definitions/schema.SiteQuestionsResp" + }, "site_seo": { "$ref": "#/definitions/schema.SiteSeoResp" }, + "site_tags": { + "$ref": "#/definitions/schema.SiteTagsResp" + }, "site_users": { "$ref": "#/definitions/schema.SiteUsersResp" }, - "site_write": { - "$ref": "#/definitions/schema.SiteWriteResp" - }, "theme": { "$ref": "#/definitions/schema.SiteThemeResp" }, @@ -10848,6 +11048,32 @@ const docTemplate = `{ } } }, + "schema.SiteQuestionsReq": { + "type": "object", + "properties": { + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "restrict_answer": { + "type": "boolean" + } + } + }, + "schema.SiteQuestionsResp": { + "type": "object", + "properties": { + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "restrict_answer": { + "type": "boolean" + } + } + }, "schema.SiteSeoReq": { "type": "object", "required": [ @@ -10882,6 +11108,56 @@ const docTemplate = `{ } } }, + "schema.SiteTagsReq": { + "type": "object", + "properties": { + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, + "recommend_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + }, + "required_tag": { + "type": "boolean" + }, + "reserved_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + } + } + }, + "schema.SiteTagsResp": { + "type": "object", + "properties": { + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, + "recommend_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + }, + "required_tag": { + "type": "boolean" + }, + "reserved_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + } + } + }, "schema.SiteThemeReq": { "type": "object", "required": [ @@ -10995,114 +11271,6 @@ const docTemplate = `{ } } }, - "schema.SiteWriteReq": { - "type": "object", - "properties": { - "authorized_attachment_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "authorized_image_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "max_attachment_size": { - "type": "integer" - }, - "max_image_megapixel": { - "type": "integer" - }, - "max_image_size": { - "type": "integer" - }, - "min_content": { - "type": "integer", - "maximum": 65535, - "minimum": 0 - }, - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, - "recommend_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "required_tag": { - "type": "boolean" - }, - "reserved_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "restrict_answer": { - "type": "boolean" - } - } - }, - "schema.SiteWriteResp": { - "type": "object", - "properties": { - "authorized_attachment_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "authorized_image_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "max_attachment_size": { - "type": "integer" - }, - "max_image_megapixel": { - "type": "integer" - }, - "max_image_size": { - "type": "integer" - }, - "min_content": { - "type": "integer", - "maximum": 65535, - "minimum": 0 - }, - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, - "recommend_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "required_tag": { - "type": "boolean" - }, - "reserved_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "restrict_answer": { - "type": "boolean" - } - } - }, "schema.SiteWriteTag": { "type": "object", "required": [ diff --git a/docs/swagger.json b/docs/swagger.json index e0f6378e4..6dbecc50a 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -848,6 +848,77 @@ } } }, + "/answer/admin/api/siteinfo/advanced": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site advanced setting", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site advanced setting", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteAdvancedResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site advanced info", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site advanced info", + "parameters": [ + { + "description": "advanced settings", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteAdvancedReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/branding": { "get": { "security": [ @@ -1274,6 +1345,77 @@ } } }, + "/answer/admin/api/siteinfo/question": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site questions setting", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site questions setting", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteQuestionsResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site question settings", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site question settings", + "parameters": [ + { + "description": "questions settings", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteQuestionsReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/seo": { "get": { "security": [ @@ -1345,21 +1487,21 @@ } } }, - "/answer/admin/api/siteinfo/theme": { + "/answer/admin/api/siteinfo/tag": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site info theme config", + "description": "get site tags setting", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site info theme config", + "summary": "get site tags setting", "responses": { "200": { "description": "OK", @@ -1372,7 +1514,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteThemeResp" + "$ref": "#/definitions/schema.SiteTagsResp" } } } @@ -1387,22 +1529,22 @@ "ApiKeyAuth": [] } ], - "description": "update site custom css html config", + "description": "update site tag settings", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site custom css html config", + "summary": "update site tag settings", "parameters": [ { - "description": "login info", + "description": "tags settings", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteThemeReq" + "$ref": "#/definitions/schema.SiteTagsReq" } } ], @@ -1416,21 +1558,21 @@ } } }, - "/answer/admin/api/siteinfo/users": { + "/answer/admin/api/siteinfo/theme": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site user config", + "description": "get site info theme config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site user config", + "summary": "get site info theme config", "responses": { "200": { "description": "OK", @@ -1443,7 +1585,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteUsersResp" + "$ref": "#/definitions/schema.SiteThemeResp" } } } @@ -1458,22 +1600,22 @@ "ApiKeyAuth": [] } ], - "description": "update site info config about users", + "description": "update site custom css html config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site info config about users", + "summary": "update site custom css html config", "parameters": [ { - "description": "users info", + "description": "login info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteUsersReq" + "$ref": "#/definitions/schema.SiteThemeReq" } } ], @@ -1487,21 +1629,21 @@ } } }, - "/answer/admin/api/siteinfo/write": { + "/answer/admin/api/siteinfo/users": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site interface", + "description": "get site user config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site interface", + "summary": "get site user config", "responses": { "200": { "description": "OK", @@ -1514,7 +1656,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteWriteResp" + "$ref": "#/definitions/schema.SiteUsersResp" } } } @@ -1529,22 +1671,22 @@ "ApiKeyAuth": [] } ], - "description": "update site write info", + "description": "update site info config about users", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site write info", + "summary": "update site info config about users", "parameters": [ { - "description": "write info", + "description": "users info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteWriteReq" + "$ref": "#/definitions/schema.SiteUsersReq" } } ], @@ -10470,6 +10612,58 @@ } } }, + "schema.SiteAdvancedReq": { + "type": "object", + "properties": { + "authorized_attachment_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "authorized_image_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "max_attachment_size": { + "type": "integer" + }, + "max_image_megapixel": { + "type": "integer" + }, + "max_image_size": { + "type": "integer" + } + } + }, + "schema.SiteAdvancedResp": { + "type": "object", + "properties": { + "authorized_attachment_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "authorized_image_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "max_attachment_size": { + "type": "integer" + }, + "max_image_megapixel": { + "type": "integer" + }, + "max_image_size": { + "type": "integer" + } + } + }, "schema.SiteBrandingReq": { "type": "object", "properties": { @@ -10649,18 +10843,24 @@ "revision": { "type": "string" }, + "site_advanced": { + "$ref": "#/definitions/schema.SiteAdvancedResp" + }, "site_legal": { "$ref": "#/definitions/schema.SiteLegalSimpleResp" }, + "site_questions": { + "$ref": "#/definitions/schema.SiteQuestionsResp" + }, "site_seo": { "$ref": "#/definitions/schema.SiteSeoResp" }, + "site_tags": { + "$ref": "#/definitions/schema.SiteTagsResp" + }, "site_users": { "$ref": "#/definitions/schema.SiteUsersResp" }, - "site_write": { - "$ref": "#/definitions/schema.SiteWriteResp" - }, "theme": { "$ref": "#/definitions/schema.SiteThemeResp" }, @@ -10840,6 +11040,32 @@ } } }, + "schema.SiteQuestionsReq": { + "type": "object", + "properties": { + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "restrict_answer": { + "type": "boolean" + } + } + }, + "schema.SiteQuestionsResp": { + "type": "object", + "properties": { + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "restrict_answer": { + "type": "boolean" + } + } + }, "schema.SiteSeoReq": { "type": "object", "required": [ @@ -10874,6 +11100,56 @@ } } }, + "schema.SiteTagsReq": { + "type": "object", + "properties": { + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, + "recommend_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + }, + "required_tag": { + "type": "boolean" + }, + "reserved_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + } + } + }, + "schema.SiteTagsResp": { + "type": "object", + "properties": { + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, + "recommend_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + }, + "required_tag": { + "type": "boolean" + }, + "reserved_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + } + } + }, "schema.SiteThemeReq": { "type": "object", "required": [ @@ -10987,114 +11263,6 @@ } } }, - "schema.SiteWriteReq": { - "type": "object", - "properties": { - "authorized_attachment_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "authorized_image_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "max_attachment_size": { - "type": "integer" - }, - "max_image_megapixel": { - "type": "integer" - }, - "max_image_size": { - "type": "integer" - }, - "min_content": { - "type": "integer", - "maximum": 65535, - "minimum": 0 - }, - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, - "recommend_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "required_tag": { - "type": "boolean" - }, - "reserved_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "restrict_answer": { - "type": "boolean" - } - } - }, - "schema.SiteWriteResp": { - "type": "object", - "properties": { - "authorized_attachment_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "authorized_image_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "max_attachment_size": { - "type": "integer" - }, - "max_image_megapixel": { - "type": "integer" - }, - "max_image_size": { - "type": "integer" - }, - "min_content": { - "type": "integer", - "maximum": 65535, - "minimum": 0 - }, - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, - "recommend_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "required_tag": { - "type": "boolean" - }, - "reserved_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "restrict_answer": { - "type": "boolean" - } - } - }, "schema.SiteWriteTag": { "type": "object", "required": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 42df5cbf1..f4107cd6b 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2055,6 +2055,40 @@ definitions: required: - user_id type: object + schema.SiteAdvancedReq: + properties: + authorized_attachment_extensions: + items: + type: string + type: array + authorized_image_extensions: + items: + type: string + type: array + max_attachment_size: + type: integer + max_image_megapixel: + type: integer + max_image_size: + type: integer + type: object + schema.SiteAdvancedResp: + properties: + authorized_attachment_extensions: + items: + type: string + type: array + authorized_image_extensions: + items: + type: string + type: array + max_attachment_size: + type: integer + max_image_megapixel: + type: integer + max_image_size: + type: integer + type: object schema.SiteBrandingReq: properties: favicon: @@ -2183,14 +2217,18 @@ definitions: $ref: '#/definitions/schema.SiteLoginResp' revision: type: string + site_advanced: + $ref: '#/definitions/schema.SiteAdvancedResp' site_legal: $ref: '#/definitions/schema.SiteLegalSimpleResp' + site_questions: + $ref: '#/definitions/schema.SiteQuestionsResp' site_seo: $ref: '#/definitions/schema.SiteSeoResp' + site_tags: + $ref: '#/definitions/schema.SiteTagsResp' site_users: $ref: '#/definitions/schema.SiteUsersResp' - site_write: - $ref: '#/definitions/schema.SiteWriteResp' theme: $ref: '#/definitions/schema.SiteThemeResp' version: @@ -2312,6 +2350,24 @@ definitions: login_required: type: boolean type: object + schema.SiteQuestionsReq: + properties: + min_content: + maximum: 65535 + minimum: 0 + type: integer + restrict_answer: + type: boolean + type: object + schema.SiteQuestionsResp: + properties: + min_content: + maximum: 65535 + minimum: 0 + type: integer + restrict_answer: + type: boolean + type: object schema.SiteSeoReq: properties: permalink: @@ -2336,6 +2392,40 @@ definitions: - permalink - robots type: object + schema.SiteTagsReq: + properties: + min_tags: + maximum: 5 + minimum: 0 + type: integer + recommend_tags: + items: + $ref: '#/definitions/schema.SiteWriteTag' + type: array + required_tag: + type: boolean + reserved_tags: + items: + $ref: '#/definitions/schema.SiteWriteTag' + type: array + type: object + schema.SiteTagsResp: + properties: + min_tags: + maximum: 5 + minimum: 0 + type: integer + recommend_tags: + items: + $ref: '#/definitions/schema.SiteWriteTag' + type: array + required_tag: + type: boolean + reserved_tags: + items: + $ref: '#/definitions/schema.SiteWriteTag' + type: array + type: object schema.SiteThemeReq: properties: color_scheme: @@ -2412,80 +2502,6 @@ definitions: required: - default_avatar type: object - schema.SiteWriteReq: - properties: - authorized_attachment_extensions: - items: - type: string - type: array - authorized_image_extensions: - items: - type: string - type: array - max_attachment_size: - type: integer - max_image_megapixel: - type: integer - max_image_size: - type: integer - min_content: - maximum: 65535 - minimum: 0 - type: integer - min_tags: - maximum: 5 - minimum: 0 - type: integer - recommend_tags: - items: - $ref: '#/definitions/schema.SiteWriteTag' - type: array - required_tag: - type: boolean - reserved_tags: - items: - $ref: '#/definitions/schema.SiteWriteTag' - type: array - restrict_answer: - type: boolean - type: object - schema.SiteWriteResp: - properties: - authorized_attachment_extensions: - items: - type: string - type: array - authorized_image_extensions: - items: - type: string - type: array - max_attachment_size: - type: integer - max_image_megapixel: - type: integer - max_image_size: - type: integer - min_content: - maximum: 65535 - minimum: 0 - type: integer - min_tags: - maximum: 5 - minimum: 0 - type: integer - recommend_tags: - items: - $ref: '#/definitions/schema.SiteWriteTag' - type: array - required_tag: - type: boolean - reserved_tags: - items: - $ref: '#/definitions/schema.SiteWriteTag' - type: array - restrict_answer: - type: boolean - type: object schema.SiteWriteTag: properties: display_name: @@ -3685,6 +3701,47 @@ paths: summary: update smtp config tags: - admin + /answer/admin/api/siteinfo/advanced: + get: + description: get site advanced setting + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteAdvancedResp' + type: object + security: + - ApiKeyAuth: [] + summary: get site advanced setting + tags: + - admin + put: + description: update site advanced info + parameters: + - description: advanced settings + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteAdvancedReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update site advanced info + tags: + - admin /answer/admin/api/siteinfo/branding: get: description: get site interface @@ -3931,6 +3988,47 @@ paths: summary: update site login tags: - admin + /answer/admin/api/siteinfo/question: + get: + description: get site questions setting + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteQuestionsResp' + type: object + security: + - ApiKeyAuth: [] + summary: get site questions setting + tags: + - admin + put: + description: update site question settings + parameters: + - description: questions settings + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteQuestionsReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update site question settings + tags: + - admin /answer/admin/api/siteinfo/seo: get: description: get site seo information @@ -3972,9 +4070,9 @@ paths: summary: update site seo information tags: - admin - /answer/admin/api/siteinfo/theme: + /answer/admin/api/siteinfo/tag: get: - description: get site info theme config + description: get site tags setting produces: - application/json responses: @@ -3985,22 +4083,22 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteThemeResp' + $ref: '#/definitions/schema.SiteTagsResp' type: object security: - ApiKeyAuth: [] - summary: get site info theme config + summary: get site tags setting tags: - admin put: - description: update site custom css html config + description: update site tag settings parameters: - - description: login info + - description: tags settings in: body name: data required: true schema: - $ref: '#/definitions/schema.SiteThemeReq' + $ref: '#/definitions/schema.SiteTagsReq' produces: - application/json responses: @@ -4010,12 +4108,12 @@ paths: $ref: '#/definitions/handler.RespBody' security: - ApiKeyAuth: [] - summary: update site custom css html config + summary: update site tag settings tags: - admin - /answer/admin/api/siteinfo/users: + /answer/admin/api/siteinfo/theme: get: - description: get site user config + description: get site info theme config produces: - application/json responses: @@ -4026,22 +4124,22 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteUsersResp' + $ref: '#/definitions/schema.SiteThemeResp' type: object security: - ApiKeyAuth: [] - summary: get site user config + summary: get site info theme config tags: - admin put: - description: update site info config about users + description: update site custom css html config parameters: - - description: users info + - description: login info in: body name: data required: true schema: - $ref: '#/definitions/schema.SiteUsersReq' + $ref: '#/definitions/schema.SiteThemeReq' produces: - application/json responses: @@ -4051,12 +4149,12 @@ paths: $ref: '#/definitions/handler.RespBody' security: - ApiKeyAuth: [] - summary: update site info config about users + summary: update site custom css html config tags: - admin - /answer/admin/api/siteinfo/write: + /answer/admin/api/siteinfo/users: get: - description: get site interface + description: get site user config produces: - application/json responses: @@ -4067,22 +4165,22 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteWriteResp' + $ref: '#/definitions/schema.SiteUsersResp' type: object security: - ApiKeyAuth: [] - summary: get site interface + summary: get site user config tags: - admin put: - description: update site write info + description: update site info config about users parameters: - - description: write info + - description: users info in: body name: data required: true schema: - $ref: '#/definitions/schema.SiteWriteReq' + $ref: '#/definitions/schema.SiteUsersReq' produces: - application/json responses: @@ -4092,7 +4190,7 @@ paths: $ref: '#/definitions/handler.RespBody' security: - ApiKeyAuth: [] - summary: update site write info + summary: update site info config about users tags: - admin /answer/admin/api/theme/options: From c2a0bee7dc5e6066ab20c6417fe9f89f6c553a86 Mon Sep 17 00:00:00 2001 From: kumfo Date: Wed, 21 Jan 2026 09:39:37 +0800 Subject: [PATCH 68/92] feat(siteinfo): add users settings endpoint and update interface settings structure --- docs/docs.go | 127 ++++++++++++++++-- docs/swagger.json | 127 ++++++++++++++++-- docs/swagger.yaml | 81 +++++++++-- internal/base/constant/site_type.go | 18 ++- internal/controller/siteinfo_controller.go | 5 + .../controller_admin/siteinfo_controller.go | 33 ++++- internal/migrations/v30.go | 96 +++++++++++++ internal/router/answer_api_router.go | 4 + internal/schema/siteinfo_schema.go | 58 +++++--- internal/service/siteinfo/siteinfo_service.go | 21 ++- .../siteinfo_common/siteinfo_service.go | 20 ++- 11 files changed, 516 insertions(+), 74 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index 73d85436c..b030c3d3d 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1167,7 +1167,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteInterfaceResp" + "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" } } } @@ -1708,6 +1708,77 @@ const docTemplate = `{ } } }, + "/answer/admin/api/siteinfo/users-settings": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site interface", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site interface", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteUsersSettingsResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site info users settings", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site info users settings", + "parameters": [ + { + "description": "general", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteUsersSettingsReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/theme/options": { "get": { "security": [ @@ -10843,7 +10914,7 @@ const docTemplate = `{ "$ref": "#/definitions/schema.SiteGeneralResp" }, "interface": { - "$ref": "#/definitions/schema.SiteInterfaceResp" + "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { "$ref": "#/definitions/schema.SiteLoginResp" @@ -10872,6 +10943,9 @@ const docTemplate = `{ "theme": { "$ref": "#/definitions/schema.SiteThemeResp" }, + "users_settings": { + "$ref": "#/definitions/schema.SiteUsersSettingsResp" + }, "version": { "type": "string" } @@ -10905,24 +10979,13 @@ const docTemplate = `{ } } }, - "schema.SiteInterfaceResp": { + "schema.SiteInterfaceSettingsResp": { "type": "object", "required": [ - "default_avatar", "language", "time_zone" ], "properties": { - "default_avatar": { - "type": "string", - "enum": [ - "system", - "gravatar" - ] - }, - "gravatar_base_url": { - "type": "string" - }, "language": { "type": "string", "maxLength": 128 @@ -11271,6 +11334,42 @@ const docTemplate = `{ } } }, + "schema.SiteUsersSettingsReq": { + "type": "object", + "required": [ + "default_avatar" + ], + "properties": { + "default_avatar": { + "type": "string", + "enum": [ + "system", + "gravatar" + ] + }, + "gravatar_base_url": { + "type": "string" + } + } + }, + "schema.SiteUsersSettingsResp": { + "type": "object", + "required": [ + "default_avatar" + ], + "properties": { + "default_avatar": { + "type": "string", + "enum": [ + "system", + "gravatar" + ] + }, + "gravatar_base_url": { + "type": "string" + } + } + }, "schema.SiteWriteTag": { "type": "object", "required": [ diff --git a/docs/swagger.json b/docs/swagger.json index 6dbecc50a..879302fa8 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1159,7 +1159,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteInterfaceResp" + "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" } } } @@ -1700,6 +1700,77 @@ } } }, + "/answer/admin/api/siteinfo/users-settings": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site interface", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site interface", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteUsersSettingsResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site info users settings", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site info users settings", + "parameters": [ + { + "description": "general", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteUsersSettingsReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/theme/options": { "get": { "security": [ @@ -10835,7 +10906,7 @@ "$ref": "#/definitions/schema.SiteGeneralResp" }, "interface": { - "$ref": "#/definitions/schema.SiteInterfaceResp" + "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { "$ref": "#/definitions/schema.SiteLoginResp" @@ -10864,6 +10935,9 @@ "theme": { "$ref": "#/definitions/schema.SiteThemeResp" }, + "users_settings": { + "$ref": "#/definitions/schema.SiteUsersSettingsResp" + }, "version": { "type": "string" } @@ -10897,24 +10971,13 @@ } } }, - "schema.SiteInterfaceResp": { + "schema.SiteInterfaceSettingsResp": { "type": "object", "required": [ - "default_avatar", "language", "time_zone" ], "properties": { - "default_avatar": { - "type": "string", - "enum": [ - "system", - "gravatar" - ] - }, - "gravatar_base_url": { - "type": "string" - }, "language": { "type": "string", "maxLength": 128 @@ -11263,6 +11326,42 @@ } } }, + "schema.SiteUsersSettingsReq": { + "type": "object", + "required": [ + "default_avatar" + ], + "properties": { + "default_avatar": { + "type": "string", + "enum": [ + "system", + "gravatar" + ] + }, + "gravatar_base_url": { + "type": "string" + } + } + }, + "schema.SiteUsersSettingsResp": { + "type": "object", + "required": [ + "default_avatar" + ], + "properties": { + "default_avatar": { + "type": "string", + "enum": [ + "system", + "gravatar" + ] + }, + "gravatar_base_url": { + "type": "string" + } + } + }, "schema.SiteWriteTag": { "type": "object", "required": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index f4107cd6b..ce16da75e 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2212,7 +2212,7 @@ definitions: general: $ref: '#/definitions/schema.SiteGeneralResp' interface: - $ref: '#/definitions/schema.SiteInterfaceResp' + $ref: '#/definitions/schema.SiteInterfaceSettingsResp' login: $ref: '#/definitions/schema.SiteLoginResp' revision: @@ -2231,6 +2231,8 @@ definitions: $ref: '#/definitions/schema.SiteUsersResp' theme: $ref: '#/definitions/schema.SiteThemeResp' + users_settings: + $ref: '#/definitions/schema.SiteUsersSettingsResp' version: type: string type: object @@ -2254,15 +2256,8 @@ definitions: - language - time_zone type: object - schema.SiteInterfaceResp: + schema.SiteInterfaceSettingsResp: properties: - default_avatar: - enum: - - system - - gravatar - type: string - gravatar_base_url: - type: string language: maxLength: 128 type: string @@ -2270,7 +2265,6 @@ definitions: maxLength: 128 type: string required: - - default_avatar - language - time_zone type: object @@ -2502,6 +2496,30 @@ definitions: required: - default_avatar type: object + schema.SiteUsersSettingsReq: + properties: + default_avatar: + enum: + - system + - gravatar + type: string + gravatar_base_url: + type: string + required: + - default_avatar + type: object + schema.SiteUsersSettingsResp: + properties: + default_avatar: + enum: + - system + - gravatar + type: string + gravatar_base_url: + type: string + required: + - default_avatar + type: object schema.SiteWriteTag: properties: display_name: @@ -3878,7 +3896,7 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteInterfaceResp' + $ref: '#/definitions/schema.SiteInterfaceSettingsResp' type: object security: - ApiKeyAuth: [] @@ -4193,6 +4211,47 @@ paths: summary: update site info config about users tags: - admin + /answer/admin/api/siteinfo/users-settings: + get: + description: get site interface + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteUsersSettingsResp' + type: object + security: + - ApiKeyAuth: [] + summary: get site interface + tags: + - admin + put: + description: update site info users settings + parameters: + - description: general + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteUsersSettingsReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update site info users settings + tags: + - admin /answer/admin/api/theme/options: get: description: Get theme options diff --git a/internal/base/constant/site_type.go b/internal/base/constant/site_type.go index 6106b190c..9bb4e10af 100644 --- a/internal/base/constant/site_type.go +++ b/internal/base/constant/site_type.go @@ -20,9 +20,11 @@ package constant const ( - SiteTypeGeneral = "general" - SiteTypeInterface = "interface" - SiteTypeBranding = "branding" + SiteTypeGeneral = "general" + // Deprecated: split SiteTypeInterfaceSettings and SiteTypeUsersSettings for better clarity + SiteTypeInterface = "interface" + SiteTypeBranding = "branding" + // Deprecated: use SiteTypeAdvanced, SiteTypeQuestions, and SiteTypeTags instead SiteTypeWrite = "write" SiteTypeLegal = "legal" SiteTypeSeo = "seo" @@ -31,7 +33,11 @@ const ( SiteTypeTheme = "theme" SiteTypePrivileges = "privileges" SiteTypeUsers = "users" - SiteTypeAdvanced = "advanced" - SiteTypeQuestions = "questions" - SiteTypeTags = "tags" + + SiteTypeAdvanced = "advanced" + SiteTypeQuestions = "questions" + SiteTypeTags = "tags" + + SiteTypeUsersSettings = "users_settings" + SiteTypeInterfaceSettings = "interface_settings" ) diff --git a/internal/controller/siteinfo_controller.go b/internal/controller/siteinfo_controller.go index 8035275a6..503bfeb68 100644 --- a/internal/controller/siteinfo_controller.go +++ b/internal/controller/siteinfo_controller.go @@ -60,6 +60,11 @@ func (sc *SiteInfoController) GetSiteInfo(ctx *gin.Context) { log.Error(err) } + resp.UsersSettings, err = sc.siteInfoService.GetSiteUsersSettings(ctx) + if err != nil { + log.Error(err) + } + resp.Branding, err = sc.siteInfoService.GetSiteBranding(ctx) if err != nil { log.Error(err) diff --git a/internal/controller_admin/siteinfo_controller.go b/internal/controller_admin/siteinfo_controller.go index bbab97942..056b01ae2 100644 --- a/internal/controller_admin/siteinfo_controller.go +++ b/internal/controller_admin/siteinfo_controller.go @@ -62,13 +62,26 @@ func (sc *SiteInfoController) GetGeneral(ctx *gin.Context) { // @Security ApiKeyAuth // @Tags admin // @Produce json -// @Success 200 {object} handler.RespBody{data=schema.SiteInterfaceResp} +// @Success 200 {object} handler.RespBody{data=schema.SiteInterfaceSettingsResp} // @Router /answer/admin/api/siteinfo/interface [get] func (sc *SiteInfoController) GetInterface(ctx *gin.Context) { resp, err := sc.siteInfoService.GetSiteInterface(ctx) handler.HandleResponse(ctx, err, resp) } +// GetUsersSettings get site interface +// @Summary get site interface +// @Description get site interface +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=schema.SiteUsersSettingsResp} +// @Router /answer/admin/api/siteinfo/users-settings [get] +func (sc *SiteInfoController) GetUsersSettings(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteUsersSettings(ctx) + handler.HandleResponse(ctx, err, resp) +} + // GetSiteBranding get site interface // @Summary get site interface // @Description get site interface @@ -287,6 +300,24 @@ func (sc *SiteInfoController) UpdateInterface(ctx *gin.Context) { handler.HandleResponse(ctx, err, nil) } +// UpdateUsersSettings update users settings +// @Summary update site info users settings +// @Description update site info users settings +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Param data body schema.SiteUsersSettingsReq true "general" +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/siteinfo/users-settings [put] +func (sc *SiteInfoController) UpdateUsersSettings(ctx *gin.Context) { + req := schema.SiteUsersSettingsReq{} + if handler.BindAndCheck(ctx, &req) { + return + } + err := sc.siteInfoService.SaveSiteUsersSettings(ctx, req) + handler.HandleResponse(ctx, err, nil) +} + // UpdateBranding update site branding // @Summary update site info branding // @Description update site info branding diff --git a/internal/migrations/v30.go b/internal/migrations/v30.go index 5d5d5223f..4d0f11304 100644 --- a/internal/migrations/v30.go +++ b/internal/migrations/v30.go @@ -171,3 +171,99 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { return nil } + +func splitInterfaceMenu(ctx context.Context, x *xorm.Engine) error { + var ( + siteInfo = &entity.SiteInfo{} + siteInfoInterface = &entity.SiteInfo{} + siteInfoUsers = &entity.SiteInfo{} + ) + type SiteInterface struct { + Language string `validate:"required,gt=1,lte=128" form:"language" json:"language"` + TimeZone string `validate:"required,gt=1,lte=128" form:"time_zone" json:"time_zone"` + DefaultAvatar string `validate:"required,oneof=system gravatar" json:"default_avatar"` + GravatarBaseURL string `validate:"omitempty" json:"gravatar_base_url"` + } + + exist, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeInterface}).Get(siteInfo) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + return err + } + if !exist { + return nil + } + oldSiteInterface := &SiteInterface{} + if err := json.Unmarshal([]byte(siteInfo.Content), oldSiteInterface); err != nil { + return err + } + siteUser := &schema.SiteUsersSettingsResp{ + DefaultAvatar: oldSiteInterface.DefaultAvatar, + GravatarBaseURL: oldSiteInterface.GravatarBaseURL, + } + siteInterface := &schema.SiteInterfaceResp{ + Language: oldSiteInterface.Language, + TimeZone: oldSiteInterface.TimeZone, + } + + // save settings + // save user settings + existsUsers, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeUsersSettings}).Get(siteInfoUsers) + if err != nil { + return err + } + userContent, err := json.Marshal(siteUser) + if err != nil { + return err + } + if existsUsers { + _, err = x.Context(ctx).ID(siteInfoUsers.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeUsersSettings, + Content: string(userContent), + Status: 1, + }) + if err != nil { + return err + } + } else { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ + Type: constant.SiteTypeUsersSettings, + Content: string(userContent), + Status: 1, + }) + if err != nil { + return err + } + } + + // save interface settings + existsInterface, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeInterfaceSettings}).Get(siteInfoInterface) + if err != nil { + return err + } + interfaceContent, err := json.Marshal(siteInterface) + if err != nil { + return err + } + if existsInterface { + _, err = x.Context(ctx).ID(siteInfoInterface.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeInterfaceSettings, + Content: string(interfaceContent), + Status: 1, + }) + if err != nil { + return err + } + } else { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ + Type: constant.SiteTypeInterfaceSettings, + Content: string(interfaceContent), + Status: 1, + }) + if err != nil { + return err + } + } + + return nil +} diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go index d717bc9d3..c776b44f0 100644 --- a/internal/router/answer_api_router.go +++ b/internal/router/answer_api_router.go @@ -343,8 +343,12 @@ func (a *AnswerAPIRouter) RegisterAnswerAdminAPIRouter(r *gin.RouterGroup) { // siteinfo r.GET("/siteinfo/general", a.adminSiteInfoController.GetGeneral) r.PUT("/siteinfo/general", a.adminSiteInfoController.UpdateGeneral) + r.GET("/siteinfo/interface", a.adminSiteInfoController.GetInterface) r.PUT("/siteinfo/interface", a.adminSiteInfoController.UpdateInterface) + r.GET("/siteinfo/users-settings", a.adminSiteInfoController.GetUsersSettings) + r.PUT("/siteinfo/users-settings", a.adminSiteInfoController.UpdateUsersSettings) + r.GET("/siteinfo/branding", a.adminSiteInfoController.GetSiteBranding) r.PUT("/siteinfo/branding", a.adminSiteInfoController.UpdateBranding) diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index deacf08fb..e4669561b 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -65,6 +65,21 @@ type SiteInterfaceReq struct { GravatarBaseURL string `validate:"omitempty" json:"gravatar_base_url"` } +// SiteInterfaceSettingsReq site interface settings request +type SiteInterfaceSettingsReq struct { + Language string `validate:"required,gt=1,lte=128" json:"language"` + TimeZone string `validate:"required,gt=1,lte=128" json:"time_zone"` +} + +type SiteInterfaceSettingsResp SiteInterfaceSettingsReq + +type SiteUsersSettingsReq struct { + DefaultAvatar string `validate:"required,oneof=system gravatar" json:"default_avatar"` + GravatarBaseURL string `validate:"omitempty" json:"gravatar_base_url"` +} + +type SiteUsersSettingsResp SiteUsersSettingsReq + // SiteBrandingReq site branding request type SiteBrandingReq struct { Logo string `validate:"omitempty,gt=0,lte=512" form:"logo" json:"logo"` @@ -281,27 +296,30 @@ type SiteSeoResp SiteSeoReq // SiteInfoResp get site info response type SiteInfoResp struct { - General *SiteGeneralResp `json:"general"` - Interface *SiteInterfaceResp `json:"interface"` - Branding *SiteBrandingResp `json:"branding"` - Login *SiteLoginResp `json:"login"` - Theme *SiteThemeResp `json:"theme"` - CustomCssHtml *SiteCustomCssHTMLResp `json:"custom_css_html"` - SiteSeo *SiteSeoResp `json:"site_seo"` - SiteUsers *SiteUsersResp `json:"site_users"` - Advanced *SiteAdvancedResp `json:"site_advanced"` - Questions *SiteQuestionsResp `json:"site_questions"` - Tags *SiteTagsResp `json:"site_tags"` - Legal *SiteLegalSimpleResp `json:"site_legal"` - Version string `json:"version"` - Revision string `json:"revision"` -} + General *SiteGeneralResp `json:"general"` + Interface *SiteInterfaceSettingsResp `json:"interface"` + UsersSettings *SiteUsersSettingsResp `json:"users_settings"` + Branding *SiteBrandingResp `json:"branding"` + Login *SiteLoginResp `json:"login"` + Theme *SiteThemeResp `json:"theme"` + CustomCssHtml *SiteCustomCssHTMLResp `json:"custom_css_html"` + SiteSeo *SiteSeoResp `json:"site_seo"` + SiteUsers *SiteUsersResp `json:"site_users"` + Advanced *SiteAdvancedResp `json:"site_advanced"` + Questions *SiteQuestionsResp `json:"site_questions"` + Tags *SiteTagsResp `json:"site_tags"` + Legal *SiteLegalSimpleResp `json:"site_legal"` + Version string `json:"version"` + Revision string `json:"revision"` +} + +// todo: 检查模板使用 type TemplateSiteInfoResp struct { - General *SiteGeneralResp `json:"general"` - Interface *SiteInterfaceResp `json:"interface"` - Branding *SiteBrandingResp `json:"branding"` - SiteSeo *SiteSeoResp `json:"site_seo"` - CustomCssHtml *SiteCustomCssHTMLResp `json:"custom_css_html"` + General *SiteGeneralResp `json:"general"` + Interface *SiteInterfaceSettingsResp `json:"interface"` + Branding *SiteBrandingResp `json:"branding"` + SiteSeo *SiteSeoResp `json:"site_seo"` + CustomCssHtml *SiteCustomCssHTMLResp `json:"custom_css_html"` Title string Year string Canonical string diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index 480606633..dd4d81225 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -89,10 +89,15 @@ func (s *SiteInfoService) GetSiteGeneral(ctx context.Context) (resp *schema.Site } // GetSiteInterface get site info interface -func (s *SiteInfoService) GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceResp, err error) { +func (s *SiteInfoService) GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceSettingsResp, err error) { return s.siteInfoCommonService.GetSiteInterface(ctx) } +// GetSiteUsersSettings get site info users settings +func (s *SiteInfoService) GetSiteUsersSettings(ctx context.Context) (resp *schema.SiteUsersSettingsResp, err error) { + return s.siteInfoCommonService.GetSiteUsersSettings(ctx) +} + // GetSiteBranding get site info branding func (s *SiteInfoService) GetSiteBranding(ctx context.Context) (resp *schema.SiteBrandingResp, err error) { return s.siteInfoCommonService.GetSiteBranding(ctx) @@ -172,10 +177,20 @@ func (s *SiteInfoService) SaveSiteInterface(ctx context.Context, req schema.Site content, _ := json.Marshal(req) data := entity.SiteInfo{ - Type: constant.SiteTypeInterface, + Type: constant.SiteTypeInterfaceSettings, + Content: string(content), + } + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeInterfaceSettings, &data) +} + +// SaveSiteUsersSettings save site users settings +func (s *SiteInfoService) SaveSiteUsersSettings(ctx context.Context, req schema.SiteUsersSettingsReq) (err error) { + content, _ := json.Marshal(req) + data := entity.SiteInfo{ + Type: constant.SiteTypeInterfaceSettings, Content: string(content), } - return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeInterface, &data) + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeUsersSettings, &data) } // SaveSiteBranding save site branding information diff --git a/internal/service/siteinfo_common/siteinfo_service.go b/internal/service/siteinfo_common/siteinfo_service.go index 5c1c790ad..1689d32fd 100644 --- a/internal/service/siteinfo_common/siteinfo_service.go +++ b/internal/service/siteinfo_common/siteinfo_service.go @@ -45,7 +45,8 @@ type siteInfoCommonService struct { type SiteInfoCommonService interface { GetSiteGeneral(ctx context.Context) (resp *schema.SiteGeneralResp, err error) - GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceResp, err error) + GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceSettingsResp, err error) + GetSiteUsersSettings(ctx context.Context) (resp *schema.SiteUsersSettingsResp, err error) GetSiteBranding(ctx context.Context) (resp *schema.SiteBrandingResp, err error) GetSiteUsers(ctx context.Context) (resp *schema.SiteUsersResp, err error) FormatAvatar(ctx context.Context, originalAvatarData, email string, userStatus int) *schema.AvatarInfo @@ -81,9 +82,18 @@ func (s *siteInfoCommonService) GetSiteGeneral(ctx context.Context) (resp *schem } // GetSiteInterface get site info interface -func (s *siteInfoCommonService) GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceResp, err error) { - resp = &schema.SiteInterfaceResp{} - if err = s.GetSiteInfoByType(ctx, constant.SiteTypeInterface, resp); err != nil { +func (s *siteInfoCommonService) GetSiteInterface(ctx context.Context) (resp *schema.SiteInterfaceSettingsResp, err error) { + resp = &schema.SiteInterfaceSettingsResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeInterfaceSettings, resp); err != nil { + return nil, err + } + return resp, nil +} + +// GetSiteUsersSettings get site info interface +func (s *siteInfoCommonService) GetSiteUsersSettings(ctx context.Context) (resp *schema.SiteUsersSettingsResp, err error) { + resp = &schema.SiteUsersSettingsResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeUsersSettings, resp); err != nil { return nil, err } return resp, nil @@ -126,7 +136,7 @@ func (s *siteInfoCommonService) FormatListAvatar(ctx context.Context, userList [ func (s *siteInfoCommonService) getAvatarDefaultConfig(ctx context.Context) (string, string) { gravatarBaseURL, defaultAvatar := constant.DefaultGravatarBaseURL, constant.DefaultAvatar - usersConfig, err := s.GetSiteInterface(ctx) + usersConfig, err := s.GetSiteUsersSettings(ctx) if err != nil { log.Error(err) } From 3264fdd1d90f8845dac1632b772bc86d2d61a554 Mon Sep 17 00:00:00 2001 From: kumfo Date: Wed, 21 Jan 2026 16:06:17 +0800 Subject: [PATCH 69/92] feat(siteinfo): refactor site legal and security settings to use new policies and security endpoints --- docs/docs.go | 250 ++++++++++++------ docs/swagger.json | 250 ++++++++++++------ docs/swagger.yaml | 171 +++++++----- internal/base/constant/site_type.go | 6 +- internal/base/middleware/auth.go | 4 +- internal/base/middleware/visit_img_auth.go | 4 +- internal/controller/siteinfo_controller.go | 4 +- internal/controller/template_controller.go | 2 +- .../controller_admin/siteinfo_controller.go | 61 +++-- internal/migrations/init.go | 85 ++++-- internal/migrations/v30.go | 217 +++++++++++---- internal/router/answer_api_router.go | 7 +- internal/schema/siteinfo_schema.go | 21 +- .../service/dashboard/dashboard_service.go | 17 +- internal/service/mock/siteinfo_repo_mock.go | 62 +++-- internal/service/siteinfo/siteinfo_service.go | 34 ++- .../siteinfo_common/siteinfo_service.go | 22 +- 17 files changed, 855 insertions(+), 362 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index b030c3d3d..a70cdab09 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1211,21 +1211,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/legal": { + "/answer/admin/api/siteinfo/login": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "Set the legal information for the site", + "description": "get site info login config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "Set the legal information for the site", + "summary": "get site info login config", "responses": { "200": { "description": "OK", @@ -1238,7 +1238,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteLegalResp" + "$ref": "#/definitions/schema.SiteLoginResp" } } } @@ -1253,22 +1253,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site legal info", + "description": "update site login", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site legal info", + "summary": "update site login", "parameters": [ { - "description": "write info", + "description": "login info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteLegalReq" + "$ref": "#/definitions/schema.SiteLoginReq" } } ], @@ -1282,21 +1282,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/login": { + "/answer/admin/api/siteinfo/polices": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site info login config", + "description": "Get the policies information for the site", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site info login config", + "summary": "Get the policies information for the site", "responses": { "200": { "description": "OK", @@ -1309,7 +1309,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteLoginResp" + "$ref": "#/definitions/schema.SitePoliciesResp" } } } @@ -1324,22 +1324,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site login", + "description": "update site policies configuration", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site login", + "summary": "update site policies configuration", "parameters": [ { - "description": "login info", + "description": "write info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteLoginReq" + "$ref": "#/definitions/schema.SitePoliciesReq" } } ], @@ -1424,6 +1424,77 @@ const docTemplate = `{ } } }, + "/answer/admin/api/siteinfo/security": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Get the security information for the site", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Get the security information for the site", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteSecurityResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site security configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site security configuration", + "parameters": [ + { + "description": "write info", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteSecurityReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/seo": { "get": { "security": [ @@ -10843,9 +10914,6 @@ const docTemplate = `{ "site_url" ], "properties": { - "check_update": { - "type": "boolean" - }, "contact_email": { "type": "string", "maxLength": 512 @@ -10876,9 +10944,6 @@ const docTemplate = `{ "site_url" ], "properties": { - "check_update": { - "type": "boolean" - }, "contact_email": { "type": "string", "maxLength": 512 @@ -10917,7 +10982,12 @@ const docTemplate = `{ "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { - "$ref": "#/definitions/schema.SiteLoginResp" + "description": "todo", + "allOf": [ + { + "$ref": "#/definitions/schema.SiteLoginResp" + } + ] }, "revision": { "type": "string" @@ -10996,60 +11066,6 @@ const docTemplate = `{ } } }, - "schema.SiteLegalReq": { - "type": "object", - "required": [ - "external_content_display" - ], - "properties": { - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "privacy_policy_original_text": { - "type": "string" - }, - "privacy_policy_parsed_text": { - "type": "string" - }, - "terms_of_service_original_text": { - "type": "string" - }, - "terms_of_service_parsed_text": { - "type": "string" - } - } - }, - "schema.SiteLegalResp": { - "type": "object", - "required": [ - "external_content_display" - ], - "properties": { - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "privacy_policy_original_text": { - "type": "string" - }, - "privacy_policy_parsed_text": { - "type": "string" - }, - "terms_of_service_original_text": { - "type": "string" - }, - "terms_of_service_parsed_text": { - "type": "string" - } - } - }, "schema.SiteLegalSimpleResp": { "type": "object", "required": [ @@ -11082,9 +11098,6 @@ const docTemplate = `{ }, "allow_password_login": { "type": "boolean" - }, - "login_required": { - "type": "boolean" } } }, @@ -11105,9 +11118,40 @@ const docTemplate = `{ }, "allow_password_login": { "type": "boolean" + } + } + }, + "schema.SitePoliciesReq": { + "type": "object", + "properties": { + "privacy_policy_original_text": { + "type": "string" }, - "login_required": { - "type": "boolean" + "privacy_policy_parsed_text": { + "type": "string" + }, + "terms_of_service_original_text": { + "type": "string" + }, + "terms_of_service_parsed_text": { + "type": "string" + } + } + }, + "schema.SitePoliciesResp": { + "type": "object", + "properties": { + "privacy_policy_original_text": { + "type": "string" + }, + "privacy_policy_parsed_text": { + "type": "string" + }, + "terms_of_service_original_text": { + "type": "string" + }, + "terms_of_service_parsed_text": { + "type": "string" } } }, @@ -11137,6 +11181,48 @@ const docTemplate = `{ } } }, + "schema.SiteSecurityReq": { + "type": "object", + "required": [ + "external_content_display" + ], + "properties": { + "check_update": { + "type": "boolean" + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "login_required": { + "type": "boolean" + } + } + }, + "schema.SiteSecurityResp": { + "type": "object", + "required": [ + "external_content_display" + ], + "properties": { + "check_update": { + "type": "boolean" + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "login_required": { + "type": "boolean" + } + } + }, "schema.SiteSeoReq": { "type": "object", "required": [ diff --git a/docs/swagger.json b/docs/swagger.json index 879302fa8..05e3302c6 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1203,21 +1203,21 @@ } } }, - "/answer/admin/api/siteinfo/legal": { + "/answer/admin/api/siteinfo/login": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "Set the legal information for the site", + "description": "get site info login config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "Set the legal information for the site", + "summary": "get site info login config", "responses": { "200": { "description": "OK", @@ -1230,7 +1230,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteLegalResp" + "$ref": "#/definitions/schema.SiteLoginResp" } } } @@ -1245,22 +1245,22 @@ "ApiKeyAuth": [] } ], - "description": "update site legal info", + "description": "update site login", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site legal info", + "summary": "update site login", "parameters": [ { - "description": "write info", + "description": "login info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteLegalReq" + "$ref": "#/definitions/schema.SiteLoginReq" } } ], @@ -1274,21 +1274,21 @@ } } }, - "/answer/admin/api/siteinfo/login": { + "/answer/admin/api/siteinfo/polices": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site info login config", + "description": "Get the policies information for the site", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site info login config", + "summary": "Get the policies information for the site", "responses": { "200": { "description": "OK", @@ -1301,7 +1301,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteLoginResp" + "$ref": "#/definitions/schema.SitePoliciesResp" } } } @@ -1316,22 +1316,22 @@ "ApiKeyAuth": [] } ], - "description": "update site login", + "description": "update site policies configuration", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site login", + "summary": "update site policies configuration", "parameters": [ { - "description": "login info", + "description": "write info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteLoginReq" + "$ref": "#/definitions/schema.SitePoliciesReq" } } ], @@ -1416,6 +1416,77 @@ } } }, + "/answer/admin/api/siteinfo/security": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Get the security information for the site", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Get the security information for the site", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteSecurityResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site security configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site security configuration", + "parameters": [ + { + "description": "write info", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteSecurityReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/seo": { "get": { "security": [ @@ -10835,9 +10906,6 @@ "site_url" ], "properties": { - "check_update": { - "type": "boolean" - }, "contact_email": { "type": "string", "maxLength": 512 @@ -10868,9 +10936,6 @@ "site_url" ], "properties": { - "check_update": { - "type": "boolean" - }, "contact_email": { "type": "string", "maxLength": 512 @@ -10909,7 +10974,12 @@ "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { - "$ref": "#/definitions/schema.SiteLoginResp" + "description": "todo", + "allOf": [ + { + "$ref": "#/definitions/schema.SiteLoginResp" + } + ] }, "revision": { "type": "string" @@ -10988,60 +11058,6 @@ } } }, - "schema.SiteLegalReq": { - "type": "object", - "required": [ - "external_content_display" - ], - "properties": { - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "privacy_policy_original_text": { - "type": "string" - }, - "privacy_policy_parsed_text": { - "type": "string" - }, - "terms_of_service_original_text": { - "type": "string" - }, - "terms_of_service_parsed_text": { - "type": "string" - } - } - }, - "schema.SiteLegalResp": { - "type": "object", - "required": [ - "external_content_display" - ], - "properties": { - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "privacy_policy_original_text": { - "type": "string" - }, - "privacy_policy_parsed_text": { - "type": "string" - }, - "terms_of_service_original_text": { - "type": "string" - }, - "terms_of_service_parsed_text": { - "type": "string" - } - } - }, "schema.SiteLegalSimpleResp": { "type": "object", "required": [ @@ -11074,9 +11090,6 @@ }, "allow_password_login": { "type": "boolean" - }, - "login_required": { - "type": "boolean" } } }, @@ -11097,9 +11110,40 @@ }, "allow_password_login": { "type": "boolean" + } + } + }, + "schema.SitePoliciesReq": { + "type": "object", + "properties": { + "privacy_policy_original_text": { + "type": "string" }, - "login_required": { - "type": "boolean" + "privacy_policy_parsed_text": { + "type": "string" + }, + "terms_of_service_original_text": { + "type": "string" + }, + "terms_of_service_parsed_text": { + "type": "string" + } + } + }, + "schema.SitePoliciesResp": { + "type": "object", + "properties": { + "privacy_policy_original_text": { + "type": "string" + }, + "privacy_policy_parsed_text": { + "type": "string" + }, + "terms_of_service_original_text": { + "type": "string" + }, + "terms_of_service_parsed_text": { + "type": "string" } } }, @@ -11129,6 +11173,48 @@ } } }, + "schema.SiteSecurityReq": { + "type": "object", + "required": [ + "external_content_display" + ], + "properties": { + "check_update": { + "type": "boolean" + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "login_required": { + "type": "boolean" + } + } + }, + "schema.SiteSecurityResp": { + "type": "object", + "required": [ + "external_content_display" + ], + "properties": { + "check_update": { + "type": "boolean" + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "login_required": { + "type": "boolean" + } + } + }, "schema.SiteSeoReq": { "type": "object", "required": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index ce16da75e..85a05baf0 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2157,8 +2157,6 @@ definitions: type: object schema.SiteGeneralReq: properties: - check_update: - type: boolean contact_email: maxLength: 512 type: string @@ -2181,8 +2179,6 @@ definitions: type: object schema.SiteGeneralResp: properties: - check_update: - type: boolean contact_email: maxLength: 512 type: string @@ -2214,7 +2210,9 @@ definitions: interface: $ref: '#/definitions/schema.SiteInterfaceSettingsResp' login: - $ref: '#/definitions/schema.SiteLoginResp' + allOf: + - $ref: '#/definitions/schema.SiteLoginResp' + description: todo revision: type: string site_advanced: @@ -2268,42 +2266,6 @@ definitions: - language - time_zone type: object - schema.SiteLegalReq: - properties: - external_content_display: - enum: - - always_display - - ask_before_display - type: string - privacy_policy_original_text: - type: string - privacy_policy_parsed_text: - type: string - terms_of_service_original_text: - type: string - terms_of_service_parsed_text: - type: string - required: - - external_content_display - type: object - schema.SiteLegalResp: - properties: - external_content_display: - enum: - - always_display - - ask_before_display - type: string - privacy_policy_original_text: - type: string - privacy_policy_parsed_text: - type: string - terms_of_service_original_text: - type: string - terms_of_service_parsed_text: - type: string - required: - - external_content_display - type: object schema.SiteLegalSimpleResp: properties: external_content_display: @@ -2326,8 +2288,6 @@ definitions: type: boolean allow_password_login: type: boolean - login_required: - type: boolean type: object schema.SiteLoginResp: properties: @@ -2341,8 +2301,28 @@ definitions: type: boolean allow_password_login: type: boolean - login_required: - type: boolean + type: object + schema.SitePoliciesReq: + properties: + privacy_policy_original_text: + type: string + privacy_policy_parsed_text: + type: string + terms_of_service_original_text: + type: string + terms_of_service_parsed_text: + type: string + type: object + schema.SitePoliciesResp: + properties: + privacy_policy_original_text: + type: string + privacy_policy_parsed_text: + type: string + terms_of_service_original_text: + type: string + terms_of_service_parsed_text: + type: string type: object schema.SiteQuestionsReq: properties: @@ -2362,6 +2342,34 @@ definitions: restrict_answer: type: boolean type: object + schema.SiteSecurityReq: + properties: + check_update: + type: boolean + external_content_display: + enum: + - always_display + - ask_before_display + type: string + login_required: + type: boolean + required: + - external_content_display + type: object + schema.SiteSecurityResp: + properties: + check_update: + type: boolean + external_content_display: + enum: + - always_display + - ask_before_display + type: string + login_required: + type: boolean + required: + - external_content_display + type: object schema.SiteSeoReq: properties: permalink: @@ -3924,9 +3932,9 @@ paths: summary: update site info interface tags: - admin - /answer/admin/api/siteinfo/legal: + /answer/admin/api/siteinfo/login: get: - description: Set the legal information for the site + description: get site info login config produces: - application/json responses: @@ -3937,22 +3945,22 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteLegalResp' + $ref: '#/definitions/schema.SiteLoginResp' type: object security: - ApiKeyAuth: [] - summary: Set the legal information for the site + summary: get site info login config tags: - admin put: - description: update site legal info + description: update site login parameters: - - description: write info + - description: login info in: body name: data required: true schema: - $ref: '#/definitions/schema.SiteLegalReq' + $ref: '#/definitions/schema.SiteLoginReq' produces: - application/json responses: @@ -3962,12 +3970,12 @@ paths: $ref: '#/definitions/handler.RespBody' security: - ApiKeyAuth: [] - summary: update site legal info + summary: update site login tags: - admin - /answer/admin/api/siteinfo/login: + /answer/admin/api/siteinfo/polices: get: - description: get site info login config + description: Get the policies information for the site produces: - application/json responses: @@ -3978,22 +3986,22 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteLoginResp' + $ref: '#/definitions/schema.SitePoliciesResp' type: object security: - ApiKeyAuth: [] - summary: get site info login config + summary: Get the policies information for the site tags: - admin put: - description: update site login + description: update site policies configuration parameters: - - description: login info + - description: write info in: body name: data required: true schema: - $ref: '#/definitions/schema.SiteLoginReq' + $ref: '#/definitions/schema.SitePoliciesReq' produces: - application/json responses: @@ -4003,7 +4011,7 @@ paths: $ref: '#/definitions/handler.RespBody' security: - ApiKeyAuth: [] - summary: update site login + summary: update site policies configuration tags: - admin /answer/admin/api/siteinfo/question: @@ -4047,6 +4055,47 @@ paths: summary: update site question settings tags: - admin + /answer/admin/api/siteinfo/security: + get: + description: Get the security information for the site + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteSecurityResp' + type: object + security: + - ApiKeyAuth: [] + summary: Get the security information for the site + tags: + - admin + put: + description: update site security configuration + parameters: + - description: write info + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteSecurityReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update site security configuration + tags: + - admin /answer/admin/api/siteinfo/seo: get: description: get site seo information diff --git a/internal/base/constant/site_type.go b/internal/base/constant/site_type.go index 9bb4e10af..44cd0abd7 100644 --- a/internal/base/constant/site_type.go +++ b/internal/base/constant/site_type.go @@ -25,7 +25,8 @@ const ( SiteTypeInterface = "interface" SiteTypeBranding = "branding" // Deprecated: use SiteTypeAdvanced, SiteTypeQuestions, and SiteTypeTags instead - SiteTypeWrite = "write" + SiteTypeWrite = "write" + // Deprecated: use SiteTypePolicies and SiteTypeSecurity instead SiteTypeLegal = "legal" SiteTypeSeo = "seo" SiteTypeLogin = "login" @@ -40,4 +41,7 @@ const ( SiteTypeUsersSettings = "users_settings" SiteTypeInterfaceSettings = "interface_settings" + + SiteTypePolicies = "policies" + SiteTypeSecurity = "security" ) diff --git a/internal/base/middleware/auth.go b/internal/base/middleware/auth.go index f21837b60..57bbaae21 100644 --- a/internal/base/middleware/auth.go +++ b/internal/base/middleware/auth.go @@ -80,7 +80,7 @@ func (am *AuthUserMiddleware) Auth() gin.HandlerFunc { func (am *AuthUserMiddleware) EjectUserBySiteInfo() gin.HandlerFunc { return func(ctx *gin.Context) { mustLogin := false - siteInfo, _ := am.siteInfoCommonService.GetSiteLogin(ctx) + siteInfo, _ := am.siteInfoCommonService.GetSiteSecurity(ctx) if siteInfo != nil { mustLogin = siteInfo.LoginRequired } @@ -197,7 +197,7 @@ func (am *AuthUserMiddleware) AdminAuth() gin.HandlerFunc { func (am *AuthUserMiddleware) CheckPrivateMode() gin.HandlerFunc { return func(ctx *gin.Context) { - resp, err := am.siteInfoCommonService.GetSiteLogin(ctx) + resp, err := am.siteInfoCommonService.GetSiteSecurity(ctx) if err != nil { ShowIndexPage(ctx) ctx.Abort() diff --git a/internal/base/middleware/visit_img_auth.go b/internal/base/middleware/visit_img_auth.go index 33b62172f..bfd157a92 100644 --- a/internal/base/middleware/visit_img_auth.go +++ b/internal/base/middleware/visit_img_auth.go @@ -41,11 +41,11 @@ func (am *AuthUserMiddleware) VisitAuth() gin.HandlerFunc { return } - siteLogin, err := am.siteInfoCommonService.GetSiteLogin(ctx) + siteSecurity, err := am.siteInfoCommonService.GetSiteSecurity(ctx) if err != nil { return } - if !siteLogin.LoginRequired { + if !siteSecurity.LoginRequired { ctx.Next() return } diff --git a/internal/controller/siteinfo_controller.go b/internal/controller/siteinfo_controller.go index 503bfeb68..64aa02ce7 100644 --- a/internal/controller/siteinfo_controller.go +++ b/internal/controller/siteinfo_controller.go @@ -104,7 +104,7 @@ func (sc *SiteInfoController) GetSiteInfo(ctx *gin.Context) { if err != nil { log.Error(err) } - if legal, err := sc.siteInfoService.GetSiteLegal(ctx); err == nil { + if legal, err := sc.siteInfoService.GetSiteSecurity(ctx); err == nil { resp.Legal = &schema.SiteLegalSimpleResp{ExternalContentDisplay: legal.ExternalContentDisplay} } @@ -124,7 +124,7 @@ func (sc *SiteInfoController) GetSiteLegalInfo(ctx *gin.Context) { if handler.BindAndCheck(ctx, req) { return } - siteLegal, err := sc.siteInfoService.GetSiteLegal(ctx) + siteLegal, err := sc.siteInfoService.GetSitePolicies(ctx) if err != nil { handler.HandleResponse(ctx, err, nil) return diff --git a/internal/controller/template_controller.go b/internal/controller/template_controller.go index e6b94f4f2..31cc5152a 100644 --- a/internal/controller/template_controller.go +++ b/internal/controller/template_controller.go @@ -656,7 +656,7 @@ func (tc *TemplateController) SitemapPage(ctx *gin.Context) { } func (tc *TemplateController) checkPrivateMode(ctx *gin.Context) bool { - resp, err := tc.siteInfoService.GetSiteLogin(ctx) + resp, err := tc.siteInfoService.GetSiteSecurity(ctx) if err != nil { log.Error(err) return false diff --git a/internal/controller_admin/siteinfo_controller.go b/internal/controller_admin/siteinfo_controller.go index 056b01ae2..339d2caa2 100644 --- a/internal/controller_admin/siteinfo_controller.go +++ b/internal/controller_admin/siteinfo_controller.go @@ -134,16 +134,29 @@ func (sc *SiteInfoController) GetSiteAdvanced(ctx *gin.Context) { handler.HandleResponse(ctx, err, resp) } -// GetSiteLegal Set the legal information for the site -// @Summary Set the legal information for the site -// @Description Set the legal information for the site +// GetSitePolicies Get the policies information for the site +// @Summary Get the policies information for the site +// @Description Get the policies information for the site // @Security ApiKeyAuth // @Tags admin // @Produce json -// @Success 200 {object} handler.RespBody{data=schema.SiteLegalResp} -// @Router /answer/admin/api/siteinfo/legal [get] -func (sc *SiteInfoController) GetSiteLegal(ctx *gin.Context) { - resp, err := sc.siteInfoService.GetSiteLegal(ctx) +// @Success 200 {object} handler.RespBody{data=schema.SitePoliciesResp} +// @Router /answer/admin/api/siteinfo/polices [get] +func (sc *SiteInfoController) GetSitePolicies(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSitePolicies(ctx) + handler.HandleResponse(ctx, err, resp) +} + +// GetSiteSecurity Get the security information for the site +// @Summary Get the security information for the site +// @Description Get the security information for the site +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=schema.SiteSecurityResp} +// @Router /answer/admin/api/siteinfo/security [get] +func (sc *SiteInfoController) GetSiteSecurity(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteSecurity(ctx) handler.HandleResponse(ctx, err, resp) } @@ -403,21 +416,39 @@ func (sc *SiteInfoController) UpdateSiteAdvanced(ctx *gin.Context) { handler.HandleResponse(ctx, err, resp) } -// UpdateSiteLegal update site legal info -// @Summary update site legal info -// @Description update site legal info +// UpdateSitePolices update site policies configuration +// @Summary update site policies configuration +// @Description update site policies configuration +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Param data body schema.SitePoliciesReq true "write info" +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/siteinfo/polices [put] +func (sc *SiteInfoController) UpdateSitePolices(ctx *gin.Context) { + req := &schema.SitePoliciesReq{} + if handler.BindAndCheck(ctx, req) { + return + } + err := sc.siteInfoService.SaveSitePolicies(ctx, req) + handler.HandleResponse(ctx, err, nil) +} + +// UpdateSiteSecurity update site security configuration +// @Summary update site security configuration +// @Description update site security configuration // @Security ApiKeyAuth // @Tags admin // @Produce json -// @Param data body schema.SiteLegalReq true "write info" +// @Param data body schema.SiteSecurityReq true "write info" // @Success 200 {object} handler.RespBody{} -// @Router /answer/admin/api/siteinfo/legal [put] -func (sc *SiteInfoController) UpdateSiteLegal(ctx *gin.Context) { - req := &schema.SiteLegalReq{} +// @Router /answer/admin/api/siteinfo/security [put] +func (sc *SiteInfoController) UpdateSiteSecurity(ctx *gin.Context) { + req := &schema.SiteSecurityReq{} if handler.BindAndCheck(ctx, req) { return } - err := sc.siteInfoService.SaveSiteLegal(ctx, req) + err := sc.siteInfoService.SaveSiteSecurity(ctx, req) handler.HandleResponse(ctx, err, nil) } diff --git a/internal/migrations/init.go b/internal/migrations/init.go index 5ffb37711..ae2eeb9a3 100644 --- a/internal/migrations/init.go +++ b/internal/migrations/init.go @@ -74,14 +74,17 @@ func (m *Mentor) InitDB() error { m.do("init role power rel", m.initRolePowerRel) m.do("init admin user role rel", m.initAdminUserRoleRel) m.do("init site info interface", m.initSiteInfoInterface) + m.do("init site info users settings", m.initSiteInfoUsersSettings) m.do("init site info general config", m.initSiteInfoGeneralData) m.do("init site info login config", m.initSiteInfoLoginConfig) m.do("init site info theme config", m.initSiteInfoThemeConfig) m.do("init site info seo config", m.initSiteInfoSEOConfig) m.do("init site info user config", m.initSiteInfoUsersConfig) m.do("init site info privilege rank", m.initSiteInfoPrivilegeRank) - m.do("init site info write", m.initSiteInfoWrite) - m.do("init site info legal", m.initSiteInfoLegalConfig) + m.do("init site info write", m.initSiteInfoAdvanced) + m.do("init site info write", m.initSiteInfoQuestions) + m.do("init site info write", m.initSiteInfoTags) + m.do("init site info security", m.initSiteInfoSecurityConfig) m.do("init default content", m.initDefaultContent) m.do("init default badges", m.initDefaultBadges) return m.err @@ -181,19 +184,30 @@ func (m *Mentor) initSiteInfoInterface() { } interfaceData := map[string]string{ - "language": m.userData.Language, - "time_zone": localTimezone, - "default_avatar": "gravatar", - "gravatar_base_url": "https://www.gravatar.com/avatar/", + "language": m.userData.Language, + "time_zone": localTimezone, } interfaceDataBytes, _ := json.Marshal(interfaceData) _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ - Type: "interface", + Type: "interface_settings", Content: string(interfaceDataBytes), Status: 1, }) } +func (m *Mentor) initSiteInfoUsersSettings() { + usersSettings := map[string]any{ + "default_avatar": "gravatar", + "gravatar_base_url": "https://www.gravatar.com/avatar/", + } + usersSettingsDataBytes, _ := json.Marshal(usersSettings) + _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ + Type: "users_settings", + Content: string(usersSettingsDataBytes), + Status: 1, + }) +} + func (m *Mentor) initSiteInfoGeneralData() { generalData := map[string]string{ "name": m.userData.SiteName, @@ -213,7 +227,6 @@ func (m *Mentor) initSiteInfoLoginConfig() { "allow_new_registrations": true, "allow_email_registrations": true, "allow_password_login": true, - "login_required": m.userData.LoginRequired, } loginConfigDataBytes, _ := json.Marshal(loginConfig) _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ @@ -223,14 +236,16 @@ func (m *Mentor) initSiteInfoLoginConfig() { }) } -func (m *Mentor) initSiteInfoLegalConfig() { - legalConfig := map[string]any{ +func (m *Mentor) initSiteInfoSecurityConfig() { + securityConfig := map[string]any{ + "login_required": m.userData.LoginRequired, "external_content_display": m.userData.ExternalContentDisplay, + "check_update": true, } - legalConfigDataBytes, _ := json.Marshal(legalConfig) + securityConfigDataBytes, _ := json.Marshal(securityConfig) _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ - Type: "legal", - Content: string(legalConfigDataBytes), + Type: "security", + Content: string(securityConfigDataBytes), Status: 1, }) } @@ -288,24 +303,46 @@ func (m *Mentor) initSiteInfoPrivilegeRank() { }) } -func (m *Mentor) initSiteInfoWrite() { - writeData := map[string]any{ - "min_content": 6, - "restrict_answer": true, - "min_tags": 1, - "required_tag": false, - "recommend_tags": []string{}, - "reserved_tags": []string{}, +func (m *Mentor) initSiteInfoAdvanced() { + advancedData := map[string]any{ "max_image_size": 4, "max_attachment_size": 8, "max_image_megapixel": 40, "authorized_image_extensions": []string{"jpg", "jpeg", "png", "gif", "webp"}, "authorized_attachment_extensions": []string{}, } - writeDataBytes, _ := json.Marshal(writeData) + advancedDataBytes, _ := json.Marshal(advancedData) + _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ + Type: "advanced", + Content: string(advancedDataBytes), + Status: 1, + }) +} + +func (m *Mentor) initSiteInfoQuestions() { + questionsData := map[string]any{ + "min_tags": 1, + "min_content": 6, + "restrict_answer": true, + } + questionsDataBytes, _ := json.Marshal(questionsData) + _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ + Type: "questions", + Content: string(questionsDataBytes), + Status: 1, + }) +} + +func (m *Mentor) initSiteInfoTags() { + tagsData := map[string]any{ + "required_tag": false, + "recommend_tags": []string{}, + "reserved_tags": []string{}, + } + tagsDataBytes, _ := json.Marshal(tagsData) _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{ - Type: "write", - Content: string(writeDataBytes), + Type: "tags", + Content: string(tagsDataBytes), Status: 1, }) } diff --git a/internal/migrations/v30.go b/internal/migrations/v30.go index 4d0f11304..c73f501d5 100644 --- a/internal/migrations/v30.go +++ b/internal/migrations/v30.go @@ -37,6 +37,16 @@ func updateAdminMenuSettings(ctx context.Context, x *xorm.Engine) (err error) { if err != nil { return } + + err = splitInterfaceMenu(ctx, x) + if err != nil { + return + } + + err = splitLegalMenu(ctx, x) + if err != nil { + return + } return } @@ -91,16 +101,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { if err != nil { return err } - if existsAdvanced { - _, err = x.Context(ctx).ID(siteInfoAdvanced.ID).Update(&entity.SiteInfo{ - Type: constant.SiteTypeAdvanced, - Content: string(advancedContent), - Status: 1, - }) - if err != nil { - return err - } - } else { + if !existsAdvanced { _, err = x.Context(ctx).Insert(&entity.SiteInfo{ Type: constant.SiteTypeAdvanced, Content: string(advancedContent), @@ -120,16 +121,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { if err != nil { return err } - if existsQuestions { - _, err = x.Context(ctx).ID(siteInfoQuestions.ID).Update(&entity.SiteInfo{ - Type: constant.SiteTypeQuestions, - Content: string(questionsContent), - Status: 1, - }) - if err != nil { - return err - } - } else { + if !existsQuestions { _, err = x.Context(ctx).Insert(&entity.SiteInfo{ Type: constant.SiteTypeQuestions, Content: string(questionsContent), @@ -149,16 +141,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { if err != nil { return err } - if existsTags { - _, err = x.Context(ctx).ID(siteInfoTags.ID).Update(&entity.SiteInfo{ - Type: constant.SiteTypeTags, - Content: string(tagsContent), - Status: 1, - }) - if err != nil { - return err - } - } else { + if !existsTags { _, err = x.Context(ctx).Insert(&entity.SiteInfo{ Type: constant.SiteTypeTags, Content: string(tagsContent), @@ -172,6 +155,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { return nil } +// splitInterfaceMenu splits the site interface settings into interface and user settings func splitInterfaceMenu(ctx context.Context, x *xorm.Engine) error { var ( siteInfo = &entity.SiteInfo{} @@ -216,16 +200,7 @@ func splitInterfaceMenu(ctx context.Context, x *xorm.Engine) error { if err != nil { return err } - if existsUsers { - _, err = x.Context(ctx).ID(siteInfoUsers.ID).Update(&entity.SiteInfo{ - Type: constant.SiteTypeUsersSettings, - Content: string(userContent), - Status: 1, - }) - if err != nil { - return err - } - } else { + if !existsUsers { _, err = x.Context(ctx).Insert(&entity.SiteInfo{ Type: constant.SiteTypeUsersSettings, Content: string(userContent), @@ -245,8 +220,8 @@ func splitInterfaceMenu(ctx context.Context, x *xorm.Engine) error { if err != nil { return err } - if existsInterface { - _, err = x.Context(ctx).ID(siteInfoInterface.ID).Update(&entity.SiteInfo{ + if !existsInterface { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ Type: constant.SiteTypeInterfaceSettings, Content: string(interfaceContent), Status: 1, @@ -254,10 +229,150 @@ func splitInterfaceMenu(ctx context.Context, x *xorm.Engine) error { if err != nil { return err } - } else { + } + + return nil +} + +// splitLegalMenu splits the site legal settings into policies and security settings +func splitLegalMenu(ctx context.Context, x *xorm.Engine) error { + var ( + siteInfo = &entity.SiteInfo{} + siteInfoPolices = &entity.SiteInfo{} + siteInfoSecurity = &entity.SiteInfo{} + siteInfoLogin = &entity.SiteInfo{} + siteInfoGeneral = &entity.SiteInfo{} + ) + + type SiteLogin struct { + AllowNewRegistrations bool `json:"allow_new_registrations"` + AllowEmailRegistrations bool `json:"allow_email_registrations"` + AllowPasswordLogin bool `json:"allow_password_login"` + LoginRequired bool `json:"login_required"` + AllowEmailDomains []string `json:"allow_email_domains"` + } + + type SiteGeneral struct { + Name string `validate:"required,sanitizer,gt=1,lte=128" form:"name" json:"name"` + ShortDescription string `validate:"omitempty,sanitizer,gt=3,lte=255" form:"short_description" json:"short_description"` + Description string `validate:"omitempty,sanitizer,gt=3,lte=2000" form:"description" json:"description"` + SiteUrl string `validate:"required,sanitizer,gt=1,lte=512,url" form:"site_url" json:"site_url"` + ContactEmail string `validate:"required,sanitizer,gt=1,lte=512,email" form:"contact_email" json:"contact_email"` + CheckUpdate bool `validate:"omitempty,sanitizer" form:"check_update" json:"check_update"` + } + + // find old site legal settings + exist, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeLegal}).Get(siteInfo) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + return err + } + if !exist { + return nil + } + oldSiteLegal := &schema.SiteLegalResp{} + if err := json.Unmarshal([]byte(siteInfo.Content), oldSiteLegal); err != nil { + return err + } + + // find old site login settings + existsLogin, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeLogin}).Get(siteInfoLogin) + if err != nil { + return err + } + oldSiteLogin := &SiteLogin{} + if err := json.Unmarshal([]byte(siteInfoLogin.Content), oldSiteLogin); err != nil { + return err + } + + // find old site general settings + existGeneral, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeGeneral}).Get(siteInfoGeneral) + if err != nil { + return err + } + oldSiteGeneral := &SiteGeneral{} + if err := json.Unmarshal([]byte(siteInfoLogin.Content), oldSiteGeneral); err != nil { + return err + } + + sitePolicies := &schema.SitePoliciesResp{ + TermsOfServiceOriginalText: oldSiteLegal.TermsOfServiceOriginalText, + TermsOfServiceParsedText: oldSiteLegal.TermsOfServiceParsedText, + PrivacyPolicyOriginalText: oldSiteLegal.PrivacyPolicyOriginalText, + PrivacyPolicyParsedText: oldSiteLegal.PrivacyPolicyParsedText, + } + siteLogin := &schema.SiteLoginResp{ + AllowNewRegistrations: oldSiteLogin.AllowNewRegistrations, + AllowEmailRegistrations: oldSiteLogin.AllowEmailRegistrations, + AllowPasswordLogin: oldSiteLogin.AllowPasswordLogin, + AllowEmailDomains: oldSiteLogin.AllowEmailDomains, + } + siteGeneral := &schema.SiteGeneralReq{ + Name: oldSiteGeneral.Name, + ShortDescription: oldSiteGeneral.ShortDescription, + Description: oldSiteGeneral.Description, + SiteUrl: oldSiteGeneral.SiteUrl, + ContactEmail: oldSiteGeneral.ContactEmail, + } + siteSecurity := &schema.SiteSecurityResp{ + LoginRequired: oldSiteLogin.LoginRequired, + ExternalContentDisplay: oldSiteLegal.ExternalContentDisplay, + CheckUpdate: oldSiteGeneral.CheckUpdate, + } + if !existsLogin { + siteSecurity.LoginRequired = false + } + if !existGeneral { + siteSecurity.CheckUpdate = true + } + + // save settings + // save policies settings + existsPolicies, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypePolicies}).Get(siteInfoPolices) + if err != nil { + return err + } + policiesContent, err := json.Marshal(sitePolicies) + if err != nil { + return err + } + if !existsPolicies { + _, err = x.Context(ctx).Insert(&entity.SiteInfo{ + Type: constant.SiteTypePolicies, + Content: string(policiesContent), + Status: 1, + }) + if err != nil { + return err + } + } + + // save security settings + existsSecurity, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeSecurity}).Get(siteInfoSecurity) + if err != nil { + return err + } + securityContent, err := json.Marshal(siteSecurity) + if err != nil { + return err + } + if !existsSecurity { _, err = x.Context(ctx).Insert(&entity.SiteInfo{ - Type: constant.SiteTypeInterfaceSettings, - Content: string(interfaceContent), + Type: constant.SiteTypeSecurity, + Content: string(securityContent), + Status: 1, + }) + if err != nil { + return err + } + } + + // save login settings + if existsLogin { + loginContent, err := json.Marshal(siteLogin) + _, err = x.Context(ctx).ID(siteInfoLogin.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeLogin, + Content: string(loginContent), Status: 1, }) if err != nil { @@ -265,5 +380,17 @@ func splitInterfaceMenu(ctx context.Context, x *xorm.Engine) error { } } + // save general settings + if existGeneral { + generalContent, err := json.Marshal(siteGeneral) + _, err = x.Context(ctx).ID(siteInfoGeneral.ID).Update(&entity.SiteInfo{ + Type: constant.SiteTypeGeneral, + Content: string(generalContent), + Status: 1, + }) + if err != nil { + return err + } + } return nil } diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go index c776b44f0..1fe8bdb14 100644 --- a/internal/router/answer_api_router.go +++ b/internal/router/answer_api_router.go @@ -359,8 +359,11 @@ func (a *AnswerAPIRouter) RegisterAnswerAdminAPIRouter(r *gin.RouterGroup) { r.GET("/siteinfo/advanced", a.adminSiteInfoController.GetSiteAdvanced) r.PUT("/siteinfo/advanced", a.adminSiteInfoController.UpdateSiteAdvanced) - r.GET("/siteinfo/legal", a.adminSiteInfoController.GetSiteLegal) - r.PUT("/siteinfo/legal", a.adminSiteInfoController.UpdateSiteLegal) + r.GET("/siteinfo/polices", a.adminSiteInfoController.GetSitePolicies) + r.PUT("/siteinfo/polices", a.adminSiteInfoController.UpdateSitePolices) + r.GET("/siteinfo/security", a.adminSiteInfoController.GetSiteSecurity) + r.PUT("/siteinfo/security", a.adminSiteInfoController.UpdateSiteSecurity) + r.GET("/siteinfo/seo", a.adminSiteInfoController.GetSeo) r.PUT("/siteinfo/seo", a.adminSiteInfoController.UpdateSeo) r.GET("/siteinfo/login", a.adminSiteInfoController.GetSiteLogin) diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index e4669561b..07747d954 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -42,7 +42,6 @@ type SiteGeneralReq struct { Description string `validate:"omitempty,sanitizer,gt=3,lte=2000" form:"description" json:"description"` SiteUrl string `validate:"required,sanitizer,gt=1,lte=512,url" form:"site_url" json:"site_url"` ContactEmail string `validate:"required,sanitizer,gt=1,lte=512,email" form:"contact_email" json:"contact_email"` - CheckUpdate bool `validate:"omitempty,sanitizer" form:"check_update" json:"check_update"` } func (r *SiteGeneralReq) FormatSiteUrl() { @@ -158,6 +157,7 @@ type SiteWriteTag struct { } // SiteLegalReq site branding request +// Deprecated: use SitePoliciesReq and SiteSecurityReq instead type SiteLegalReq struct { TermsOfServiceOriginalText string `json:"terms_of_service_original_text"` TermsOfServiceParsedText string `json:"terms_of_service_parsed_text"` @@ -166,6 +166,22 @@ type SiteLegalReq struct { ExternalContentDisplay string `validate:"required,oneof=always_display ask_before_display" json:"external_content_display"` } +type SitePoliciesReq struct { + TermsOfServiceOriginalText string `json:"terms_of_service_original_text"` + TermsOfServiceParsedText string `json:"terms_of_service_parsed_text"` + PrivacyPolicyOriginalText string `json:"privacy_policy_original_text"` + PrivacyPolicyParsedText string `json:"privacy_policy_parsed_text"` +} + +type SiteSecurityReq struct { + LoginRequired bool `json:"login_required"` + ExternalContentDisplay string `validate:"required,oneof=always_display ask_before_display" json:"external_content_display"` + CheckUpdate bool `validate:"omitempty,sanitizer" form:"check_update" json:"check_update"` +} + +type SitePoliciesResp SitePoliciesReq +type SiteSecurityResp SiteSecurityReq + // GetSiteLegalInfoReq site site legal request type GetSiteLegalInfoReq struct { InfoType string `validate:"required,oneof=tos privacy" form:"info_type"` @@ -204,7 +220,6 @@ type SiteLoginReq struct { AllowNewRegistrations bool `json:"allow_new_registrations"` AllowEmailRegistrations bool `json:"allow_email_registrations"` AllowPasswordLogin bool `json:"allow_password_login"` - LoginRequired bool `json:"login_required"` AllowEmailDomains []string `json:"allow_email_domains"` } @@ -284,6 +299,7 @@ type SiteAdvancedResp SiteAdvancedReq type SiteTagsResp SiteTagsReq // SiteLegalResp site write response +// Deprecated: use SitePoliciesResp and SiteSecurityResp instead type SiteLegalResp SiteLegalReq // SiteLegalSimpleResp site write response @@ -313,7 +329,6 @@ type SiteInfoResp struct { Revision string `json:"revision"` } -// todo: 检查模板使用 type TemplateSiteInfoResp struct { General *SiteGeneralResp `json:"general"` Interface *SiteInterfaceSettingsResp `json:"interface"` diff --git a/internal/service/dashboard/dashboard_service.go b/internal/service/dashboard/dashboard_service.go index 8b08ba02f..a6ac76e63 100644 --- a/internal/service/dashboard/dashboard_service.go +++ b/internal/service/dashboard/dashboard_service.go @@ -101,6 +101,12 @@ type DashboardService interface { func (ds *dashboardService) Statistical(ctx context.Context) (*schema.DashboardInfo, error) { dashboardInfo := ds.getFromCache(ctx) + security, err := ds.siteInfoService.GetSiteSecurity(ctx) + if err != nil { + log.Errorf("get general site info failed: %s", err) + return dashboardInfo, nil + } + if dashboardInfo == nil { dashboardInfo = &schema.DashboardInfo{} dashboardInfo.AnswerCount = ds.answerCount(ctx) @@ -108,12 +114,7 @@ func (ds *dashboardService) Statistical(ctx context.Context) (*schema.DashboardI dashboardInfo.UserCount = ds.userCount(ctx) dashboardInfo.VoteCount = ds.voteCount(ctx) dashboardInfo.OccupyingStorageSpace = ds.calculateStorage() - general, err := ds.siteInfoService.GetSiteGeneral(ctx) - if err != nil { - log.Errorf("get general site info failed: %s", err) - return dashboardInfo, nil - } - if general.CheckUpdate { + if security.CheckUpdate { dashboardInfo.VersionInfo.RemoteVersion = ds.remoteVersion(ctx) } dashboardInfo.DatabaseVersion = ds.getDatabaseInfo() @@ -141,9 +142,7 @@ func (ds *dashboardService) Statistical(ctx context.Context) (*schema.DashboardI dashboardInfo.VersionInfo.Version = constant.Version dashboardInfo.VersionInfo.Revision = constant.Revision dashboardInfo.GoVersion = constant.GoVersion - if siteLogin, err := ds.siteInfoService.GetSiteLogin(ctx); err == nil { - dashboardInfo.LoginRequired = siteLogin.LoginRequired - } + dashboardInfo.LoginRequired = security.LoginRequired ds.setCache(ctx, dashboardInfo) return dashboardInfo, nil diff --git a/internal/service/mock/siteinfo_repo_mock.go b/internal/service/mock/siteinfo_repo_mock.go index b809d8aef..8feb6a27c 100644 --- a/internal/service/mock/siteinfo_repo_mock.go +++ b/internal/service/mock/siteinfo_repo_mock.go @@ -212,10 +212,10 @@ func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInfoByType(ctx, siteType } // GetSiteInterface mocks base method. -func (m *MockSiteInfoCommonService) GetSiteInterface(ctx context.Context) (*schema.SiteInterfaceResp, error) { +func (m *MockSiteInfoCommonService) GetSiteInterface(ctx context.Context) (*schema.SiteInterfaceSettingsResp, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSiteInterface", ctx) - ret0, _ := ret[0].(*schema.SiteInterfaceResp) + ret0, _ := ret[0].(*schema.SiteInterfaceSettingsResp) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -226,34 +226,34 @@ func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInterface(ctx interface{ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteInterface", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteInterface), ctx) } -// GetSiteLegal mocks base method. -func (m *MockSiteInfoCommonService) GetSiteLegal(ctx context.Context) (*schema.SiteLegalResp, error) { +// GetSiteLogin mocks base method. +func (m *MockSiteInfoCommonService) GetSiteLogin(ctx context.Context) (*schema.SiteLoginResp, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSiteLegal", ctx) - ret0, _ := ret[0].(*schema.SiteLegalResp) + ret := m.ctrl.Call(m, "GetSiteLogin", ctx) + ret0, _ := ret[0].(*schema.SiteLoginResp) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetSiteLegal indicates an expected call of GetSiteLegal. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLegal(ctx interface{}) *gomock.Call { +// GetSiteLogin indicates an expected call of GetSiteLogin. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLegal", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLegal), ctx) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLogin", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLogin), ctx) } -// GetSiteLogin mocks base method. -func (m *MockSiteInfoCommonService) GetSiteLogin(ctx context.Context) (*schema.SiteLoginResp, error) { +// GetSitePolicies mocks base method. +func (m *MockSiteInfoCommonService) GetSitePolicies(ctx context.Context) (*schema.SitePoliciesResp, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSiteLogin", ctx) - ret0, _ := ret[0].(*schema.SiteLoginResp) + ret := m.ctrl.Call(m, "GetSitePolicies", ctx) + ret0, _ := ret[0].(*schema.SitePoliciesResp) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetSiteLogin indicates an expected call of GetSiteLogin. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx interface{}) *gomock.Call { +// GetSitePolicies indicates an expected call of GetSitePolicies. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSitePolicies(ctx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLogin", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLogin), ctx) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSitePolicies", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSitePolicies), ctx) } // GetSiteQuestion mocks base method. @@ -271,6 +271,21 @@ func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteQuestion(ctx interface{} return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteQuestion", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteQuestion), ctx) } +// GetSiteSecurity mocks base method. +func (m *MockSiteInfoCommonService) GetSiteSecurity(ctx context.Context) (*schema.SiteSecurityResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteSecurity", ctx) + ret0, _ := ret[0].(*schema.SiteSecurityResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteSecurity indicates an expected call of GetSiteSecurity. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteSecurity(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteSecurity", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteSecurity), ctx) +} + // GetSiteSeo mocks base method. func (m *MockSiteInfoCommonService) GetSiteSeo(ctx context.Context) (*schema.SiteSeoResp, error) { m.ctrl.T.Helper() @@ -331,6 +346,21 @@ func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsers(ctx interface{}) * return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteUsers", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteUsers), ctx) } +// GetSiteUsersSettings mocks base method. +func (m *MockSiteInfoCommonService) GetSiteUsersSettings(ctx context.Context) (*schema.SiteUsersSettingsResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteUsersSettings", ctx) + ret0, _ := ret[0].(*schema.SiteUsersSettingsResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteUsersSettings indicates an expected call of GetSiteUsersSettings. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsersSettings(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteUsersSettings", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteUsersSettings), ctx) +} + // GetSiteWrite mocks base method. func (m *MockSiteInfoCommonService) GetSiteWrite(ctx context.Context) (*schema.SiteWriteResp, error) { m.ctrl.T.Helper() diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index dd4d81225..ab4705a8d 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -138,9 +138,14 @@ func (s *SiteInfoService) GetSiteAdvanced(ctx context.Context) (resp *schema.Sit return s.siteInfoCommonService.GetSiteAdvanced(ctx) } -// GetSiteLegal get site legal info -func (s *SiteInfoService) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) { - return s.siteInfoCommonService.GetSiteLegal(ctx) +// GetSitePolicies get site legal info +func (s *SiteInfoService) GetSitePolicies(ctx context.Context) (resp *schema.SitePoliciesResp, err error) { + return s.siteInfoCommonService.GetSitePolicies(ctx) +} + +// GetSiteSecurity get site security info +func (s *SiteInfoService) GetSiteSecurity(ctx context.Context) (resp *schema.SiteSecurityResp, err error) { + return s.siteInfoCommonService.GetSiteSecurity(ctx) } // GetSiteLogin get site login info @@ -261,15 +266,26 @@ func (s *SiteInfoService) SaveSiteTags(ctx context.Context, req *schema.SiteTags return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeTags, data) } -// SaveSiteLegal save site legal configuration -func (s *SiteInfoService) SaveSiteLegal(ctx context.Context, req *schema.SiteLegalReq) (err error) { +// SaveSitePolicies save site policies configuration +func (s *SiteInfoService) SaveSitePolicies(ctx context.Context, req *schema.SitePoliciesReq) (err error) { + content, _ := json.Marshal(req) + data := &entity.SiteInfo{ + Type: constant.SiteTypePolicies, + Content: string(content), + Status: 1, + } + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypePolicies, data) +} + +// SaveSiteSecurity save site security configuration +func (s *SiteInfoService) SaveSiteSecurity(ctx context.Context, req *schema.SiteSecurityReq) (err error) { content, _ := json.Marshal(req) data := &entity.SiteInfo{ - Type: constant.SiteTypeLegal, + Type: constant.SiteTypeSecurity, Content: string(content), Status: 1, } - return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeLegal, data) + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeSecurity, data) } // SaveSiteLogin save site legal configuration @@ -364,13 +380,13 @@ func (s *SiteInfoService) GetSeo(ctx context.Context) (resp *schema.SiteSeoReq, if err = s.siteInfoCommonService.GetSiteInfoByType(ctx, constant.SiteTypeSeo, resp); err != nil { return resp, err } - loginConfig, err := s.GetSiteLogin(ctx) + siteSecurity, err := s.GetSiteSecurity(ctx) if err != nil { log.Error(err) return resp, nil } // If the site is set to privacy mode, prohibit crawling any page. - if loginConfig.LoginRequired { + if siteSecurity.LoginRequired { resp.Robots = "User-agent: *\nDisallow: /" return resp, nil } diff --git a/internal/service/siteinfo_common/siteinfo_service.go b/internal/service/siteinfo_common/siteinfo_service.go index 1689d32fd..2f2efb799 100644 --- a/internal/service/siteinfo_common/siteinfo_service.go +++ b/internal/service/siteinfo_common/siteinfo_service.go @@ -55,7 +55,8 @@ type SiteInfoCommonService interface { GetSiteAdvanced(ctx context.Context) (resp *schema.SiteAdvancedResp, err error) GetSiteQuestion(ctx context.Context) (resp *schema.SiteQuestionsResp, err error) GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error) - GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) + GetSitePolicies(ctx context.Context) (resp *schema.SitePoliciesResp, err error) + GetSiteSecurity(ctx context.Context) (resp *schema.SiteSecurityResp, err error) GetSiteLogin(ctx context.Context) (resp *schema.SiteLoginResp, err error) GetSiteCustomCssHTML(ctx context.Context) (resp *schema.SiteCustomCssHTMLResp, err error) GetSiteTheme(ctx context.Context) (resp *schema.SiteThemeResp, err error) @@ -73,7 +74,7 @@ func NewSiteInfoCommonService(siteInfoRepo SiteInfoRepo) SiteInfoCommonService { // GetSiteGeneral get site info general func (s *siteInfoCommonService) GetSiteGeneral(ctx context.Context) (resp *schema.SiteGeneralResp, err error) { - resp = &schema.SiteGeneralResp{CheckUpdate: true} + resp = &schema.SiteGeneralResp{} if err = s.GetSiteInfoByType(ctx, constant.SiteTypeGeneral, resp); err != nil { return nil, err } @@ -207,10 +208,19 @@ func (s *siteInfoCommonService) GetSiteTag(ctx context.Context) (resp *schema.Si return resp, nil } -// GetSiteLegal get site info write -func (s *siteInfoCommonService) GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err error) { - resp = &schema.SiteLegalResp{} - if err = s.GetSiteInfoByType(ctx, constant.SiteTypeLegal, resp); err != nil { +// GetSitePolicies get site info policies +func (s *siteInfoCommonService) GetSitePolicies(ctx context.Context) (resp *schema.SitePoliciesResp, err error) { + resp = &schema.SitePoliciesResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypePolicies, resp); err != nil { + return nil, err + } + return resp, nil +} + +// GetSiteSecurity get site security config +func (s *siteInfoCommonService) GetSiteSecurity(ctx context.Context) (resp *schema.SiteSecurityResp, err error) { + resp = &schema.SiteSecurityResp{CheckUpdate: true} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeSecurity, resp); err != nil { return nil, err } return resp, nil From 128c44f5a3477074c106e6a3065fe07ab50dacf8 Mon Sep 17 00:00:00 2001 From: kumfo Date: Wed, 21 Jan 2026 16:29:08 +0800 Subject: [PATCH 70/92] feat(menu): update schema to remove deprecated min_tags and add MinimumTags to SiteQuestionsReq --- docs/docs.go | 27 +++++++++-------------- docs/swagger.json | 27 +++++++++-------------- docs/swagger.yaml | 20 ++++++++--------- internal/migrations/v30.go | 2 +- internal/schema/siteinfo_schema.go | 3 ++- internal/service/tag_common/tag_common.go | 2 +- 6 files changed, 35 insertions(+), 46 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index a70cdab09..c624133bd 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -10982,12 +10982,7 @@ const docTemplate = `{ "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { - "description": "todo", - "allOf": [ - { - "$ref": "#/definitions/schema.SiteLoginResp" - } - ] + "$ref": "#/definitions/schema.SiteLoginResp" }, "revision": { "type": "string" @@ -11163,6 +11158,11 @@ const docTemplate = `{ "maximum": 65535, "minimum": 0 }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "restrict_answer": { "type": "boolean" } @@ -11176,6 +11176,11 @@ const docTemplate = `{ "maximum": 65535, "minimum": 0 }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "restrict_answer": { "type": "boolean" } @@ -11260,11 +11265,6 @@ const docTemplate = `{ "schema.SiteTagsReq": { "type": "object", "properties": { - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, "recommend_tags": { "type": "array", "items": { @@ -11285,11 +11285,6 @@ const docTemplate = `{ "schema.SiteTagsResp": { "type": "object", "properties": { - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, "recommend_tags": { "type": "array", "items": { diff --git a/docs/swagger.json b/docs/swagger.json index 05e3302c6..58f385790 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -10974,12 +10974,7 @@ "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { - "description": "todo", - "allOf": [ - { - "$ref": "#/definitions/schema.SiteLoginResp" - } - ] + "$ref": "#/definitions/schema.SiteLoginResp" }, "revision": { "type": "string" @@ -11155,6 +11150,11 @@ "maximum": 65535, "minimum": 0 }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "restrict_answer": { "type": "boolean" } @@ -11168,6 +11168,11 @@ "maximum": 65535, "minimum": 0 }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, "restrict_answer": { "type": "boolean" } @@ -11252,11 +11257,6 @@ "schema.SiteTagsReq": { "type": "object", "properties": { - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, "recommend_tags": { "type": "array", "items": { @@ -11277,11 +11277,6 @@ "schema.SiteTagsResp": { "type": "object", "properties": { - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, "recommend_tags": { "type": "array", "items": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 85a05baf0..39235a336 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2210,9 +2210,7 @@ definitions: interface: $ref: '#/definitions/schema.SiteInterfaceSettingsResp' login: - allOf: - - $ref: '#/definitions/schema.SiteLoginResp' - description: todo + $ref: '#/definitions/schema.SiteLoginResp' revision: type: string site_advanced: @@ -2330,6 +2328,10 @@ definitions: maximum: 65535 minimum: 0 type: integer + min_tags: + maximum: 5 + minimum: 0 + type: integer restrict_answer: type: boolean type: object @@ -2339,6 +2341,10 @@ definitions: maximum: 65535 minimum: 0 type: integer + min_tags: + maximum: 5 + minimum: 0 + type: integer restrict_answer: type: boolean type: object @@ -2396,10 +2402,6 @@ definitions: type: object schema.SiteTagsReq: properties: - min_tags: - maximum: 5 - minimum: 0 - type: integer recommend_tags: items: $ref: '#/definitions/schema.SiteWriteTag' @@ -2413,10 +2415,6 @@ definitions: type: object schema.SiteTagsResp: properties: - min_tags: - maximum: 5 - minimum: 0 - type: integer recommend_tags: items: $ref: '#/definitions/schema.SiteWriteTag' diff --git a/internal/migrations/v30.go b/internal/migrations/v30.go index c73f501d5..aa2f48b36 100644 --- a/internal/migrations/v30.go +++ b/internal/migrations/v30.go @@ -80,6 +80,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { } // site questions settings siteQuestions := &schema.SiteQuestionsResp{ + MinimumTags: siteWrite.MinimumTags, MinimumContent: siteWrite.MinimumContent, RestrictAnswer: siteWrite.RestrictAnswer, } @@ -87,7 +88,6 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine) error { siteTags := &schema.SiteTagsResp{ ReservedTags: siteWrite.ReservedTags, RecommendTags: siteWrite.RecommendTags, - MinimumTags: siteWrite.MinimumTags, RequiredTag: siteWrite.RequiredTag, } diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index 07747d954..d3a886fdf 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -88,6 +88,7 @@ type SiteBrandingReq struct { } // SiteWriteReq site write request +// Deprecated: use SiteQuestionsReq, SiteAdvancedReq and SiteTagsReq instead type SiteWriteReq struct { MinimumContent int `validate:"omitempty,gte=0,lte=65535" json:"min_content"` RestrictAnswer bool `validate:"omitempty" json:"restrict_answer"` @@ -107,6 +108,7 @@ type SiteWriteResp SiteWriteReq // SiteQuestionsReq site questions settings request type SiteQuestionsReq struct { + MinimumTags int `validate:"omitempty,gte=0,lte=5" json:"min_tags"` MinimumContent int `validate:"omitempty,gte=0,lte=65535" json:"min_content"` RestrictAnswer bool `validate:"omitempty" json:"restrict_answer"` } @@ -124,7 +126,6 @@ type SiteAdvancedReq struct { type SiteTagsReq struct { ReservedTags []*SiteWriteTag `validate:"omitempty,dive" json:"reserved_tags"` RecommendTags []*SiteWriteTag `validate:"omitempty,dive" json:"recommend_tags"` - MinimumTags int `validate:"omitempty,gte=0,lte=5" json:"min_tags"` RequiredTag bool `validate:"omitempty" json:"required_tag"` UserID string `json:"-"` } diff --git a/internal/service/tag_common/tag_common.go b/internal/service/tag_common/tag_common.go index 0da9f6fd5..87b53f396 100644 --- a/internal/service/tag_common/tag_common.go +++ b/internal/service/tag_common/tag_common.go @@ -295,7 +295,7 @@ func (ts *TagCommonService) ExistRecommend(ctx context.Context, tags []*schema.T } func (ts *TagCommonService) GetMinimumTags(ctx context.Context) (int, error) { - siteInfo, err := ts.siteInfoService.GetSiteTag(ctx) + siteInfo, err := ts.siteInfoService.GetSiteQuestion(ctx) if err != nil { return 1, err } From 6369056914a5a92f0898e013e1bf2cea03fadba3 Mon Sep 17 00:00:00 2001 From: kumfo Date: Wed, 21 Jan 2026 17:21:28 +0800 Subject: [PATCH 71/92] feat(siteinfo): fix GetSiteTag method to correctly assign response from siteInfoCommonService --- internal/service/siteinfo/siteinfo_service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index ab4705a8d..cc0cb5997 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -111,7 +111,7 @@ func (s *SiteInfoService) GetSiteUsers(ctx context.Context) (resp *schema.SiteUs // GetSiteTag get site info write func (s *SiteInfoService) GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error) { resp = &schema.SiteTagsResp{} - _, err = s.siteInfoCommonService.GetSiteTag(ctx) + resp, err = s.siteInfoCommonService.GetSiteTag(ctx) if err != nil { log.Error(err) return resp, nil From 18b76f3e23bace34b0fe352aab0a8a33549e4928 Mon Sep 17 00:00:00 2001 From: kumfo Date: Thu, 22 Jan 2026 10:59:28 +0800 Subject: [PATCH 72/92] feat(siteinfo): add site_security to response structure and update related schemas --- docs/docs.go | 3 +++ docs/swagger.json | 3 +++ docs/swagger.yaml | 2 ++ internal/controller/siteinfo_controller.go | 3 +++ internal/schema/siteinfo_schema.go | 1 + 5 files changed, 12 insertions(+) diff --git a/docs/docs.go b/docs/docs.go index c624133bd..23398e509 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -10996,6 +10996,9 @@ const docTemplate = `{ "site_questions": { "$ref": "#/definitions/schema.SiteQuestionsResp" }, + "site_security": { + "$ref": "#/definitions/schema.SiteSecurityResp" + }, "site_seo": { "$ref": "#/definitions/schema.SiteSeoResp" }, diff --git a/docs/swagger.json b/docs/swagger.json index 58f385790..b9dc0b0b1 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -10988,6 +10988,9 @@ "site_questions": { "$ref": "#/definitions/schema.SiteQuestionsResp" }, + "site_security": { + "$ref": "#/definitions/schema.SiteSecurityResp" + }, "site_seo": { "$ref": "#/definitions/schema.SiteSeoResp" }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 39235a336..4a680ec49 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2219,6 +2219,8 @@ definitions: $ref: '#/definitions/schema.SiteLegalSimpleResp' site_questions: $ref: '#/definitions/schema.SiteQuestionsResp' + site_security: + $ref: '#/definitions/schema.SiteSecurityResp' site_seo: $ref: '#/definitions/schema.SiteSeoResp' site_tags: diff --git a/internal/controller/siteinfo_controller.go b/internal/controller/siteinfo_controller.go index 64aa02ce7..320c1b475 100644 --- a/internal/controller/siteinfo_controller.go +++ b/internal/controller/siteinfo_controller.go @@ -107,6 +107,9 @@ func (sc *SiteInfoController) GetSiteInfo(ctx *gin.Context) { if legal, err := sc.siteInfoService.GetSiteSecurity(ctx); err == nil { resp.Legal = &schema.SiteLegalSimpleResp{ExternalContentDisplay: legal.ExternalContentDisplay} } + if security, err := sc.siteInfoService.GetSiteSecurity(ctx); err == nil { + resp.Security = security + } handler.HandleResponse(ctx, nil, resp) } diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index d3a886fdf..77ab75fc2 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -326,6 +326,7 @@ type SiteInfoResp struct { Questions *SiteQuestionsResp `json:"site_questions"` Tags *SiteTagsResp `json:"site_tags"` Legal *SiteLegalSimpleResp `json:"site_legal"` + Security *SiteSecurityResp `json:"site_security"` Version string `json:"version"` Revision string `json:"revision"` } From 73cfbace7090b233a51571dabdd26ec47c62c890 Mon Sep 17 00:00:00 2001 From: kumfo Date: Thu, 22 Jan 2026 11:49:50 +0800 Subject: [PATCH 73/92] feat(menu): deprecate default_avatar and gravatar_base_url in SiteInterfaceReq schema --- docs/docs.go | 11 ----------- docs/swagger.json | 11 ----------- docs/swagger.yaml | 8 -------- internal/schema/siteinfo_schema.go | 10 ++++++---- 4 files changed, 6 insertions(+), 34 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index 23398e509..00eb75ce2 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -11022,21 +11022,10 @@ const docTemplate = `{ "schema.SiteInterfaceReq": { "type": "object", "required": [ - "default_avatar", "language", "time_zone" ], "properties": { - "default_avatar": { - "type": "string", - "enum": [ - "system", - "gravatar" - ] - }, - "gravatar_base_url": { - "type": "string" - }, "language": { "type": "string", "maxLength": 128 diff --git a/docs/swagger.json b/docs/swagger.json index b9dc0b0b1..c181109d2 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -11014,21 +11014,10 @@ "schema.SiteInterfaceReq": { "type": "object", "required": [ - "default_avatar", "language", "time_zone" ], "properties": { - "default_avatar": { - "type": "string", - "enum": [ - "system", - "gravatar" - ] - }, - "gravatar_base_url": { - "type": "string" - }, "language": { "type": "string", "maxLength": 128 diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 4a680ec49..caab11876 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2236,13 +2236,6 @@ definitions: type: object schema.SiteInterfaceReq: properties: - default_avatar: - enum: - - system - - gravatar - type: string - gravatar_base_url: - type: string language: maxLength: 128 type: string @@ -2250,7 +2243,6 @@ definitions: maxLength: 128 type: string required: - - default_avatar - language - time_zone type: object diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index 77ab75fc2..bf1c7713e 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -58,10 +58,12 @@ func (r *SiteGeneralReq) FormatSiteUrl() { // SiteInterfaceReq site interface request type SiteInterfaceReq struct { - Language string `validate:"required,gt=1,lte=128" form:"language" json:"language"` - TimeZone string `validate:"required,gt=1,lte=128" form:"time_zone" json:"time_zone"` - DefaultAvatar string `validate:"required,oneof=system gravatar" json:"default_avatar"` - GravatarBaseURL string `validate:"omitempty" json:"gravatar_base_url"` + Language string `validate:"required,gt=1,lte=128" form:"language" json:"language"` + TimeZone string `validate:"required,gt=1,lte=128" form:"time_zone" json:"time_zone"` + // Deperecated: use SiteUsersSettingsReq instead + DefaultAvatar string `validate:"omitempty" json:"-"` + // Deperecated: use SiteUsersSettingsReq instead + GravatarBaseURL string `validate:"omitempty" json:"-"` } // SiteInterfaceSettingsReq site interface settings request From 86c2d64dbf7f9b592e7026f0f432759d552fce45 Mon Sep 17 00:00:00 2001 From: kumfo Date: Thu, 22 Jan 2026 12:18:57 +0800 Subject: [PATCH 74/92] feat(docs): add Apache License 2.0 header to docs.go and swagger.yaml --- docs/docs.go | 19 +++++++++++++++++++ docs/swagger.yaml | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/docs/docs.go b/docs/docs.go index 00eb75ce2..cfe48366f 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + // Package docs Code generated by swaggo/swag. DO NOT EDIT package docs diff --git a/docs/swagger.yaml b/docs/swagger.yaml index caab11876..13e9575eb 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,3 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + basePath: / definitions: constant.NotificationChannelKey: From 630ac20a384cad4b4e1527528c2fbbc50b937933 Mon Sep 17 00:00:00 2001 From: dashuai Date: Thu, 22 Jan 2026 14:07:30 +0800 Subject: [PATCH 75/92] Management Backend Menu and Function Adjustments (#1474) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …ent, regardless of functional split or reorganization --- i18n/en_US.yaml | 9 +- i18n/zh_CN.yaml | 9 +- ui/src/common/constants.ts | 58 ++- ui/src/common/interface.ts | 37 +- ui/src/components/AccordionNav/index.tsx | 65 ++- ui/src/components/AdminSideNav/index.tsx | 13 +- .../SchemaForm/components/Switch.tsx | 3 +- ui/src/components/SchemaForm/index.tsx | 8 +- ui/src/components/SchemaForm/types.ts | 2 +- ui/src/components/TabNav/index.tsx | 26 + ui/src/components/index.ts | 2 + ui/src/pages/Admin/Answers/index.tsx | 8 +- ui/src/pages/Admin/Branding/index.tsx | 16 +- ui/src/pages/Admin/CssAndHtml/index.tsx | 16 +- .../components/HealthStatus/index.tsx | 6 +- ui/src/pages/Admin/Files/index.tsx | 261 ++++++++++ ui/src/pages/Admin/General/index.tsx | 29 +- ui/src/pages/Admin/Interface/index.tsx | 75 +-- ui/src/pages/Admin/Login/index.tsx | 30 +- ui/src/pages/Admin/Plugins/Config/index.tsx | 18 +- .../pages/Admin/{Legal => Policies}/index.tsx | 63 +-- ui/src/pages/Admin/Privileges/index.tsx | 32 +- ui/src/pages/Admin/QaSettings/index.tsx | 132 +++++ ui/src/pages/Admin/Questions/index.tsx | 4 +- ui/src/pages/Admin/Security/index.tsx | 145 ++++++ ui/src/pages/Admin/Seo/index.tsx | 16 +- ui/src/pages/Admin/Smtp/index.tsx | 16 +- ui/src/pages/Admin/TagsSettings/index.tsx | 170 +++++++ ui/src/pages/Admin/Themes/index.tsx | 16 +- ui/src/pages/Admin/Users/index.tsx | 3 + ui/src/pages/Admin/UsersSettings/index.tsx | 132 +++++ ui/src/pages/Admin/Write/index.tsx | 473 ------------------ ui/src/pages/Admin/index.scss | 4 + ui/src/pages/Admin/index.tsx | 16 +- ui/src/pages/Layout/index.tsx | 5 +- ui/src/pages/Users/Settings/Profile/index.tsx | 10 +- ui/src/router/routes.ts | 36 +- ui/src/services/admin/index.ts | 1 + ui/src/services/admin/question.ts | 10 + ui/src/services/admin/settings.ts | 38 +- ui/src/services/admin/tags.ts | 29 ++ ui/src/services/admin/users.ts | 19 + ui/src/stores/index.ts | 4 +- ui/src/stores/interface.ts | 4 +- ui/src/stores/loginSetting.ts | 1 - ui/src/stores/siteInfo.ts | 3 +- .../stores/{siteLegal.ts => siteSecurity.ts} | 16 +- ui/src/stores/writeSetting.ts | 12 +- ui/src/utils/guard.ts | 15 +- 49 files changed, 1325 insertions(+), 791 deletions(-) create mode 100644 ui/src/components/TabNav/index.tsx create mode 100644 ui/src/pages/Admin/Files/index.tsx rename ui/src/pages/Admin/{Legal => Policies}/index.tsx (70%) create mode 100644 ui/src/pages/Admin/QaSettings/index.tsx create mode 100644 ui/src/pages/Admin/Security/index.tsx create mode 100644 ui/src/pages/Admin/TagsSettings/index.tsx create mode 100644 ui/src/pages/Admin/UsersSettings/index.tsx delete mode 100644 ui/src/pages/Admin/Write/index.tsx create mode 100644 ui/src/services/admin/tags.ts rename ui/src/stores/{siteLegal.ts => siteSecurity.ts} (75%) diff --git a/i18n/en_US.yaml b/i18n/en_US.yaml index 653793f23..ea6073664 100644 --- a/i18n/en_US.yaml +++ b/i18n/en_US.yaml @@ -1816,6 +1816,13 @@ ui: plugins: Plugins installed_plugins: Installed Plugins apperance: Appearance + community: Community + advanced: Advanced + tags: Tags + rules: Rules + policies: Policies + security: Security + files: Files website_welcome: Welcome to {{site_name}} user_center: login: Login @@ -2128,7 +2135,7 @@ ui: always_display: Always display external content ask_before_display: Ask before displaying external content write: - page_title: Write + page_title: Files min_content: label: Minimum question body length text: Minimum allowed question body length in characters. diff --git a/i18n/zh_CN.yaml b/i18n/zh_CN.yaml index a6c7f1983..29e18151b 100644 --- a/i18n/zh_CN.yaml +++ b/i18n/zh_CN.yaml @@ -1778,6 +1778,13 @@ ui: plugins: 插件 installed_plugins: 已安装插件 apperance: 外观 + community: 社区 + advanced: 高级 + tags: 标签 + rules: 规则 + policies: 政策 + security: 安全 + files: 文件 website_welcome: 欢迎来到 {{site_name}} user_center: login: 登录 @@ -2089,7 +2096,7 @@ ui: always_display: 总是显示外部内容 ask_before_display: 在显示外部内容之前询问 write: - page_title: 编辑 + page_title: 文件 min_content: label: 最小问题长度 text: 最小允许的问题内容长度(字符)。 diff --git a/ui/src/common/constants.ts b/ui/src/common/constants.ts index 18f251145..285da4747 100644 --- a/ui/src/common/constants.ts +++ b/ui/src/common/constants.ts @@ -83,6 +83,11 @@ export const ADMIN_LIST_STATUS = { }, }; +/** + * ADMIN_NAV_MENUS is the navigation menu for the admin panel. + * pathPrefix is used to activate the menu item when the activeKey starts with the pathPrefix. + */ + export const ADMIN_NAV_MENUS = [ { name: 'dashboard', @@ -92,15 +97,19 @@ export const ADMIN_NAV_MENUS = [ { name: 'contents', icon: 'file-earmark-text-fill', - children: [{ name: 'questions' }, { name: 'answers' }], + children: [ + { name: 'questions', path: 'qa/questions', pathPrefix: 'qa/' }, + { name: 'tags', path: 'tags/settings', pathPrefix: 'tags/' }, + ], }, { - name: 'users', + name: 'community', icon: 'people-fill', - }, - { - name: 'badges', - icon: 'award-fill', + children: [ + { name: 'users', pathPrefix: 'users/' }, + { name: 'badges' }, + { name: 'rules', path: 'rules/privileges', pathPrefix: 'rules/' }, + ], }, { name: 'apperance', @@ -113,20 +122,19 @@ export const ADMIN_NAV_MENUS = [ name: 'customize', }, { name: 'branding' }, + { name: 'interface' }, ], }, { - name: 'settings', + name: 'advanced', icon: 'gear-fill', children: [ { name: 'general' }, - { name: 'interface' }, - { name: 'smtp' }, - { name: 'legal' }, - { name: 'write' }, - { name: 'seo' }, + { name: 'security' }, + { name: 'files' }, { name: 'login' }, - { name: 'privileges' }, + { name: 'seo' }, + { name: 'smtp' }, ], }, { @@ -141,6 +149,30 @@ export const ADMIN_NAV_MENUS = [ }, ]; +export const ADMIN_QA_NAV_MENUS = [ + { name: 'questions', path: '/admin/qa/questions' }, + { name: 'answers', path: '/admin/qa/answers' }, + { name: 'settings', path: '/admin/qa/settings' }, +]; + +export const ADMIN_TAGS_NAV_MENUS = [ + // { name: 'tags', path: '/admin/tags' }, + { + name: 'settings', + path: '/admin/tags/settings', + }, +]; + +export const ADMIN_USERS_NAV_MENUS = [ + { name: 'users', path: '/admin/users' }, + { name: 'settings', path: '/admin/users/settings' }, +]; + +export const ADMIN_RULES_NAV_MENUS = [ + { name: 'privileges', path: '/admin/rules/privileges' }, + { name: 'policies', path: '/admin/rules/policies' }, +]; + export const TIMEZONES = [ { label: 'Africa', diff --git a/ui/src/common/interface.ts b/ui/src/common/interface.ts index 3a77047e7..aac89cce2 100644 --- a/ui/src/common/interface.ts +++ b/ui/src/common/interface.ts @@ -364,7 +364,6 @@ export interface AdminSettingsGeneral { description: string; site_url: string; contact_email: string; - check_update: boolean; permalink?: number; } @@ -382,8 +381,6 @@ export interface HelmetUpdate extends Omit { export interface AdminSettingsInterface { language: string; time_zone?: string; - default_avatar: string; - gravatar_base_url: string; } export interface AdminSettingsSmtp { @@ -405,6 +402,14 @@ export interface AdminSettingsUsers { allow_update_location: boolean; allow_update_username: boolean; allow_update_website: boolean; + default_avatar: string; + gravatar_base_url: string; +} + +export interface AdminSettingsSecurity { + external_content_display: string; + check_update: boolean; + login_required: boolean; } export interface SiteSettings { @@ -416,10 +421,12 @@ export interface SiteSettings { theme: AdminSettingsTheme; site_seo: AdminSettingsSeo; site_users: AdminSettingsUsers; - site_write: AdminSettingsWrite; + site_advanced: AdminSettingsWrite; + site_questions: AdminQuestionSetting; + site_tags: AdminTagsSetting; version: string; revision: string; - site_legal: AdminSettingsLegal; + site_security: AdminSettingsSecurity; } export interface AdminSettingBranding { @@ -430,7 +437,6 @@ export interface AdminSettingBranding { } export interface AdminSettingsLegal { - external_content_display: string; privacy_policy_original_text?: string; privacy_policy_parsed_text?: string; terms_of_service_original_text?: string; @@ -438,12 +444,6 @@ export interface AdminSettingsLegal { } export interface AdminSettingsWrite { - restrict_answer?: boolean; - min_tags?: number; - min_content?: number; - recommend_tags?: Tag[]; - required_tag?: boolean; - reserved_tags?: Tag[]; max_image_size?: number; max_attachment_size?: number; max_image_megapixel?: number; @@ -484,7 +484,6 @@ export interface AdminSettingsCustom { export interface AdminSettingsLogin { allow_new_registrations: boolean; - login_required: boolean; allow_email_registrations: boolean; allow_email_domains: string[]; allow_password_login: boolean; @@ -809,3 +808,15 @@ export interface BadgeDetailListRes { count: number; list: BadgeDetailListItem[]; } + +export interface AdminQuestionSetting { + min_tags: number; + min_content: number; + restrict_answer: boolean; +} + +export interface AdminTagsSetting { + recommend_tags: Tag[]; + required_tag: boolean; + reserved_tags: Tag[]; +} diff --git a/ui/src/components/AccordionNav/index.tsx b/ui/src/components/AccordionNav/index.tsx index ee0819787..583c01987 100644 --- a/ui/src/components/AccordionNav/index.tsx +++ b/ui/src/components/AccordionNav/index.tsx @@ -28,16 +28,32 @@ import { floppyNavigation } from '@/utils'; import { Icon } from '@/components'; import './index.css'; +export interface MenuItem { + name: string; + path?: string; + pathPrefix?: string; + icon?: string; + displayName?: string; + badgeContent?: string | number; + children?: MenuItem[]; +} + function MenuNode({ menu, callback, activeKey, expanding = false, path = '/', +}: { + menu: MenuItem; + callback: (evt: any, menu: MenuItem, href: string, isLeaf: boolean) => void; + activeKey: string; + expanding?: boolean; + path?: string; }) { const { t } = useTranslation('translation', { keyPrefix: 'nav_menus' }); - const isLeaf = !menu.children.length; - const href = isLeaf ? `${path}${menu.path}` : '#'; + const isLeaf = !menu.children || menu.children.length === 0; + const href = isLeaf ? `${path}${menu.path || ''}` : '#'; return ( @@ -51,7 +67,14 @@ function MenuNode({ }} className={classNames( 'text-nowrap d-flex flex-nowrap align-items-center w-100', - { expanding, active: activeKey === menu.path }, + { + expanding, + active: + activeKey === menu.path || + (menu.path && activeKey.startsWith(`${menu.path}/`)) || + // if pathPrefix is set, activate when activeKey starts with the pathPrefix + (menu.pathPrefix && activeKey.startsWith(menu.pathPrefix)), + }, )}> {menu?.icon && } @@ -75,7 +98,13 @@ function MenuNode({ }} className={classNames( 'text-nowrap d-flex flex-nowrap align-items-center w-100', - { expanding, active: activeKey === menu.path }, + { + expanding, + active: + activeKey === menu.path || + (menu.path && activeKey.startsWith(`${menu.path}/`)) || + (menu.pathPrefix && activeKey.startsWith(menu.pathPrefix)), + }, )}> {menu?.icon && } @@ -90,8 +119,8 @@ function MenuNode({ )} - {menu.children.length ? ( - + {menu.children && menu.children.length > 0 ? ( + <> {menu.children.map((leaf) => { return ( @@ -100,7 +129,7 @@ function MenuNode({ callback={callback} activeKey={activeKey} path={path} - key={leaf.path} + key={leaf.path || leaf.name} /> ); })} @@ -112,7 +141,7 @@ function MenuNode({ } interface AccordionProps { - menus: any[]; + menus: MenuItem[]; path?: string; } const AccordionNav: FC = ({ menus = [], path = '/' }) => { @@ -137,19 +166,27 @@ const AccordionNav: FC = ({ menus = [], path = '/' }) => { }); const splat = pathMatch && pathMatch.params['*']; - let activeKey = menus[0].path; + let activeKey: string = menus[0]?.path || menus[0]?.name || ''; + if (splat) { activeKey = splat; } + const getOpenKey = () => { let openKey = ''; menus.forEach((li) => { - if (li.children.length) { + if (li.children && li.children.length > 0) { const matchedChild = li.children.find((el) => { - return el.path === activeKey; + // exact match or path prefix match + return ( + el.path === activeKey || + (el.path && activeKey.startsWith(`${el.path}/`)) || + // if pathPrefix is set, activate when activeKey starts with the pathPrefix + (el.pathPrefix && activeKey.startsWith(el.pathPrefix)) + ); }); if (matchedChild) { - openKey = li.path; + openKey = li.path || li.name || ''; } } }); @@ -181,8 +218,8 @@ const AccordionNav: FC = ({ menus = [], path = '/' }) => { path={path} callback={menuClick} activeKey={activeKey} - expanding={openKey === li.path} - key={li.path} + expanding={openKey === (li.path || li.name)} + key={li.path || li.name} /> ); })} diff --git a/ui/src/components/AdminSideNav/index.tsx b/ui/src/components/AdminSideNav/index.tsx index a2d36fbd4..b6c4d4bca 100644 --- a/ui/src/components/AdminSideNav/index.tsx +++ b/ui/src/components/AdminSideNav/index.tsx @@ -24,6 +24,7 @@ import { useTranslation } from 'react-i18next'; import cloneDeep from 'lodash/cloneDeep'; import { AccordionNav, Icon } from '@/components'; +import type { MenuItem } from '@/components/AccordionNav'; import { ADMIN_NAV_MENUS } from '@/common/constants'; import { useQueryPlugins } from '@/services'; import { interfaceStore } from '@/stores'; @@ -37,16 +38,18 @@ const AdminSideNav = () => { have_config: true, }); - const menus = cloneDeep(ADMIN_NAV_MENUS); + const menus = cloneDeep(ADMIN_NAV_MENUS) as MenuItem[]; if (configurablePlugins && configurablePlugins.length > 0) { menus.forEach((item) => { if (item.name === 'plugins' && item.children) { item.children = [ ...item.children, - ...configurablePlugins.map((plugin) => ({ - name: plugin.slug_name, - displayName: plugin.name, - })), + ...configurablePlugins.map( + (plugin): MenuItem => ({ + name: plugin.slug_name, + displayName: plugin.name, + }), + ), ]; } }); diff --git a/ui/src/components/SchemaForm/components/Switch.tsx b/ui/src/components/SchemaForm/components/Switch.tsx index 336142ae1..81f928d38 100644 --- a/ui/src/components/SchemaForm/components/Switch.tsx +++ b/ui/src/components/SchemaForm/components/Switch.tsx @@ -51,6 +51,7 @@ const Index: FC = ({ onChange(state); } }; + return ( = ({ checked={fieldObject?.value || ''} feedback={fieldObject?.errorMsg} feedbackType="invalid" - isInvalid={fieldObject.isInvalid} + isInvalid={fieldObject?.isInvalid} disabled={readOnly} onChange={handleChange} /> diff --git a/ui/src/components/SchemaForm/index.tsx b/ui/src/components/SchemaForm/index.tsx index 171b5f675..01f506813 100644 --- a/ui/src/components/SchemaForm/index.tsx +++ b/ui/src/components/SchemaForm/index.tsx @@ -290,7 +290,7 @@ const SchemaForm: ForwardRefRenderFunction = ( controlId={key} className={classnames( groupClassName, - formData[key].hidden ? 'd-none' : null, + formData[key]?.hidden ? 'd-none' : null, )}> {/* Uniform processing `label` */} {title && !uiSimplify ? {title} : null} @@ -437,12 +437,12 @@ const SchemaForm: ForwardRefRenderFunction = ( /> ) : null} {/* Unified handling of `Feedback` and `Text` */} - - {fieldState?.errorMsg} - {description && widget !== 'tag_selector' ? ( ) : null} + + {fieldState?.errorMsg} + ); })} diff --git a/ui/src/components/SchemaForm/types.ts b/ui/src/components/SchemaForm/types.ts index 55cf8e99d..25e5c56c3 100644 --- a/ui/src/components/SchemaForm/types.ts +++ b/ui/src/components/SchemaForm/types.ts @@ -44,7 +44,7 @@ export interface JSONSchema { required?: string[]; properties: { [key: string]: { - type?: 'string' | 'boolean' | 'number'; + type?: 'string' | 'boolean' | 'number' | Type.Tag[]; title: string; description?: string; enum?: Array; diff --git a/ui/src/components/TabNav/index.tsx b/ui/src/components/TabNav/index.tsx new file mode 100644 index 000000000..482cd0cf0 --- /dev/null +++ b/ui/src/components/TabNav/index.tsx @@ -0,0 +1,26 @@ +import { FC } from 'react'; +import { Nav } from 'react-bootstrap'; +import { NavLink, useLocation } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; + +const TabNav: FC<{ menus: { name: string; path: string }[] }> = ({ menus }) => { + const { t } = useTranslation('translation', { keyPrefix: 'nav_menus' }); + const { pathname } = useLocation(); + return ( + + ); +}; + +export default TabNav; diff --git a/ui/src/components/index.ts b/ui/src/components/index.ts index 68e863d2f..416db241c 100644 --- a/ui/src/components/index.ts +++ b/ui/src/components/index.ts @@ -64,6 +64,7 @@ import CardBadge from './CardBadge'; import PinList from './PinList'; import MobileSideNav from './MobileSideNav'; import AdminSideNav from './AdminSideNav'; +import TabNav from './TabNav'; export { Avatar, @@ -115,5 +116,6 @@ export { PinList, MobileSideNav, AdminSideNav, + TabNav, }; export type { EditorRef, JSONSchema, UISchema }; diff --git a/ui/src/pages/Admin/Answers/index.tsx b/ui/src/pages/Admin/Answers/index.tsx index 07190024f..9909739f5 100644 --- a/ui/src/pages/Admin/Answers/index.tsx +++ b/ui/src/pages/Admin/Answers/index.tsx @@ -32,8 +32,9 @@ import { Empty, QueryGroup, Modal, + TabNav, } from '@/components'; -import { ADMIN_LIST_STATUS } from '@/common/constants'; +import { ADMIN_LIST_STATUS, ADMIN_QA_NAV_MENUS } from '@/common/constants'; import * as Type from '@/common/interface'; import { deletePermanently, useAnswerSearch } from '@/services'; import { escapeRemove } from '@/utils'; @@ -96,7 +97,10 @@ const Answers: FC = () => { }; return ( <> -

        {t('page_title')}

        +

        + {t('page_title', { keyPrefix: 'admin.questions' })} +

        +
        { return (

        {t('page_title')}

        - +
        + +
        ); }; diff --git a/ui/src/pages/Admin/CssAndHtml/index.tsx b/ui/src/pages/Admin/CssAndHtml/index.tsx index 422659afc..557ffa3c6 100644 --- a/ui/src/pages/Admin/CssAndHtml/index.tsx +++ b/ui/src/pages/Admin/CssAndHtml/index.tsx @@ -151,13 +151,15 @@ const Index: FC = () => { return ( <>

        {t('customize', { keyPrefix: 'nav_menus' })}

        - +
        + +
        ); }; diff --git a/ui/src/pages/Admin/Dashboard/components/HealthStatus/index.tsx b/ui/src/pages/Admin/Dashboard/components/HealthStatus/index.tsx index 137fcd2e1..9a79edd92 100644 --- a/ui/src/pages/Admin/Dashboard/components/HealthStatus/index.tsx +++ b/ui/src/pages/Admin/Dashboard/components/HealthStatus/index.tsx @@ -23,7 +23,7 @@ import { useTranslation } from 'react-i18next'; import { Link } from 'react-router-dom'; import type * as Type from '@/common/interface'; -import { siteInfoStore } from '@/stores'; +import { siteSecurityStore } from '@/stores'; const { gt, gte } = require('semver'); @@ -34,7 +34,7 @@ interface IProps { const HealthStatus: FC = ({ data }) => { const { t } = useTranslation('translation', { keyPrefix: 'admin.dashboard' }); const { version, remote_version } = data.version_info || {}; - const { siteInfo } = siteInfoStore(); + const { check_update } = siteSecurityStore.getState(); let isLatest = false; let hasNewerVersion = false; const downloadUrl = `https://answer.apache.org/download?from_version=${version}`; @@ -68,7 +68,7 @@ const HealthStatus: FC = ({ data }) => { {t('update_to')} {remote_version} )} - {!isLatest && !remote_version && siteInfo.check_update && ( + {!isLatest && !remote_version && check_update && ( { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.write', + }); + const Toast = useToast(); + + const [formData, setFormData] = useState(initFormData); + + const handleValueChange = (value) => { + setFormData({ + ...formData, + ...value, + }); + }; + + const onSubmit = (evt) => { + evt.preventDefault(); + evt.stopPropagation(); + + const reqParams: Type.AdminSettingsWrite = { + max_image_size: Number(formData.max_image_size.value), + max_attachment_size: Number(formData.max_attachment_size.value), + max_image_megapixel: Number(formData.max_image_megapixel.value), + authorized_image_extensions: + formData.authorized_image_extensions.value?.length > 0 + ? formData.authorized_image_extensions.value + .split(',') + ?.map((item) => item.trim().toLowerCase()) + : [], + authorized_attachment_extensions: + formData.authorized_attachment_extensions.value?.length > 0 + ? formData.authorized_attachment_extensions.value + .split(',') + ?.map((item) => item.trim().toLowerCase()) + : [], + }; + updateAdminFilesSetting(reqParams) + .then(() => { + Toast.onShow({ + msg: t('update', { keyPrefix: 'toast' }), + variant: 'success', + }); + writeSettingStore.getState().update({ ...reqParams }); + }) + .catch((err) => { + if (err.isError) { + const data = handleFormError(err, formData); + setFormData({ ...data }); + const ele = document.getElementById(err.list[0].error_field); + scrollToElementTop(ele); + } + }); + }; + + const initData = () => { + getAdminFilesSetting().then((res) => { + formData.max_image_size.value = res.max_image_size; + formData.max_attachment_size.value = res.max_attachment_size; + formData.max_image_megapixel.value = res.max_image_megapixel; + formData.authorized_image_extensions.value = + res.authorized_image_extensions?.join(', ').toLowerCase(); + formData.authorized_attachment_extensions.value = + res.authorized_attachment_extensions?.join(', ').toLowerCase(); + setFormData({ ...formData }); + }); + }; + + useEffect(() => { + initData(); + }, []); + + return ( + <> +

        {t('page_title')}

        +
        +
        + + {t('image_size.label')} + { + handleValueChange({ + max_image_size: { + value: evt.target.value, + errorMsg: '', + isInvalid: false, + }, + }); + }} + /> + {t('image_size.text')} + + {formData.max_image_size.errorMsg} + + + + + {t('attachment_size.label')} + { + handleValueChange({ + max_attachment_size: { + value: evt.target.value, + errorMsg: '', + isInvalid: false, + }, + }); + }} + /> + {t('attachment_size.text')} + + {formData.max_attachment_size.errorMsg} + + + + + {t('image_megapixels.label')} + { + handleValueChange({ + max_image_megapixel: { + value: evt.target.value, + errorMsg: '', + isInvalid: false, + }, + }); + }} + /> + {t('image_megapixels.text')} + + {formData.max_image_megapixel.errorMsg} + + + + + {t('image_extensions.label')} + { + handleValueChange({ + authorized_image_extensions: { + value: evt.target.value.toLowerCase(), + errorMsg: '', + isInvalid: false, + }, + }); + }} + /> + {t('image_extensions.text')} + + {formData.authorized_image_extensions.errorMsg} + + + + + {t('attachment_extensions.label')} + { + handleValueChange({ + authorized_attachment_extensions: { + value: evt.target.value.toLowerCase(), + errorMsg: '', + isInvalid: false, + }, + }); + }} + /> + {t('attachment_extensions.text')} + + {formData.authorized_attachment_extensions.errorMsg} + + + + + + + +
        + + ); +}; + +export default Index; diff --git a/ui/src/pages/Admin/General/index.tsx b/ui/src/pages/Admin/General/index.tsx index ce2cdeb59..57602f453 100644 --- a/ui/src/pages/Admin/General/index.tsx +++ b/ui/src/pages/Admin/General/index.tsx @@ -70,11 +70,6 @@ const General: FC = () => { title: t('contact_email.label'), description: t('contact_email.text'), }, - check_update: { - type: 'boolean', - title: t('check_update.label'), - default: true, - }, }, }; const uiSchema: UISchema = { @@ -114,12 +109,6 @@ const General: FC = () => { }, }, }, - check_update: { - 'ui:widget': 'switch', - 'ui:options': { - label: t('check_update.text'), - }, - }, }; const [formData, setFormData] = useState( initFormData(schema), @@ -134,7 +123,6 @@ const General: FC = () => { short_description: formData.short_description.value, site_url: formData.site_url.value, contact_email: formData.contact_email.value, - check_update: formData.check_update.value, }; updateGeneralSetting(reqParams) @@ -149,7 +137,6 @@ const General: FC = () => { formData.short_description.value = res.short_description; formData.site_url.value = res.site_url; formData.contact_email.value = res.contact_email; - formData.check_update.value = res.check_update; } setFormData({ ...formData }); @@ -183,13 +170,15 @@ const General: FC = () => { return ( <>

        {t('page_title')}

        - +
        + +
        ); }; diff --git a/ui/src/pages/Admin/Interface/index.tsx b/ui/src/pages/Admin/Interface/index.tsx index 865029e9c..49e5175d0 100644 --- a/ui/src/pages/Admin/Interface/index.tsx +++ b/ui/src/pages/Admin/Interface/index.tsx @@ -28,7 +28,7 @@ import { } from '@/common/interface'; import { interfaceStore, loggedUserInfoStore } from '@/stores'; import { JSONSchema, SchemaForm, UISchema } from '@/components'; -import { DEFAULT_TIMEZONE, SYSTEM_AVATAR_OPTIONS } from '@/common/constants'; +import { DEFAULT_TIMEZONE } from '@/common/constants'; import { updateInterfaceSetting, useInterfaceSetting, @@ -68,20 +68,6 @@ const Interface: FC = () => { description: t('time_zone.text'), default: setting?.time_zone || DEFAULT_TIMEZONE, }, - default_avatar: { - type: 'string', - title: t('avatar.label'), - description: t('avatar.text'), - enum: SYSTEM_AVATAR_OPTIONS?.map((v) => v.value), - enumNames: SYSTEM_AVATAR_OPTIONS?.map((v) => v.label), - default: setting?.default_avatar || 'system', - }, - gravatar_base_url: { - type: 'string', - title: t('gravatar_base_url.label'), - description: t('gravatar_base_url.text'), - default: setting?.gravatar_base_url || '', - }, }, }; @@ -96,16 +82,6 @@ const Interface: FC = () => { isInvalid: false, errorMsg: '', }, - default_avatar: { - value: setting?.default_avatar || 'system', - isInvalid: false, - errorMsg: '', - }, - gravatar_base_url: { - value: setting?.gravatar_base_url || '', - isInvalid: false, - errorMsg: '', - }, }); const uiSchema: UISchema = { @@ -115,15 +91,6 @@ const Interface: FC = () => { time_zone: { 'ui:widget': 'timezone', }, - default_avatar: { - 'ui:widget': 'select', - }, - gravatar_base_url: { - 'ui:widget': 'input', - 'ui:options': { - placeholder: 'https://www.gravatar.com/avatar/', - }, - }, }; const getLangs = async () => { const res: LangsType[] = await loadLanguageOptions(true); @@ -156,8 +123,6 @@ const Interface: FC = () => { const reqParams: AdminSettingsInterface = { language: formData.language.value, time_zone: formData.time_zone.value, - default_avatar: formData.default_avatar.value, - gravatar_base_url: formData.gravatar_base_url.value, }; updateInterfaceSetting(reqParams) @@ -185,20 +150,18 @@ const Interface: FC = () => { useEffect(() => { if (setting) { - const formMeta = {}; - Object.keys(setting).forEach((k) => { - let v = setting[k]; - if (k === 'default_avatar' && !v) { - v = 'system'; - } - if (k === 'gravatar_base_url' && !v) { - v = ''; - } - formMeta[k] = { ...formData[k], value: v }; - }); + const formMeta = { ...formData }; + if (setting.language) { + formMeta.language.value = setting.language; + } else { + formMeta.language.value = storeInterface.language || langs?.[0]?.value; + } + if (setting.time_zone) { + formMeta.time_zone.value = setting.time_zone; + } setFormData({ ...formData, ...formMeta }); } - }, [setting]); + }, [setting, langs]); useEffect(() => { getLangs(); }, []); @@ -209,13 +172,15 @@ const Interface: FC = () => { return ( <>

        {t('page_title')}

        - +
        + +
        ); }; diff --git a/ui/src/pages/Admin/Login/index.tsx b/ui/src/pages/Admin/Login/index.tsx index c43cfcffb..a4a61152f 100644 --- a/ui/src/pages/Admin/Login/index.tsx +++ b/ui/src/pages/Admin/Login/index.tsx @@ -58,12 +58,6 @@ const Index: FC = () => { title: t('allowed_email_domains.title'), description: t('allowed_email_domains.text'), }, - login_required: { - type: 'boolean', - title: t('private.title'), - description: t('private.text'), - default: false, - }, }, }; const uiSchema: UISchema = { @@ -88,12 +82,6 @@ const Index: FC = () => { allow_email_domains: { 'ui:widget': 'textarea', }, - login_required: { - 'ui:widget': 'switch', - 'ui:options': { - label: t('private.label'), - }, - }, }; const [formData, setFormData] = useState(initFormData(schema)); const { update: updateLoginSetting } = loginSettingStore((_) => _); @@ -116,7 +104,6 @@ const Index: FC = () => { allow_new_registrations: formData.allow_new_registrations.value, allow_email_registrations: formData.allow_email_registrations.value, allow_email_domains: allowedEmailDomains, - login_required: formData.login_required.value, allow_password_login: formData.allow_password_login.value, }; @@ -151,7 +138,6 @@ const Index: FC = () => { formMeta.allow_email_domains.value = setting.allow_email_domains.join('\n'); } - formMeta.login_required.value = setting.login_required; formMeta.allow_password_login.value = setting.allow_password_login; setFormData({ ...formMeta }); } @@ -165,13 +151,15 @@ const Index: FC = () => { return ( <>

        {t('page_title')}

        - +
        + +
        ); }; diff --git a/ui/src/pages/Admin/Plugins/Config/index.tsx b/ui/src/pages/Admin/Plugins/Config/index.tsx index 7c47d0162..44d83ad68 100644 --- a/ui/src/pages/Admin/Plugins/Config/index.tsx +++ b/ui/src/pages/Admin/Plugins/Config/index.tsx @@ -114,14 +114,16 @@ const Config = () => { return ( <>

        {data?.name}

        - +
        + +
        ); }; diff --git a/ui/src/pages/Admin/Legal/index.tsx b/ui/src/pages/Admin/Policies/index.tsx similarity index 70% rename from ui/src/pages/Admin/Legal/index.tsx rename to ui/src/pages/Admin/Policies/index.tsx index 4a4e4ea1a..7170c39ff 100644 --- a/ui/src/pages/Admin/Legal/index.tsx +++ b/ui/src/pages/Admin/Policies/index.tsx @@ -23,11 +23,17 @@ import { useTranslation } from 'react-i18next'; import { marked } from 'marked'; import type * as Type from '@/common/interface'; -import { SchemaForm, JSONSchema, initFormData, UISchema } from '@/components'; +import { + SchemaForm, + JSONSchema, + initFormData, + UISchema, + TabNav, +} from '@/components'; import { useToast } from '@/hooks'; -import { getLegalSetting, putLegalSetting } from '@/services'; +import { getPoliciesSetting, putPoliciesSetting } from '@/services'; import { handleFormError, scrollToElementTop } from '@/utils'; -import { siteLealStore } from '@/stores'; +import { ADMIN_RULES_NAV_MENUS } from '@/common/constants'; const Legal: FC = () => { const { t } = useTranslation('translation', { @@ -35,29 +41,10 @@ const Legal: FC = () => { }); const Toast = useToast(); - const externalContent = [ - { - value: 'always_display', - label: t('external_content_display.always_display'), - }, - { - value: 'ask_before_display', - label: t('external_content_display.ask_before_display'), - }, - ]; - const schema: JSONSchema = { title: t('page_title'), required: ['terms_of_service', 'privacy_policy'], properties: { - external_content_display: { - type: 'string', - title: t('external_content_display.label'), - description: t('external_content_display.text'), - enum: externalContent?.map((lang) => lang.value), - enumNames: externalContent?.map((lang) => lang.label), - default: 0, - }, terms_of_service: { type: 'string', title: t('terms_of_service.label'), @@ -71,9 +58,6 @@ const Legal: FC = () => { }, }; const uiSchema: UISchema = { - external_content_display: { - 'ui:widget': 'select', - }, terms_of_service: { 'ui:widget': 'textarea', 'ui:options': { @@ -94,7 +78,6 @@ const Legal: FC = () => { evt.stopPropagation(); const reqParams: Type.AdminSettingsLegal = { - external_content_display: formData.external_content_display.value, terms_of_service_original_text: formData.terms_of_service.value, terms_of_service_parsed_text: marked.parse( formData.terms_of_service.value, @@ -103,15 +86,12 @@ const Legal: FC = () => { privacy_policy_parsed_text: marked.parse(formData.privacy_policy.value), }; - putLegalSetting(reqParams) + putPoliciesSetting(reqParams) .then(() => { Toast.onShow({ msg: t('update', { keyPrefix: 'toast' }), variant: 'success', }); - siteLealStore.getState().update({ - external_content_display: reqParams.external_content_display, - }); }) .catch((err) => { if (err.isError) { @@ -124,11 +104,9 @@ const Legal: FC = () => { }; useEffect(() => { - getLegalSetting().then((setting) => { + getPoliciesSetting().then((setting) => { if (setting) { const formMeta = { ...formData }; - formMeta.external_content_display.value = - setting.external_content_display; formMeta.terms_of_service.value = setting.terms_of_service_original_text; formMeta.privacy_policy.value = setting.privacy_policy_original_text; @@ -143,14 +121,17 @@ const Legal: FC = () => { return ( <> -

        {t('page_title')}

        - +

        {t('rules', { keyPrefix: 'nav_menus' })}

        + +
        + +
        ); }; diff --git a/ui/src/pages/Admin/Privileges/index.tsx b/ui/src/pages/Admin/Privileges/index.tsx index f0930c7af..9ab775dc4 100644 --- a/ui/src/pages/Admin/Privileges/index.tsx +++ b/ui/src/pages/Admin/Privileges/index.tsx @@ -22,7 +22,13 @@ import { useTranslation } from 'react-i18next'; import { useToast } from '@/hooks'; import { FormDataType } from '@/common/interface'; -import { JSONSchema, SchemaForm, UISchema, initFormData } from '@/components'; +import { + JSONSchema, + SchemaForm, + UISchema, + initFormData, + TabNav, +} from '@/components'; import { getPrivilegeSetting, putPrivilegeSetting, @@ -30,7 +36,10 @@ import { AdminSettingsPrivilegeReq, } from '@/services'; import { handleFormError, scrollToElementTop } from '@/utils'; -import { ADMIN_PRIVILEGE_CUSTOM_LEVEL } from '@/common/constants'; +import { + ADMIN_PRIVILEGE_CUSTOM_LEVEL, + ADMIN_RULES_NAV_MENUS, +} from '@/common/constants'; const Index: FC = () => { const { t } = useTranslation('translation', { @@ -187,14 +196,17 @@ const Index: FC = () => { return ( <> -

        {t('title')}

        - +

        {t('rules', { keyPrefix: 'nav_menus' })}

        + +
        + +
        ); }; diff --git a/ui/src/pages/Admin/QaSettings/index.tsx b/ui/src/pages/Admin/QaSettings/index.tsx new file mode 100644 index 000000000..0c2636eae --- /dev/null +++ b/ui/src/pages/Admin/QaSettings/index.tsx @@ -0,0 +1,132 @@ +import { useState, useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { + SchemaForm, + JSONSchema, + UISchema, + initFormData, + TabNav, +} from '@/components'; +import { ADMIN_QA_NAV_MENUS } from '@/common/constants'; +import * as Type from '@/common/interface'; +import { writeSettingStore } from '@/stores'; +import { + getQuestionSetting, + updateQuestionSetting, +} from '@/services/admin/question'; +import { handleFormError, scrollToElementTop } from '@/utils'; +import { useToast } from '@/hooks'; + +const QaSettings = () => { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.write', + }); + const Toast = useToast(); + const schema: JSONSchema = { + title: t('page_title'), + properties: { + min_tags: { + type: 'number', + title: t('min_tags.label'), + description: t('min_tags.text'), + }, + min_content: { + type: 'number', + title: t('min_content.label'), + description: t('min_content.text'), + }, + restrict_answer: { + type: 'boolean', + title: t('restrict_answer.label'), + description: t('restrict_answer.text'), + }, + }, + }; + const uiSchema: UISchema = { + min_tags: { + 'ui:widget': 'input', + 'ui:options': { + inputType: 'number', + }, + }, + min_content: { + 'ui:widget': 'input', + 'ui:options': { + inputType: 'number', + }, + }, + restrict_answer: { + 'ui:widget': 'switch', + 'ui:options': { + label: t('restrict_answer.label'), + }, + }, + }; + const [formData, setFormData] = useState( + initFormData(schema), + ); + + const handleValueChange = (data: Type.FormDataType) => { + setFormData(data); + }; + + const onSubmit = (evt) => { + evt.preventDefault(); + evt.stopPropagation(); + // TODO: submit data + const reqParams: Type.AdminQuestionSetting = { + min_tags: formData.min_tags.value, + min_content: formData.min_content.value, + restrict_answer: formData.restrict_answer.value, + }; + updateQuestionSetting(reqParams) + .then(() => { + Toast.onShow({ + msg: t('update', { keyPrefix: 'toast' }), + variant: 'success', + }); + writeSettingStore.getState().update({ ...reqParams }); + }) + .catch((err) => { + if (err.isError) { + const data = handleFormError(err, formData); + setFormData({ ...data }); + const ele = document.getElementById(err.list[0].error_field); + scrollToElementTop(ele); + } + }); + }; + + useEffect(() => { + getQuestionSetting().then((res) => { + if (res) { + const formMeta = { ...formData }; + formMeta.min_tags.value = res.min_tags; + formMeta.min_content.value = res.min_content; + formMeta.restrict_answer.value = res.restrict_answer; + setFormData(formMeta); + } + }); + }, []); + + return ( + <> +

        + {t('page_title', { keyPrefix: 'admin.questions' })} +

        + +
        + +
        + + ); +}; + +export default QaSettings; diff --git a/ui/src/pages/Admin/Questions/index.tsx b/ui/src/pages/Admin/Questions/index.tsx index 494effe68..ffd9f6096 100644 --- a/ui/src/pages/Admin/Questions/index.tsx +++ b/ui/src/pages/Admin/Questions/index.tsx @@ -32,8 +32,9 @@ import { Empty, QueryGroup, Modal, + TabNav, } from '@/components'; -import { ADMIN_LIST_STATUS } from '@/common/constants'; +import { ADMIN_LIST_STATUS, ADMIN_QA_NAV_MENUS } from '@/common/constants'; import * as Type from '@/common/interface'; import { deletePermanently, useQuestionSearch } from '@/services'; import { pathFactory } from '@/router/pathFactory'; @@ -95,6 +96,7 @@ const Questions: FC = () => { return ( <>

        {t('page_title')}

        +
        { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.security', + }); + const Toast = useToast(); + const externalContent = [ + { + value: 'always_display', + label: t('external_content_display.always_display', { + keyPrefix: 'admin.legal', + }), + }, + { + value: 'ask_before_display', + label: t('external_content_display.ask_before_display', { + keyPrefix: 'admin.legal', + }), + }, + ]; + + const schema: JSONSchema = { + title: t('page_title'), + properties: { + login_required: { + type: 'boolean', + title: t('private.title', { keyPrefix: 'admin.login' }), + description: t('private.text', { keyPrefix: 'admin.login' }), + default: false, + }, + external_content_display: { + type: 'string', + title: t('external_content_display.label', { + keyPrefix: 'admin.legal', + }), + description: t('external_content_display.text', { + keyPrefix: 'admin.legal', + }), + enum: externalContent?.map((lang) => lang.value), + enumNames: externalContent?.map((lang) => lang.label), + default: 0, + }, + check_update: { + type: 'boolean', + title: t('check_update.label', { keyPrefix: 'admin.general' }), + default: true, + }, + }, + }; + const uiSchema: UISchema = { + login_required: { + 'ui:widget': 'switch', + 'ui:options': { + label: t('private.label', { keyPrefix: 'admin.login' }), + }, + }, + external_content_display: { + 'ui:widget': 'select', + 'ui:options': { + label: t('external_content_display.label', { + keyPrefix: 'admin.legal', + }), + }, + }, + check_update: { + 'ui:widget': 'switch', + 'ui:options': { + label: t('check_update.label', { keyPrefix: 'admin.general' }), + }, + }, + }; + const [formData, setFormData] = useState(initFormData(schema)); + + const handleValueChange = (data: Type.FormDataType) => { + setFormData(data); + }; + + const onSubmit = (evt) => { + evt.preventDefault(); + evt.stopPropagation(); + const reqParams = { + login_required: formData.login_required.value, + external_content_display: formData.external_content_display.value, + check_update: formData.check_update.value, + }; + putSecuritySetting(reqParams) + .then(() => { + Toast.onShow({ + msg: t('update', { keyPrefix: 'toast' }), + variant: 'success', + }); + siteSecurityStore.getState().update(reqParams); + }) + .catch((err) => { + if (err.isError) { + const data = handleFormError(err, formData); + setFormData({ ...data }); + const ele = document.getElementById(err.list[0].error_field); + scrollToElementTop(ele); + } + }); + }; + + useEffect(() => { + getSecuritySetting().then((setting) => { + if (setting) { + const formMeta = { ...formData }; + formMeta.login_required.value = setting.login_required; + formMeta.external_content_display.value = + setting.external_content_display; + formMeta.check_update.value = setting.check_update; + setFormData(formMeta); + } + }); + }, []); + + return ( + <> +

        {t('security', { keyPrefix: 'nav_menus' })}

        +
        + +
        + + ); +}; + +export default Security; diff --git a/ui/src/pages/Admin/Seo/index.tsx b/ui/src/pages/Admin/Seo/index.tsx index e539595bd..0675479d7 100644 --- a/ui/src/pages/Admin/Seo/index.tsx +++ b/ui/src/pages/Admin/Seo/index.tsx @@ -117,13 +117,15 @@ const Index: FC = () => { return ( <>

        {t('page_title')}

        - +
        + +
        ); }; diff --git a/ui/src/pages/Admin/Smtp/index.tsx b/ui/src/pages/Admin/Smtp/index.tsx index 85a1b9760..595387512 100644 --- a/ui/src/pages/Admin/Smtp/index.tsx +++ b/ui/src/pages/Admin/Smtp/index.tsx @@ -224,13 +224,15 @@ const Smtp: FC = () => { return ( <>

        {t('page_title')}

        - +
        + +
        ); }; diff --git a/ui/src/pages/Admin/TagsSettings/index.tsx b/ui/src/pages/Admin/TagsSettings/index.tsx new file mode 100644 index 000000000..f2ab2f5b1 --- /dev/null +++ b/ui/src/pages/Admin/TagsSettings/index.tsx @@ -0,0 +1,170 @@ +import { useState, useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { + SchemaForm, + JSONSchema, + UISchema, + initFormData, + TabNav, +} from '@/components'; +import { ADMIN_TAGS_NAV_MENUS } from '@/common/constants'; +import * as Type from '@/common/interface'; +import { handleFormError, scrollToElementTop } from '@/utils'; +import { writeSettingStore } from '@/stores'; +import { getAdminTagsSetting, updateAdminTagsSetting } from '@/services/admin'; +import { useToast } from '@/hooks'; + +const QaSettings = () => { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.write', + }); + const Toast = useToast(); + const schema: JSONSchema = { + title: t('page_title'), + properties: { + reserved_tags: { + type: 'string', + title: t('reserved_tags.label'), + description: t('reserved_tags.text'), + }, + recommend_tags: { + type: 'string', + title: t('recommend_tags.label'), + description: t('recommend_tags.text'), + }, + required_tag: { + type: 'boolean', + title: t('required_tag.title'), + description: t('required_tag.text'), + }, + }, + }; + const uiSchema: UISchema = { + reserved_tags: { + 'ui:widget': 'tag_selector', + 'ui:options': { + label: t('reserved_tags.label'), + }, + }, + recommend_tags: { + 'ui:widget': 'tag_selector', + 'ui:options': { + label: t('recommend_tags.label'), + }, + }, + required_tag: { + 'ui:widget': 'switch', + 'ui:options': { + label: t('required_tag.label'), + }, + }, + }; + const [formData, setFormData] = useState( + initFormData(schema), + ); + + const handleValueChange = (data: Type.FormDataType) => { + setFormData(data); + }; + + const checkValidated = (): boolean => { + let bol = true; + const { recommend_tags, reserved_tags } = formData; + // 找出 recommend_tags 和 reserved_tags 中是否有重复的标签 + // 通过标签中的 slug_name 来去重 + const repeatTag = recommend_tags.value.filter((tag) => + reserved_tags.value.some((rTag) => rTag?.slug_name === tag?.slug_name), + ); + if (repeatTag.length > 0) { + handleValueChange({ + ...formData, + recommend_tags: { + ...recommend_tags, + errorMsg: t('recommend_tags.msg.contain_reserved'), + isInvalid: true, + }, + }); + bol = false; + const ele = document.getElementById('recommend_tags'); + scrollToElementTop(ele); + } else { + handleValueChange({ + ...formData, + recommend_tags: { + ...recommend_tags, + errorMsg: '', + isInvalid: false, + }, + }); + } + return bol; + }; + + const onSubmit = (evt) => { + evt.preventDefault(); + evt.stopPropagation(); + if (!checkValidated()) { + return; + } + const reqParams: Type.AdminTagsSetting = { + recommend_tags: formData.recommend_tags.value, + reserved_tags: formData.reserved_tags.value, + required_tag: formData.required_tag.value, + }; + updateAdminTagsSetting(reqParams) + .then(() => { + Toast.onShow({ + msg: t('update', { keyPrefix: 'toast' }), + variant: 'success', + }); + writeSettingStore.getState().update({ ...reqParams }); + }) + .catch((err) => { + if (err.isError) { + const data = handleFormError(err, formData); + setFormData({ ...data }); + const ele = document.getElementById(err.list[0].error_field); + scrollToElementTop(ele); + } + }); + }; + + useEffect(() => { + getAdminTagsSetting().then((res) => { + if (res) { + const formMeta = { ...formData }; + if (Array.isArray(res.recommend_tags)) { + formData.recommend_tags.value = res.recommend_tags; + } else { + formData.recommend_tags.value = []; + } + if (Array.isArray(res.reserved_tags)) { + formData.reserved_tags.value = res.reserved_tags; + } else { + formData.reserved_tags.value = []; + } + formMeta.required_tag.value = res.required_tag; + setFormData(formMeta); + } + }); + }, []); + + return ( + <> +

        {t('tags', { keyPrefix: 'nav_menus' })}

        + +
        + +
        + + ); +}; + +export default QaSettings; diff --git a/ui/src/pages/Admin/Themes/index.tsx b/ui/src/pages/Admin/Themes/index.tsx index 873dd7c9c..c6983cbec 100644 --- a/ui/src/pages/Admin/Themes/index.tsx +++ b/ui/src/pages/Admin/Themes/index.tsx @@ -205,13 +205,15 @@ const Index: FC = () => { return ( <>

        {t('page_title')}

        - +
        + +
        ); }; diff --git a/ui/src/pages/Admin/Users/index.tsx b/ui/src/pages/Admin/Users/index.tsx index 220429007..200aacf38 100644 --- a/ui/src/pages/Admin/Users/index.tsx +++ b/ui/src/pages/Admin/Users/index.tsx @@ -32,6 +32,7 @@ import { Empty, QueryGroup, Modal, + TabNav, } from '@/components'; import * as Type from '@/common/interface'; import { useUserModal } from '@/hooks'; @@ -45,6 +46,7 @@ import { deletePermanently, } from '@/services'; import { formatCount } from '@/utils'; +import { ADMIN_USERS_NAV_MENUS } from '@/common/constants'; import DeleteUserModal from './components/DeleteUserModal'; import Action from './components/Action'; @@ -208,6 +210,7 @@ const Users: FC = () => { return ( <>

        {t('title')}

        +
        { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.interface', + }); + const { data: setting } = useAdminUsersSettings(); + const Toast = useToast(); + const schema: JSONSchema = { + title: t('page_title'), + properties: { + default_avatar: { + type: 'string', + title: t('avatar.label'), + description: t('avatar.text'), + enum: SYSTEM_AVATAR_OPTIONS?.map((v) => v.value), + enumNames: SYSTEM_AVATAR_OPTIONS?.map((v) => v.label), + default: setting?.default_avatar || 'system', + }, + gravatar_base_url: { + type: 'string', + title: t('gravatar_base_url.label'), + description: t('gravatar_base_url.text'), + default: setting?.gravatar_base_url || '', + }, + }, + }; + + const [formData, setFormData] = useState({ + default_avatar: { + value: setting?.default_avatar || 'system', + isInvalid: false, + errorMsg: '', + }, + gravatar_base_url: { + value: setting?.gravatar_base_url || '', + isInvalid: false, + errorMsg: '', + }, + }); + + const uiSchema: UISchema = { + default_avatar: { + 'ui:widget': 'select', + }, + gravatar_base_url: { + 'ui:widget': 'input', + 'ui:options': { + placeholder: 'https://www.gravatar.com/avatar/', + }, + }, + }; + + const handleValueChange = (data: FormDataType) => { + setFormData(data); + }; + + const onSubmit = (evt) => { + evt.preventDefault(); + evt.stopPropagation(); + const reqParams = { + default_avatar: formData.default_avatar.value, + gravatar_base_url: formData.gravatar_base_url.value, + }; + updateAdminUsersSettings(reqParams) + .then(() => { + Toast.onShow({ + msg: t('update', { keyPrefix: 'toast' }), + variant: 'success', + }); + siteInfoStore.getState().updateUsers({ + ...siteInfoStore.getState().users, + ...reqParams, + }); + }) + .catch((err) => { + if (err.isError) { + const data = handleFormError(err, formData); + setFormData({ ...data }); + const ele = document.getElementById(err.list[0].error_field); + scrollToElementTop(ele); + } + }); + }; + + useEffect(() => { + if (setting) { + const formMeta = {}; + Object.keys(setting).forEach((k) => { + let v = setting[k]; + if (k === 'default_avatar' && !v) { + v = 'system'; + } + if (k === 'gravatar_base_url' && !v) { + v = ''; + } + formMeta[k] = { ...formData[k], value: v }; + }); + setFormData({ ...formData, ...formMeta }); + } + }, [setting]); + + return ( + <> +

        {t('tags', { keyPrefix: 'nav_menus' })}

        + +
        + +
        + + ); +}; + +export default UsersSettings; diff --git a/ui/src/pages/Admin/Write/index.tsx b/ui/src/pages/Admin/Write/index.tsx deleted file mode 100644 index fee2d28cc..000000000 --- a/ui/src/pages/Admin/Write/index.tsx +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { FC, useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { Form, Button } from 'react-bootstrap'; - -import { TagSelector } from '@/components'; -import type * as Type from '@/common/interface'; -import { useToast } from '@/hooks'; -import { - getRequireAndReservedTag, - postRequireAndReservedTag, -} from '@/services'; -import { handleFormError, scrollToElementTop } from '@/utils'; -import { writeSettingStore } from '@/stores'; - -const initFormData = { - reserved_tags: { - value: [] as Type.Tag[], // Replace `Type.Tag` with the correct type for `reserved_tags.value` - errorMsg: '', - isInvalid: false, - }, - min_content: { - value: 0, - errorMsg: '', - isInvalid: false, - }, - min_tags: { - value: 0, - errorMsg: '', - isInvalid: false, - }, - recommend_tags: { - value: [] as Type.Tag[], - errorMsg: '', - isInvalid: false, - }, - required_tag: { - value: false, - errorMsg: '', - isInvalid: false, - }, - restrict_answer: { - value: false, - errorMsg: '', - isInvalid: false, - }, - max_image_size: { - value: 0, - errorMsg: '', - isInvalid: false, - }, - max_attachment_size: { - value: 0, - errorMsg: '', - isInvalid: false, - }, - max_image_megapixel: { - value: 0, - errorMsg: '', - isInvalid: false, - }, - authorized_image_extensions: { - value: '', - errorMsg: '', - isInvalid: false, - }, - authorized_attachment_extensions: { - value: '', - errorMsg: '', - isInvalid: false, - }, -}; - -const Index: FC = () => { - const { t } = useTranslation('translation', { - keyPrefix: 'admin.write', - }); - const Toast = useToast(); - - const [formData, setFormData] = useState(initFormData); - - const handleValueChange = (value) => { - setFormData({ - ...formData, - ...value, - }); - }; - - const checkValidated = (): boolean => { - let bol = true; - const { recommend_tags, reserved_tags } = formData; - // 找出 recommend_tags 和 reserved_tags 中是否有重复的标签 - // 通过标签中的 slug_name 来去重 - const repeatTag = recommend_tags.value.filter((tag) => - reserved_tags.value.some((rTag) => rTag?.slug_name === tag?.slug_name), - ); - if (repeatTag.length > 0) { - handleValueChange({ - recommend_tags: { - ...recommend_tags, - errorMsg: t('recommend_tags.msg.contain_reserved'), - isInvalid: true, - }, - }); - bol = false; - const ele = document.getElementById('recommend_tags'); - scrollToElementTop(ele); - } else { - handleValueChange({ - recommend_tags: { - ...recommend_tags, - errorMsg: '', - isInvalid: false, - }, - }); - } - return bol; - }; - - const onSubmit = (evt) => { - evt.preventDefault(); - evt.stopPropagation(); - if (!checkValidated()) { - return; - } - const reqParams: Type.AdminSettingsWrite = { - recommend_tags: formData.recommend_tags.value, - min_tags: Number(formData.min_tags.value), - reserved_tags: formData.reserved_tags.value, - required_tag: formData.required_tag.value, - restrict_answer: formData.restrict_answer.value, - min_content: Number(formData.min_content.value), - max_image_size: Number(formData.max_image_size.value), - max_attachment_size: Number(formData.max_attachment_size.value), - max_image_megapixel: Number(formData.max_image_megapixel.value), - authorized_image_extensions: - formData.authorized_image_extensions.value?.length > 0 - ? formData.authorized_image_extensions.value - .split(',') - ?.map((item) => item.trim().toLowerCase()) - : [], - authorized_attachment_extensions: - formData.authorized_attachment_extensions.value?.length > 0 - ? formData.authorized_attachment_extensions.value - .split(',') - ?.map((item) => item.trim().toLowerCase()) - : [], - }; - postRequireAndReservedTag(reqParams) - .then(() => { - Toast.onShow({ - msg: t('update', { keyPrefix: 'toast' }), - variant: 'success', - }); - writeSettingStore - .getState() - .update({ restrict_answer: reqParams.restrict_answer, ...reqParams }); - }) - .catch((err) => { - if (err.isError) { - const data = handleFormError(err, formData); - setFormData({ ...data }); - const ele = document.getElementById(err.list[0].error_field); - scrollToElementTop(ele); - } - }); - }; - - const initData = () => { - getRequireAndReservedTag().then((res) => { - if (Array.isArray(res.recommend_tags)) { - formData.recommend_tags.value = res.recommend_tags; - } - formData.min_content.value = res.min_content; - formData.min_tags.value = res.min_tags; - formData.required_tag.value = res.required_tag; - formData.restrict_answer.value = res.restrict_answer; - if (Array.isArray(res.reserved_tags)) { - formData.reserved_tags.value = res.reserved_tags; - } - formData.max_image_size.value = res.max_image_size; - formData.max_attachment_size.value = res.max_attachment_size; - formData.max_image_megapixel.value = res.max_image_megapixel; - formData.authorized_image_extensions.value = - res.authorized_image_extensions?.join(', ').toLowerCase(); - formData.authorized_attachment_extensions.value = - res.authorized_attachment_extensions?.join(', ').toLowerCase(); - setFormData({ ...formData }); - }); - }; - - useEffect(() => { - initData(); - }, []); - - return ( - <> -

        {t('page_title')}

        -
        - - {t('reserved_tags.label')} - { - handleValueChange({ - reserved_tags: { - value: val, - errorMsg: '', - isInvalid: false, - }, - }); - }} - showRequiredTag={false} - maxTagLength={0} - tagStyleMode="simple" - formText={t('reserved_tags.text')} - isInvalid={formData.reserved_tags.isInvalid} - errMsg={formData.reserved_tags.errorMsg} - /> - - - - {t('recommend_tags.label')} - { - handleValueChange({ - recommend_tags: { - value: val, - errorMsg: '', - isInvalid: false, - }, - }); - }} - showRequiredTag={false} - tagStyleMode="simple" - formText={t('recommend_tags.text')} - isInvalid={formData.recommend_tags.isInvalid} - errMsg={formData.recommend_tags.errorMsg} - /> - - - {t('min_tags.label')} - { - handleValueChange({ - min_tags: { - value: evt.target.value, - errorMsg: '', - isInvalid: false, - }, - }); - }} - /> - {t('min_tags.text')} - - {formData.min_tags.errorMsg} - - - - {t('required_tag.title')} - { - handleValueChange({ - required_tag: { - value: evt.target.checked, - errorMsg: '', - isInvalid: false, - }, - }); - }} - /> - {t('required_tag.text')} - - {formData.required_tag.errorMsg} - - - - {t('min_content.label')} - { - handleValueChange({ - min_content: { - value: evt.target.value, - errorMsg: '', - isInvalid: false, - }, - }); - }} - /> - {t('min_content.text')} - - {formData.min_content.errorMsg} - - - - {t('restrict_answer.title')} - { - handleValueChange({ - restrict_answer: { - value: evt.target.checked, - errorMsg: '', - isInvalid: false, - }, - }); - }} - /> - {t('restrict_answer.text')} - - {formData.restrict_answer.errorMsg} - - - - - {t('image_size.label')} - { - handleValueChange({ - max_image_size: { - value: evt.target.value, - errorMsg: '', - isInvalid: false, - }, - }); - }} - /> - {t('image_size.text')} - - {formData.max_image_size.errorMsg} - - - - - {t('attachment_size.label')} - { - handleValueChange({ - max_attachment_size: { - value: evt.target.value, - errorMsg: '', - isInvalid: false, - }, - }); - }} - /> - {t('attachment_size.text')} - - {formData.max_attachment_size.errorMsg} - - - - - {t('image_megapixels.label')} - { - handleValueChange({ - max_image_megapixel: { - value: evt.target.value, - errorMsg: '', - isInvalid: false, - }, - }); - }} - /> - {t('image_megapixels.text')} - - {formData.max_image_megapixel.errorMsg} - - - - - {t('image_extensions.label')} - { - handleValueChange({ - authorized_image_extensions: { - value: evt.target.value.toLowerCase(), - errorMsg: '', - isInvalid: false, - }, - }); - }} - /> - {t('image_extensions.text')} - - {formData.authorized_image_extensions.errorMsg} - - - - - {t('attachment_extensions.label')} - { - handleValueChange({ - authorized_attachment_extensions: { - value: evt.target.value.toLowerCase(), - errorMsg: '', - isInvalid: false, - }, - }); - }} - /> - {t('attachment_extensions.text')} - - {formData.authorized_attachment_extensions.errorMsg} - - - - - - - - - ); -}; - -export default Index; diff --git a/ui/src/pages/Admin/index.scss b/ui/src/pages/Admin/index.scss index 5748d0532..c33e92be6 100644 --- a/ui/src/pages/Admin/index.scss +++ b/ui/src/pages/Admin/index.scss @@ -25,6 +25,10 @@ max-width: 30rem; } +.max-w-748 { + max-width: 748px; +} + @media screen and (max-width: 768px) { .max-w-30 { max-width: 15rem; diff --git a/ui/src/pages/Admin/index.tsx b/ui/src/pages/Admin/index.tsx index 27503296c..da167ac40 100644 --- a/ui/src/pages/Admin/index.tsx +++ b/ui/src/pages/Admin/index.tsx @@ -20,7 +20,7 @@ import { FC } from 'react'; import { useTranslation } from 'react-i18next'; import { Row, Col } from 'react-bootstrap'; -import { Outlet, useMatch } from 'react-router-dom'; +import { Outlet } from 'react-router-dom'; import { usePageTags } from '@/hooks'; import { AdminSideNav, Footer } from '@/components'; @@ -28,19 +28,8 @@ import { AdminSideNav, Footer } from '@/components'; import '@/common/sideNavLayout.scss'; import './index.scss'; -const g10Paths = [ - 'dashboard', - 'questions', - 'answers', - 'users', - 'badges', - 'flags', - 'installed-plugins', -]; const Index: FC = () => { const { t } = useTranslation('translation', { keyPrefix: 'page_title' }); - const pathMatch = useMatch('/admin/:path'); - const curPath = pathMatch?.params.path || 'dashboard'; usePageTags({ title: t('admin'), @@ -59,9 +48,6 @@ const Index: FC = () => {
    - {g10Paths.find((v) => curPath === v) ? null : ( - - )} diff --git a/ui/src/pages/Layout/index.tsx b/ui/src/pages/Layout/index.tsx index bd229165c..048ca812e 100644 --- a/ui/src/pages/Layout/index.tsx +++ b/ui/src/pages/Layout/index.tsx @@ -28,7 +28,7 @@ import { toastStore, loginToContinueStore, errorCodeStore, - siteLealStore, + siteSecurityStore, themeSettingStore, } from '@/stores'; import { @@ -49,7 +49,7 @@ const Layout: FC = () => { const location = useLocation(); const { msg: toastMsg, variant, clear: toastClear } = toastStore(); const externalToast = useExternalToast(); - const externalContentDisplay = siteLealStore( + const externalContentDisplay = siteSecurityStore( (state) => state.external_content_display, ); const closeToast = () => { @@ -59,7 +59,6 @@ const Layout: FC = () => { const { show: showLoginToContinueModal } = loginToContinueStore(); const { data: notificationData } = useQueryNotificationStatus(); const layout = themeSettingStore((state) => state.layout); - console.log(layout); useEffect(() => { // handle footnote links const fixFootnoteLinks = () => { diff --git a/ui/src/pages/Users/Settings/Profile/index.tsx b/ui/src/pages/Users/Settings/Profile/index.tsx index 7fb8247c1..62bd6fb8e 100644 --- a/ui/src/pages/Users/Settings/Profile/index.tsx +++ b/ui/src/pages/Users/Settings/Profile/index.tsx @@ -25,7 +25,7 @@ import { sha256 } from 'js-sha256'; import type { FormDataType } from '@/common/interface'; import { UploadImg, Avatar, Icon, ImgViewer } from '@/components'; -import { loggedUserInfoStore, userCenterStore, interfaceStore } from '@/stores'; +import { loggedUserInfoStore, userCenterStore, siteInfoStore } from '@/stores'; import { useToast } from '@/hooks'; import { modifyUserInfo, @@ -42,7 +42,7 @@ const Index: React.FC = () => { const toast = useToast(); const { user, update } = loggedUserInfoStore(); const { agent: ucAgent } = userCenterStore(); - const { interface: interfaceSetting } = interfaceStore(); + const { users: usersSettings } = siteInfoStore(); const [mailHash, setMailHash] = useState(''); const [count] = useState(0); const [profileAgent, setProfileAgent] = useState(); @@ -384,7 +384,7 @@ const Index: React.FC = () => { {t('avatar.gravatar_text')} { className="ms-1" target="_blank" rel="noreferrer"> - {interfaceSetting.gravatar_base_url.includes( - 'gravatar.cn', - ) + {usersSettings.gravatar_base_url.includes('gravatar.cn') ? 'gravatar.cn' : 'gravatar.com'} diff --git a/ui/src/router/routes.ts b/ui/src/router/routes.ts index 3ca8431fc..7d7003a12 100644 --- a/ui/src/router/routes.ts +++ b/ui/src/router/routes.ts @@ -358,9 +358,25 @@ const routes: RouteNode[] = [ page: 'pages/Admin/Dashboard', }, { - path: 'answers', + path: 'qa/questions', + page: 'pages/Admin/Questions', + }, + { + path: 'qa/answers', page: 'pages/Admin/Answers', }, + { + path: 'qa/settings', + page: 'pages/Admin/QaSettings', + }, + { + path: 'tags/settings', + page: 'pages/Admin/TagsSettings', + }, + { + path: 'security', + page: 'pages/Admin/Security', + }, { path: 'themes', page: 'pages/Admin/Themes', @@ -377,14 +393,14 @@ const routes: RouteNode[] = [ path: 'interface', page: 'pages/Admin/Interface', }, - { - path: 'questions', - page: 'pages/Admin/Questions', - }, { path: 'users', page: 'pages/Admin/Users', }, + { + path: 'users/settings', + page: 'pages/Admin/UsersSettings', + }, { path: 'users/:user_id', page: 'pages/Admin/UserOverview', @@ -398,12 +414,12 @@ const routes: RouteNode[] = [ page: 'pages/Admin/Branding', }, { - path: 'legal', - page: 'pages/Admin/Legal', + path: 'rules/policies', + page: 'pages/Admin/Policies', }, { - path: 'write', - page: 'pages/Admin/Write', + path: 'files', + page: 'pages/Admin/Files', }, { path: 'seo', @@ -414,7 +430,7 @@ const routes: RouteNode[] = [ page: 'pages/Admin/Login', }, { - path: 'privileges', + path: 'rules/privileges', page: 'pages/Admin/Privileges', }, { diff --git a/ui/src/services/admin/index.ts b/ui/src/services/admin/index.ts index af83d365b..3fa211ee3 100644 --- a/ui/src/services/admin/index.ts +++ b/ui/src/services/admin/index.ts @@ -25,3 +25,4 @@ export * from './users'; export * from './dashboard'; export * from './plugins'; export * from './badges'; +export * from './tags'; diff --git a/ui/src/services/admin/question.ts b/ui/src/services/admin/question.ts index 670534e26..bcd3ac7fc 100644 --- a/ui/src/services/admin/question.ts +++ b/ui/src/services/admin/question.ts @@ -46,3 +46,13 @@ export const changeQuestionStatus = ( status, }); }; + +export const getQuestionSetting = () => { + return request.get( + '/answer/admin/api/siteinfo/question', + ); +}; + +export const updateQuestionSetting = (params: Type.AdminQuestionSetting) => { + return request.put('/answer/admin/api/siteinfo/question', params); +}; diff --git a/ui/src/services/admin/settings.ts b/ui/src/services/admin/settings.ts index f2b9e598c..c1f99d40b 100644 --- a/ui/src/services/admin/settings.ts +++ b/ui/src/services/admin/settings.ts @@ -122,22 +122,12 @@ export const brandSetting = (params: Type.AdminSettingBranding) => { return request.put('/answer/admin/api/siteinfo/branding', params); }; -export const getRequireAndReservedTag = () => { - return request.get('/answer/admin/api/siteinfo/write'); +export const getAdminFilesSetting = () => { + return request.get('/answer/admin/api/siteinfo/advanced'); }; -export const postRequireAndReservedTag = (params) => { - return request.put('/answer/admin/api/siteinfo/write', params); -}; - -export const getLegalSetting = () => { - return request.get( - '/answer/admin/api/siteinfo/legal', - ); -}; - -export const putLegalSetting = (params: Type.AdminSettingsLegal) => { - return request.put('/answer/admin/api/siteinfo/legal', params); +export const updateAdminFilesSetting = (params: Type.AdminSettingsWrite) => { + return request.put('/answer/admin/api/siteinfo/advanced', params); }; export const getSeoSetting = () => { @@ -195,3 +185,23 @@ export const getPrivilegeSetting = () => { export const putPrivilegeSetting = (params: AdminSettingsPrivilegeReq) => { return request.put('/answer/admin/api/setting/privileges', params); }; + +export const getPoliciesSetting = () => { + return request.get( + '/answer/admin/api/siteinfo/polices', + ); +}; + +export const putPoliciesSetting = (params: Type.AdminSettingsLegal) => { + return request.put('/answer/admin/api/siteinfo/polices', params); +}; + +export const getSecuritySetting = () => { + return request.get( + '/answer/admin/api/siteinfo/security', + ); +}; + +export const putSecuritySetting = (params: Type.AdminSettingsSecurity) => { + return request.put('/answer/admin/api/siteinfo/security', params); +}; diff --git a/ui/src/services/admin/tags.ts b/ui/src/services/admin/tags.ts new file mode 100644 index 000000000..c7d6bc773 --- /dev/null +++ b/ui/src/services/admin/tags.ts @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import request from '@/utils/request'; +import type * as Type from '@/common/interface'; + +export const getAdminTagsSetting = () => { + return request.get('/answer/admin/api/siteinfo/tag'); +}; + +export const updateAdminTagsSetting = (params: Type.AdminTagsSetting) => { + return request.put('/answer/admin/api/siteinfo/tag', params); +}; diff --git a/ui/src/services/admin/users.ts b/ui/src/services/admin/users.ts index ee8cad5d0..c7aeafe51 100644 --- a/ui/src/services/admin/users.ts +++ b/ui/src/services/admin/users.ts @@ -94,3 +94,22 @@ export const postUserActivation = (userId: string) => { user_id: userId, }); }; + +export const useAdminUsersSettings = () => { + const apiUrl = `/answer/admin/api/siteinfo/users-settings`; + const { data, error } = useSWR< + { + default_avatar: string; + gravatar_base_url: string; + }, + Error + >(apiUrl, request.instance.get); + return { data, isLoading: !data && !error, error }; +}; + +export const updateAdminUsersSettings = (params: { + default_avatar: string; + gravatar_base_url: string; +}) => { + return request.put('/answer/admin/api/siteinfo/users-settings', params); +}; diff --git a/ui/src/stores/index.ts b/ui/src/stores/index.ts index 66d59b32f..1bd2fece0 100644 --- a/ui/src/stores/index.ts +++ b/ui/src/stores/index.ts @@ -33,7 +33,7 @@ import loginToContinueStore from './loginToContinue'; import errorCodeStore from './errorCode'; import sideNavStore from './sideNav'; import commentReplyStore from './commentReply'; -import siteLealStore from './siteLegal'; +import siteSecurityStore from './siteSecurity'; export { toastStore, @@ -52,5 +52,5 @@ export { sideNavStore, commentReplyStore, writeSettingStore, - siteLealStore, + siteSecurityStore, }; diff --git a/ui/src/stores/interface.ts b/ui/src/stores/interface.ts index cceb425cd..fdb4ab961 100644 --- a/ui/src/stores/interface.ts +++ b/ui/src/stores/interface.ts @@ -35,9 +35,9 @@ const interfaceSetting = create((set) => ({ gravatar_base_url: '', }, update: (params) => - set(() => { + set((state) => { return { - interface: params, + interface: { ...state.interface, ...params }, }; }), })); diff --git a/ui/src/stores/loginSetting.ts b/ui/src/stores/loginSetting.ts index 73fd48807..7acf765ee 100644 --- a/ui/src/stores/loginSetting.ts +++ b/ui/src/stores/loginSetting.ts @@ -29,7 +29,6 @@ interface IType { const loginSetting = create((set) => ({ login: { allow_new_registrations: true, - login_required: false, allow_email_registrations: true, allow_email_domains: [], allow_password_login: true, diff --git a/ui/src/stores/siteInfo.ts b/ui/src/stores/siteInfo.ts index 725546d64..c529cc624 100644 --- a/ui/src/stores/siteInfo.ts +++ b/ui/src/stores/siteInfo.ts @@ -39,6 +39,8 @@ const defaultUsersConf: AdminSettingsUsers = { allow_update_location: false, allow_update_username: false, allow_update_website: false, + default_avatar: 'system', + gravatar_base_url: '', }; const siteInfo = create((set) => ({ @@ -48,7 +50,6 @@ const siteInfo = create((set) => ({ short_description: '', site_url: '', contact_email: '', - check_update: true, permalink: 1, }, users: defaultUsersConf, diff --git a/ui/src/stores/siteLegal.ts b/ui/src/stores/siteSecurity.ts similarity index 75% rename from ui/src/stores/siteLegal.ts rename to ui/src/stores/siteSecurity.ts index 29a26ea35..e4e5bb52b 100644 --- a/ui/src/stores/siteLegal.ts +++ b/ui/src/stores/siteSecurity.ts @@ -19,12 +19,20 @@ import { create } from 'zustand'; -interface LealStore { +interface SecurityStore { + login_required: boolean; + check_update: boolean; external_content_display: string; - update: (params: { external_content_display: string }) => void; + update: (params: { + external_content_display: string; + check_update: boolean; + login_required: boolean; + }) => void; } -const siteLealStore = create((set) => ({ +const siteSecurityStore = create((set) => ({ + login_required: false, + check_update: true, external_content_display: 'always_display', update: (params) => set((state) => { @@ -35,4 +43,4 @@ const siteLealStore = create((set) => ({ }), })); -export default siteLealStore; +export default siteSecurityStore; diff --git a/ui/src/stores/writeSetting.ts b/ui/src/stores/writeSetting.ts index 9f6542d27..576979a2e 100644 --- a/ui/src/stores/writeSetting.ts +++ b/ui/src/stores/writeSetting.ts @@ -19,11 +19,17 @@ import { create } from 'zustand'; -import { AdminSettingsWrite } from '@/common/interface'; +import { + AdminSettingsWrite, + AdminQuestionSetting, + AdminTagsSetting, +} from '@/common/interface'; interface IProps { - write: AdminSettingsWrite; - update: (params: AdminSettingsWrite) => void; + write: AdminSettingsWrite & AdminQuestionSetting & AdminTagsSetting; + update: ( + params: AdminSettingsWrite | AdminQuestionSetting | AdminTagsSetting, + ) => void; } const Index = create((set) => ({ diff --git a/ui/src/utils/guard.ts b/ui/src/utils/guard.ts index 24064669a..6e6a6d801 100644 --- a/ui/src/utils/guard.ts +++ b/ui/src/utils/guard.ts @@ -30,7 +30,7 @@ import { loginToContinueStore, pageTagStore, writeSettingStore, - siteLealStore, + siteSecurityStore, } from '@/stores'; import { RouteAlias } from '@/router/alias'; import { @@ -263,8 +263,8 @@ export const singUpAgent = () => { export const shouldLoginRequired = () => { const gr: TGuardResult = { ok: true }; - const loginSetting = loginSettingStore.getState().login; - if (!loginSetting.login_required) { + const { login_required } = siteSecurityStore.getState(); + if (!login_required) { return gr; } const us = deriveLoginState(); @@ -382,12 +382,11 @@ export const initAppSettingsStore = async () => { themeSettingStore.getState().update(appSettings.theme); seoSettingStore.getState().update(appSettings.site_seo); writeSettingStore.getState().update({ - restrict_answer: appSettings.site_write.restrict_answer, - ...appSettings.site_write, - }); - siteLealStore.getState().update({ - external_content_display: appSettings.site_legal.external_content_display, + ...appSettings.site_advanced, + ...appSettings.site_questions, + ...appSettings.site_tags, }); + siteSecurityStore.getState().update(appSettings.site_security); } }; From 2d02452e172068268fd5099ee88c980096d67561 Mon Sep 17 00:00:00 2001 From: shuai Date: Thu, 22 Jan 2026 14:50:53 +0800 Subject: [PATCH 76/92] fix: Changes in the editor content will reset the values of other form fields. --- i18n/zh_CN.yaml | 2 +- ui/src/pages/Questions/Ask/index.tsx | 94 +++++++++++++++++----------- 2 files changed, 60 insertions(+), 36 deletions(-) diff --git a/i18n/zh_CN.yaml b/i18n/zh_CN.yaml index 29e18151b..59ef41be5 100644 --- a/i18n/zh_CN.yaml +++ b/i18n/zh_CN.yaml @@ -1760,7 +1760,7 @@ ui: users: 用户管理 badges: 徽章 flags: 举报管理 - settings: 站点设置 + settings: 设置 general: 一般 interface: 界面 smtp: SMTP diff --git a/ui/src/pages/Questions/Ask/index.tsx b/ui/src/pages/Questions/Ask/index.tsx index cac75dd87..386fd213d 100644 --- a/ui/src/pages/Questions/Ask/index.tsx +++ b/ui/src/pages/Questions/Ask/index.tsx @@ -147,8 +147,11 @@ const Ask = () => { if (prefill || draft) { if (prefill) { const file = fm(decodeURIComponent(prefill)); - formData.title.value = file.attributes?.title; - formData.content.value = file.body; + setFormData((prev) => ({ + ...prev, + title: { ...prev.title, value: file.attributes?.title || '' }, + content: { ...prev.content, value: file.body || '' }, + })); if (!queryTags && file.attributes?.tags) { // Remove spaces in file.attributes.tags const filterTags = file.attributes.tags @@ -158,14 +161,19 @@ const Ask = () => { updateTags(filterTags); } } else if (draft) { - formData.title.value = draft.title; - formData.content.value = draft.content; - formData.tags.value = draft.tags; - formData.answer_content.value = draft.answer_content; + setFormData((prev) => ({ + ...prev, + title: { ...prev.title, value: draft.title || '' }, + content: { ...prev.content, value: draft.content || '' }, + tags: { ...prev.tags, value: draft.tags || [] }, + answer_content: { + ...prev.answer_content, + value: draft.answer_content || '', + }, + })); setCheckState(Boolean(draft.answer_content)); setHasDraft(true); } - setFormData({ ...formData }); } else { resetForm(); } @@ -231,17 +239,25 @@ const Ask = () => { return; } questionDetail(qid).then((res) => { - formData.title.value = res.title; - formData.content.value = res.content; - formData.tags.value = res.tags.map((item) => { - return { - ...item, - parsed_text: '', - original_text: '', + setFormData((prev) => { + const updatedFormData = { + ...prev, + title: { ...prev.title, value: res.title }, + content: { ...prev.content, value: res.content }, + tags: { + ...prev.tags, + value: res.tags.map((item) => { + return { + ...item, + parsed_text: '', + original_text: '', + }; + }), + }, }; + setImmData(updatedFormData); + return updatedFormData; }); - setImmData({ ...formData }); - setFormData({ ...formData }); }); }, [qid]); @@ -255,10 +271,10 @@ const Ask = () => { ); const handleTitleChange = (e: React.ChangeEvent) => { - setFormData({ - ...formData, + setFormData((prev) => ({ + ...prev, title: { value: e.currentTarget.value, errorMsg: '', isInvalid: false }, - }); + })); if (e.currentTarget.value.length >= 10) { querySimilarQuestions(e.currentTarget.value); } @@ -267,31 +283,31 @@ const Ask = () => { } }; const handleContentChange = (value: string) => { - setFormData({ - ...formData, + setFormData((prev) => ({ + ...prev, content: { value, errorMsg: '', isInvalid: false }, - }); + })); }; const handleTagsChange = (value) => - setFormData({ - ...formData, + setFormData((prev) => ({ + ...prev, tags: { value, errorMsg: '', isInvalid: false }, - }); + })); const handleAnswerChange = (value: string) => - setFormData({ - ...formData, + setFormData((prev) => ({ + ...prev, answer_content: { value, errorMsg: '', isInvalid: false }, - }); + })); const handleSummaryChange = (evt: React.ChangeEvent) => - setFormData({ - ...formData, + setFormData((prev) => ({ + ...prev, edit_summary: { - ...formData.edit_summary, + ...prev.edit_summary, value: evt.currentTarget.value, }, - }); + })); const deleteDraft = () => { const res = window.confirm(t('discard_confirm', { keyPrefix: 'draft' })); @@ -413,9 +429,17 @@ const Ask = () => { const handleSelectedRevision = (e) => { const index = e.target.value; const revision = revisions[index]; - formData.content.value = revision.content?.content || ''; - setImmData({ ...formData }); - setFormData({ ...formData }); + setFormData((prev) => { + const updated = { + ...prev, + content: { + ...prev.content, + value: revision.content?.content || '', + }, + }; + setImmData(updated); + return updated; + }); }; const bool = similarQuestions.length > 0 && !isEdit; let pageTitle = t('ask_a_question', { keyPrefix: 'page_title' }); From 06e9d437e0115c066910905c2329145b2b5c2a78 Mon Sep 17 00:00:00 2001 From: shuai Date: Thu, 22 Jan 2026 15:13:23 +0800 Subject: [PATCH 77/92] fix: Changes in the editor content will reset the values of other form fields. --- ui/src/pages/Questions/Ask/index.tsx | 88 ++++++++++------------------ 1 file changed, 32 insertions(+), 56 deletions(-) diff --git a/ui/src/pages/Questions/Ask/index.tsx b/ui/src/pages/Questions/Ask/index.tsx index 386fd213d..5fb4d57f2 100644 --- a/ui/src/pages/Questions/Ask/index.tsx +++ b/ui/src/pages/Questions/Ask/index.tsx @@ -147,11 +147,8 @@ const Ask = () => { if (prefill || draft) { if (prefill) { const file = fm(decodeURIComponent(prefill)); - setFormData((prev) => ({ - ...prev, - title: { ...prev.title, value: file.attributes?.title || '' }, - content: { ...prev.content, value: file.body || '' }, - })); + formData.title.value = file.attributes?.title; + formData.content.value = file.body; if (!queryTags && file.attributes?.tags) { // Remove spaces in file.attributes.tags const filterTags = file.attributes.tags @@ -161,19 +158,14 @@ const Ask = () => { updateTags(filterTags); } } else if (draft) { - setFormData((prev) => ({ - ...prev, - title: { ...prev.title, value: draft.title || '' }, - content: { ...prev.content, value: draft.content || '' }, - tags: { ...prev.tags, value: draft.tags || [] }, - answer_content: { - ...prev.answer_content, - value: draft.answer_content || '', - }, - })); + formData.title.value = draft.title; + formData.content.value = draft.content; + formData.tags.value = draft.tags; + formData.answer_content.value = draft.answer_content; setCheckState(Boolean(draft.answer_content)); setHasDraft(true); } + setFormData({ ...formData }); } else { resetForm(); } @@ -239,25 +231,17 @@ const Ask = () => { return; } questionDetail(qid).then((res) => { - setFormData((prev) => { - const updatedFormData = { - ...prev, - title: { ...prev.title, value: res.title }, - content: { ...prev.content, value: res.content }, - tags: { - ...prev.tags, - value: res.tags.map((item) => { - return { - ...item, - parsed_text: '', - original_text: '', - }; - }), - }, + formData.title.value = res.title; + formData.content.value = res.content; + formData.tags.value = res.tags.map((item) => { + return { + ...item, + parsed_text: '', + original_text: '', }; - setImmData(updatedFormData); - return updatedFormData; }); + setImmData({ ...formData }); + setFormData({ ...formData }); }); }, [qid]); @@ -271,10 +255,10 @@ const Ask = () => { ); const handleTitleChange = (e: React.ChangeEvent) => { - setFormData((prev) => ({ - ...prev, + setFormData({ + ...formData, title: { value: e.currentTarget.value, errorMsg: '', isInvalid: false }, - })); + }); if (e.currentTarget.value.length >= 10) { querySimilarQuestions(e.currentTarget.value); } @@ -289,25 +273,25 @@ const Ask = () => { })); }; const handleTagsChange = (value) => - setFormData((prev) => ({ - ...prev, + setFormData({ + ...formData, tags: { value, errorMsg: '', isInvalid: false }, - })); + }); const handleAnswerChange = (value: string) => - setFormData((prev) => ({ - ...prev, + setFormData({ + ...formData, answer_content: { value, errorMsg: '', isInvalid: false }, - })); + }); const handleSummaryChange = (evt: React.ChangeEvent) => - setFormData((prev) => ({ - ...prev, + setFormData({ + ...formData, edit_summary: { - ...prev.edit_summary, + ...formData.edit_summary, value: evt.currentTarget.value, }, - })); + }); const deleteDraft = () => { const res = window.confirm(t('discard_confirm', { keyPrefix: 'draft' })); @@ -429,17 +413,9 @@ const Ask = () => { const handleSelectedRevision = (e) => { const index = e.target.value; const revision = revisions[index]; - setFormData((prev) => { - const updated = { - ...prev, - content: { - ...prev.content, - value: revision.content?.content || '', - }, - }; - setImmData(updated); - return updated; - }); + formData.content.value = revision.content?.content || ''; + setImmData({ ...formData }); + setFormData({ ...formData }); }; const bool = similarQuestions.length > 0 && !isEdit; let pageTitle = t('ask_a_question', { keyPrefix: 'page_title' }); From c509723f295a67ff1f651e58862d60f76770d4ab Mon Sep 17 00:00:00 2001 From: kumfo Date: Thu, 22 Jan 2026 15:08:49 +0800 Subject: [PATCH 78/92] feat(docs): add layout property with enum options to schema definitions --- docs/docs.go | 10 ++++++++++ docs/swagger.json | 10 ++++++++++ docs/swagger.yaml | 7 +++++++ 3 files changed, 27 insertions(+) diff --git a/docs/docs.go b/docs/docs.go index cfe48366f..0cd064294 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -11323,6 +11323,13 @@ const docTemplate = `{ "type": "string", "maxLength": 100 }, + "layout": { + "type": "string", + "enum": [ + "Full-width", + "Fixed-width" + ] + }, "theme": { "type": "string", "maxLength": 255 @@ -11339,6 +11346,9 @@ const docTemplate = `{ "color_scheme": { "type": "string" }, + "layout": { + "type": "string" + }, "theme": { "type": "string" }, diff --git a/docs/swagger.json b/docs/swagger.json index c181109d2..a59867f96 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -11296,6 +11296,13 @@ "type": "string", "maxLength": 100 }, + "layout": { + "type": "string", + "enum": [ + "Full-width", + "Fixed-width" + ] + }, "theme": { "type": "string", "maxLength": 255 @@ -11312,6 +11319,9 @@ "color_scheme": { "type": "string" }, + "layout": { + "type": "string" + }, "theme": { "type": "string" }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 13e9575eb..426f5332a 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2442,6 +2442,11 @@ definitions: color_scheme: maxLength: 100 type: string + layout: + enum: + - Full-width + - Fixed-width + type: string theme: maxLength: 255 type: string @@ -2455,6 +2460,8 @@ definitions: properties: color_scheme: type: string + layout: + type: string theme: type: string theme_config: From c1549d2909856d6bac6af7e94cc3afc979e00ed0 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Fri, 23 Jan 2026 17:09:05 +0800 Subject: [PATCH 79/92] feat: add AI configuration support with related controllers and services --- cmd/wire_gen.go | 89 +- docs/docs.go | 1349 +++++++++++++++-- docs/swagger.json | 1330 ++++++++++++++-- docs/swagger.yaml | 652 ++++++++ go.mod | 12 +- go.sum | 22 +- internal/base/constant/ai_config.go | 49 + internal/base/constant/site_type.go | 3 + internal/base/middleware/mcp_auth.go | 47 + internal/base/reason/reason.go | 1 + internal/base/translator/provider.go | 6 +- internal/controller/ai_controller.go | 756 +++++++++ .../controller/ai_conversation_controller.go | 130 ++ internal/controller/controller.go | 3 + internal/controller/mcp_controller.go | 351 +++++ internal/controller/siteinfo_controller.go | 7 + .../ai_conversation_admin_controller.go | 123 ++ internal/controller_admin/controller.go | 2 + .../controller_admin/e_api_key_controller.go | 116 ++ .../controller_admin/siteinfo_controller.go | 102 ++ internal/entity/ai_conversation.go | 37 + internal/entity/ai_conversation_record.go | 40 + internal/entity/api_key_entity.go | 42 + internal/migrations/migrations.go | 1 + internal/migrations/v32.go | 116 ++ .../ai_conversation/ai_conversation_repo.go | 205 +++ internal/repo/api_key/api_key_repo.go | 83 + internal/repo/provider.go | 4 + internal/repo/site_info/siteinfo_repo.go | 10 +- internal/router/answer_api_router.go | 161 +- internal/schema/ai_config_schema.go | 51 + internal/schema/ai_conversation_schema.go | 123 ++ internal/schema/api_key_schema.go | 60 + internal/schema/mcp_schema.go | 194 +++ internal/schema/mcp_tools/mcp_tools.go | 105 ++ internal/schema/siteinfo_schema.go | 52 + .../ai_conversation_service.go | 372 +++++ internal/service/apikey/apikey_service.go | 116 ++ .../feature_toggle/feature_toggle_service.go | 130 ++ internal/service/mock/siteinfo_repo_mock.go | 62 +- internal/service/provider.go | 6 + internal/service/siteinfo/siteinfo_service.go | 223 +++ .../siteinfo_common/siteinfo_service.go | 22 +- 43 files changed, 6971 insertions(+), 394 deletions(-) create mode 100644 internal/base/constant/ai_config.go create mode 100644 internal/base/middleware/mcp_auth.go create mode 100644 internal/controller/ai_controller.go create mode 100644 internal/controller/ai_conversation_controller.go create mode 100644 internal/controller/mcp_controller.go create mode 100644 internal/controller_admin/ai_conversation_admin_controller.go create mode 100644 internal/controller_admin/e_api_key_controller.go create mode 100644 internal/entity/ai_conversation.go create mode 100644 internal/entity/ai_conversation_record.go create mode 100644 internal/entity/api_key_entity.go create mode 100644 internal/migrations/v32.go create mode 100644 internal/repo/ai_conversation/ai_conversation_repo.go create mode 100644 internal/repo/api_key/api_key_repo.go create mode 100644 internal/schema/ai_config_schema.go create mode 100644 internal/schema/ai_conversation_schema.go create mode 100644 internal/schema/api_key_schema.go create mode 100644 internal/schema/mcp_schema.go create mode 100644 internal/schema/mcp_tools/mcp_tools.go create mode 100644 internal/service/ai_conversation/ai_conversation_service.go create mode 100644 internal/service/apikey/apikey_service.go create mode 100644 internal/service/feature_toggle/feature_toggle_service.go diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index 8435cf310..24d32f7eb 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -1,8 +1,28 @@ +//go:build !wireinject +// +build !wireinject + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + // Code generated by Wire. DO NOT EDIT. //go:generate go run github.com/google/wire/cmd/wire -//go:build !wireinject -// +build !wireinject package answercmd @@ -18,7 +38,9 @@ import ( "github.com/apache/answer/internal/controller_admin" "github.com/apache/answer/internal/repo/activity" "github.com/apache/answer/internal/repo/activity_common" + "github.com/apache/answer/internal/repo/ai_conversation" "github.com/apache/answer/internal/repo/answer" + "github.com/apache/answer/internal/repo/api_key" "github.com/apache/answer/internal/repo/auth" "github.com/apache/answer/internal/repo/badge" "github.com/apache/answer/internal/repo/badge_award" @@ -53,7 +75,9 @@ import ( activity2 "github.com/apache/answer/internal/service/activity" activity_common2 "github.com/apache/answer/internal/service/activity_common" "github.com/apache/answer/internal/service/activityqueue" + ai_conversation2 "github.com/apache/answer/internal/service/ai_conversation" "github.com/apache/answer/internal/service/answer_common" + "github.com/apache/answer/internal/service/apikey" auth2 "github.com/apache/answer/internal/service/auth" badge2 "github.com/apache/answer/internal/service/badge" collection2 "github.com/apache/answer/internal/service/collection" @@ -65,6 +89,7 @@ import ( "github.com/apache/answer/internal/service/dashboard" "github.com/apache/answer/internal/service/eventqueue" export2 "github.com/apache/answer/internal/service/export" + "github.com/apache/answer/internal/service/feature_toggle" file_record2 "github.com/apache/answer/internal/service/file_record" "github.com/apache/answer/internal/service/follow" "github.com/apache/answer/internal/service/importer" @@ -152,29 +177,29 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, tagRepo := tag.NewTagRepo(dataData, uniqueIDRepo) revisionRepo := revision.NewRevisionRepo(dataData, uniqueIDRepo) revisionService := revision_common.NewRevisionService(revisionRepo, userRepo) - v := activityqueue.NewService() - tagCommonService := tag_common2.NewTagCommonService(tagCommonRepo, tagRelRepo, tagRepo, revisionService, siteInfoCommonService, v) + service := activityqueue.NewService() + tagCommonService := tag_common2.NewTagCommonService(tagCommonRepo, tagRelRepo, tagRepo, revisionService, siteInfoCommonService, service) collectionRepo := collection.NewCollectionRepo(dataData, uniqueIDRepo) collectionCommon := collectioncommon.NewCollectionCommon(collectionRepo) answerCommon := answercommon.NewAnswerCommon(answerRepo) metaRepo := meta.NewMetaRepo(dataData) metaCommonService := metacommon.NewMetaCommonService(metaRepo) - questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaCommonService, configService, v, revisionRepo, siteInfoCommonService, dataData) - v2 := eventqueue.NewService() + questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaCommonService, configService, service, revisionRepo, siteInfoCommonService, dataData) + eventqueueService := eventqueue.NewService() fileRecordRepo := file_record.NewFileRecordRepo(dataData) fileRecordService := file_record2.NewFileRecordService(fileRecordRepo, revisionRepo, serviceConf, siteInfoCommonService, userCommon) - userService := content.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo, userNotificationConfigService, questionCommon, v2, fileRecordService) + userService := content.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo, userNotificationConfigService, questionCommon, eventqueueService, fileRecordService) captchaRepo := captcha.NewCaptchaRepo(dataData) captchaService := action.NewCaptchaService(captchaRepo) userController := controller.NewUserController(authService, userService, captchaService, emailService, siteInfoCommonService, userNotificationConfigService) commentRepo := comment.NewCommentRepo(dataData, uniqueIDRepo) commentCommonRepo := comment.NewCommentCommonRepo(dataData, uniqueIDRepo) objService := object_info.NewObjService(answerRepo, questionRepo, commentCommonRepo, tagCommonRepo, tagCommonService) - v3 := noticequeue.NewService() - v4 := noticequeue.NewExternalService() + noticequeueService := noticequeue.NewService() + externalService := noticequeue.NewExternalService() reviewRepo := review.NewReviewRepo(dataData) - reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, v4, tagCommonService, questionCommon, v3, siteInfoCommonService, commentCommonRepo) - commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, v3, v4, v, v2, reviewService) + reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, externalService, tagCommonService, questionCommon, noticequeueService, siteInfoCommonService, commentCommonRepo) + commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, noticequeueService, externalService, service, eventqueueService, reviewService) rolePowerRelRepo := role.NewRolePowerRelRepo(dataData) rolePowerRelService := role2.NewRolePowerRelService(rolePowerRelRepo, userRoleRelService) rankService := rank2.NewRankService(userCommon, userRankRepo, objService, userRoleRelService, rolePowerRelService, configService) @@ -182,17 +207,17 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, rateLimitMiddleware := middleware.NewRateLimitMiddleware(limitRepo) commentController := controller.NewCommentController(commentService, rankService, captchaService, rateLimitMiddleware) reportRepo := report.NewReportRepo(dataData, uniqueIDRepo) - tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, v) - answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, v3) + tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, service) + answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, noticequeueService) answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, configService) - externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, v4, userExternalLoginRepo, siteInfoCommonService) - questionService := content.NewQuestionService(activityRepo, questionRepo, answerRepo, tagCommonService, tagService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, v3, v4, v, siteInfoCommonService, externalNotificationService, reviewService, configService, v2, reviewRepo) - answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, v3, v4, v, reviewService, v2) + externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, externalService, userExternalLoginRepo, siteInfoCommonService) + questionService := content.NewQuestionService(activityRepo, questionRepo, answerRepo, tagCommonService, tagService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, noticequeueService, externalService, service, siteInfoCommonService, externalNotificationService, reviewService, configService, eventqueueService, reviewRepo) + answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, noticequeueService, externalService, service, reviewService, eventqueueService) reportHandle := report_handle.NewReportHandle(questionService, answerService, commentService) - reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, v2) + reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, eventqueueService) reportController := controller.NewReportController(reportService, rankService, captchaService) - contentVoteRepo := activity.NewVoteRepo(dataData, activityRepo, userRankRepo, v3) - voteService := content.NewVoteService(contentVoteRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService, v2) + contentVoteRepo := activity.NewVoteRepo(dataData, activityRepo, userRankRepo, noticequeueService) + voteService := content.NewVoteService(contentVoteRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService, eventqueueService) voteController := controller.NewVoteController(voteService, rankService, captchaService) tagController := controller.NewTagController(tagService, tagCommonService, rankService) followFollowRepo := activity.NewFollowRepo(dataData, uniqueIDRepo, activityRepo) @@ -208,7 +233,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, searchService := content.NewSearchService(searchParser, searchRepo) searchController := controller.NewSearchController(searchService, captchaService) reviewActivityRepo := activity.NewReviewActivityRepo(dataData, activityRepo, userRankRepo, configService) - contentRevisionService := content.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService, v3, v, reportRepo, reviewService, reviewActivityRepo) + contentRevisionService := content.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService, noticequeueService, service, reportRepo, reviewService, reviewActivityRepo) revisionController := controller.NewRevisionController(contentRevisionService, rankService) rankController := controller.NewRankController(rankService) userAdminRepo := user.NewUserAdminRepo(dataData, authRepo) @@ -224,7 +249,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, siteInfoService := siteinfo.NewSiteInfoService(siteInfoRepo, siteInfoCommonService, emailService, tagCommonService, configService, questionCommon, fileRecordService) siteInfoController := controller_admin.NewSiteInfoController(siteInfoService) controllerSiteInfoController := controller.NewSiteInfoController(siteInfoCommonService) - notificationCommon := notificationcommon.NewNotificationCommon(dataData, notificationRepo, userCommon, activityRepo, followRepo, objService, v3, userExternalLoginRepo, siteInfoCommonService) + notificationCommon := notificationcommon.NewNotificationCommon(dataData, notificationRepo, userCommon, activityRepo, followRepo, objService, noticequeueService, userExternalLoginRepo, siteInfoCommonService) badgeRepo := badge.NewBadgeRepo(dataData, uniqueIDRepo) notificationService := notification.NewNotificationService(dataData, notificationRepo, notificationCommon, revisionService, userRepo, reportRepo, reviewService, badgeRepo) notificationController := controller.NewNotificationController(notificationService, rankService) @@ -233,7 +258,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, uploaderService := uploader.NewUploaderService(serviceConf, siteInfoCommonService, fileRecordService) uploadController := controller.NewUploadController(uploaderService) activityActivityRepo := activity.NewActivityRepo(dataData, configService) - activityCommon := activity_common2.NewActivityCommon(activityRepo, v) + activityCommon := activity_common2.NewActivityCommon(activityRepo, service) commentCommonService := comment_common.NewCommentCommonService(commentCommonRepo) activityService := activity2.NewActivityService(activityActivityRepo, userCommon, activityCommon, tagCommonService, objService, commentCommonService, revisionService, metaCommonService, configService) activityController := controller.NewActivityController(activityService) @@ -245,23 +270,33 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, permissionController := controller.NewPermissionController(rankService) userPluginController := controller.NewUserPluginController(pluginCommonService) reviewController := controller.NewReviewController(reviewService, rankService, captchaService) - metaService := meta2.NewMetaService(metaCommonService, userCommon, answerRepo, questionRepo, v2) + metaService := meta2.NewMetaService(metaCommonService, userCommon, answerRepo, questionRepo, eventqueueService) metaController := controller.NewMetaController(metaService) badgeGroupRepo := badge_group.NewBadgeGroupRepo(dataData, uniqueIDRepo) eventRuleRepo := badge.NewEventRuleRepo(dataData) - badgeAwardService := badge2.NewBadgeAwardService(badgeAwardRepo, badgeRepo, userCommon, objService, v3) - badgeEventService := badge2.NewBadgeEventService(dataData, v2, badgeRepo, eventRuleRepo, badgeAwardService) + badgeAwardService := badge2.NewBadgeAwardService(badgeAwardRepo, badgeRepo, userCommon, objService, noticequeueService) + badgeEventService := badge2.NewBadgeEventService(dataData, eventqueueService, badgeRepo, eventRuleRepo, badgeAwardService) badgeService := badge2.NewBadgeService(badgeRepo, badgeGroupRepo, badgeAwardRepo, badgeEventService, siteInfoCommonService) badgeController := controller.NewBadgeController(badgeService, badgeAwardService) controller_adminBadgeController := controller_admin.NewBadgeController(badgeService) - answerAPIRouter := router.NewAnswerAPIRouter(langController, userController, commentController, reportController, voteController, tagController, followController, collectionController, questionController, answerController, searchController, revisionController, rankController, userAdminController, reasonController, themeController, siteInfoController, controllerSiteInfoController, notificationController, dashboardController, uploadController, activityController, roleController, pluginController, permissionController, userPluginController, reviewController, metaController, badgeController, controller_adminBadgeController) + apiKeyRepo := api_key.NewAPIKeyRepo(dataData) + apiKeyService := apikey.NewAPIKeyService(apiKeyRepo) + adminAPIKeyController := controller_admin.NewAdminAPIKeyController(apiKeyService) + featureToggleService := feature_toggle.NewFeatureToggleService(siteInfoRepo) + mcpController := controller.NewMCPController(searchService, siteInfoCommonService, tagCommonService, questionCommon, commentRepo, userCommon, answerRepo, featureToggleService) + aiConversationRepo := ai_conversation.NewAIConversationRepo(dataData) + aiConversationService := ai_conversation2.NewAIConversationService(aiConversationRepo, userCommon) + aiController := controller.NewAIController(searchService, siteInfoCommonService, tagCommonService, questionCommon, commentRepo, userCommon, answerRepo, mcpController, aiConversationService, featureToggleService) + aiConversationController := controller.NewAIConversationController(aiConversationService, featureToggleService) + aiConversationAdminController := controller_admin.NewAIConversationAdminController(aiConversationService, featureToggleService) + answerAPIRouter := router.NewAnswerAPIRouter(langController, userController, commentController, reportController, voteController, tagController, followController, collectionController, questionController, answerController, searchController, revisionController, rankController, userAdminController, reasonController, themeController, siteInfoController, controllerSiteInfoController, notificationController, dashboardController, uploadController, activityController, roleController, pluginController, permissionController, userPluginController, reviewController, metaController, badgeController, controller_adminBadgeController, adminAPIKeyController, aiController, aiConversationController, aiConversationAdminController) swaggerRouter := router.NewSwaggerRouter(swaggerConf) uiRouter := router.NewUIRouter(controllerSiteInfoController, siteInfoCommonService) authUserMiddleware := middleware.NewAuthUserMiddleware(authService, siteInfoCommonService) avatarMiddleware := middleware.NewAvatarMiddleware(serviceConf, uploaderService) shortIDMiddleware := middleware.NewShortIDMiddleware(siteInfoCommonService) templateRenderController := templaterender.NewTemplateRenderController(questionService, userService, tagService, answerService, commentService, siteInfoCommonService, questionRepo) - templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService, v2, userService, questionService) + templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService, eventqueueService, userService, questionService) templateRouter := router.NewTemplateRouter(templateController, templateRenderController, siteInfoController, authUserMiddleware) connectorController := controller.NewConnectorController(siteInfoCommonService, emailService, userExternalLoginService) userCenterLoginService := user_external_login2.NewUserCenterLoginService(userRepo, userCommon, userExternalLoginRepo, userActiveActivityRepo, siteInfoCommonService) diff --git a/docs/docs.go b/docs/docs.go index fc4d9909e..9c984d26c 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + // Package docs Code generated by swaggo/swag. DO NOT EDIT package docs @@ -31,6 +50,297 @@ const docTemplate = `{ "responses": {} } }, + "/answer/admin/api/ai-config": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get AI configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get AI configuration", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteAIResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update AI configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update AI configuration", + "parameters": [ + { + "description": "AI config", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteAIReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/ai-models": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get AI models", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get AI models", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetAIModelResp" + } + } + } + } + ] + } + } + } + } + }, + "/answer/admin/api/ai-provider": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get AI provider configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get AI provider configuration", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetAIProviderResp" + } + } + } + } + ] + } + } + } + } + }, + "/answer/admin/api/ai/conversation": { + "get": { + "description": "get conversation detail for admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation-admin" + ], + "summary": "get conversation detail for admin", + "parameters": [ + { + "type": "string", + "description": "conversation id", + "name": "conversation_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.AIConversationAdminDetailResp" + } + } + } + ] + } + } + } + }, + "delete": { + "description": "delete conversation and its related records for admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation-admin" + ], + "summary": "delete conversation for admin", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AIConversationAdminDeleteReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/ai/conversation/page": { + "get": { + "description": "get conversation list for admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation-admin" + ], + "summary": "get conversation list for admin", + "parameters": [ + { + "type": "integer", + "description": "page", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "page size", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/pager.PageModel" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationAdminListItem" + } + } + } + } + ] + } + } + } + ] + } + } + } + } + }, "/answer/admin/api/answer/page": { "get": { "security": [ @@ -96,40 +406,196 @@ const docTemplate = `{ } } }, - "/answer/admin/api/answer/status": { - "put": { + "/answer/admin/api/answer/status": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update answer status", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update answer status", + "parameters": [ + { + "description": "AdminUpdateAnswerStatusReq", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AdminUpdateAnswerStatusReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/api-key": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update apikey", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update apikey", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.UpdateAPIKeyReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + }, + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "add apikey", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "add apikey", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AddAPIKeyReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.AddAPIKeyResp" + } + } + } + ] + } + } + } + }, + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "delete apikey", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "delete apikey", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.DeleteAPIKeyReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/api-key/all": { + "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "update answer status", - "consumes": [ - "application/json" - ], + "description": "get all api keys", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update answer status", - "parameters": [ - { - "description": "AdminUpdateAnswerStatusReq", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/schema.AdminUpdateAnswerStatusReq" - } - } - ], + "summary": "get all api keys", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/handler.RespBody" + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetAPIKeyResp" + } + } + } + } + ] } } } @@ -340,6 +806,77 @@ const docTemplate = `{ } } }, + "/answer/admin/api/mcp-config": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get MCP configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get MCP configuration", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteMCPResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update MCP configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update MCP configuration", + "parameters": [ + { + "description": "MCP config", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteMCPReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/plugin/config": { "get": { "security": [ @@ -1954,9 +2491,172 @@ const docTemplate = `{ "inactive" ], "type": "string", - "description": "user status", - "name": "status", - "in": "query" + "description": "user status", + "name": "status", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/pager.PageModel" + }, + { + "type": "object", + "properties": { + "records": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetUserPageResp" + } + } + } + } + ] + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/activity/timeline": { + "get": { + "description": "get object timeline", + "produces": [ + "application/json" + ], + "tags": [ + "Comment" + ], + "summary": "get object timeline", + "parameters": [ + { + "type": "string", + "description": "object id", + "name": "object_id", + "in": "query" + }, + { + "type": "string", + "description": "tag slug name", + "name": "tag_slug_name", + "in": "query" + }, + { + "enum": [ + "question", + "answer", + "tag" + ], + "type": "string", + "description": "object type", + "name": "object_type", + "in": "query" + }, + { + "type": "boolean", + "description": "is show vote", + "name": "show_vote", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.GetObjectTimelineResp" + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/activity/timeline/detail": { + "get": { + "description": "get object timeline detail", + "produces": [ + "application/json" + ], + "tags": [ + "Comment" + ], + "summary": "get object timeline detail", + "parameters": [ + { + "type": "string", + "description": "revision id", + "name": "revision_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.GetObjectTimelineResp" + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/ai/conversation": { + "get": { + "description": "get conversation detail", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation" + ], + "summary": "get conversation detail", + "parameters": [ + { + "type": "string", + "description": "conversation id", + "name": "conversation_id", + "in": "query", + "required": true } ], "responses": { @@ -1971,22 +2671,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "allOf": [ - { - "$ref": "#/definitions/pager.PageModel" - }, - { - "type": "object", - "properties": { - "records": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.GetUserPageResp" - } - } - } - } - ] + "$ref": "#/definitions/schema.AIConversationDetailResp" } } } @@ -1996,44 +2681,30 @@ const docTemplate = `{ } } }, - "/answer/api/v1/activity/timeline": { + "/answer/api/v1/ai/conversation/page": { "get": { - "description": "get object timeline", + "description": "get conversation list", + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "Comment" + "ai-conversation" ], - "summary": "get object timeline", + "summary": "get conversation list", "parameters": [ { - "type": "string", - "description": "object id", - "name": "object_id", - "in": "query" - }, - { - "type": "string", - "description": "tag slug name", - "name": "tag_slug_name", - "in": "query" - }, - { - "enum": [ - "question", - "answer", - "tag" - ], - "type": "string", - "description": "object type", - "name": "object_type", + "type": "integer", + "description": "page", + "name": "page", "in": "query" }, { - "type": "boolean", - "description": "is show vote", - "name": "show_vote", + "type": "integer", + "description": "page size", + "name": "page_size", "in": "query" } ], @@ -2049,7 +2720,22 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.GetObjectTimelineResp" + "allOf": [ + { + "$ref": "#/definitions/pager.PageModel" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationListItem" + } + } + } + } + ] } } } @@ -2059,42 +2745,35 @@ const docTemplate = `{ } } }, - "/answer/api/v1/activity/timeline/detail": { - "get": { - "description": "get object timeline detail", + "/answer/api/v1/ai/conversation/vote": { + "post": { + "description": "vote record", + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "Comment" + "ai-conversation" ], - "summary": "get object timeline detail", + "summary": "vote record", "parameters": [ { - "type": "string", - "description": "revision id", - "name": "revision_id", - "in": "query", - "required": true + "description": "vote request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AIConversationVoteReq" + } } ], "responses": { "200": { "description": "OK", "schema": { - "allOf": [ - { - "$ref": "#/definitions/handler.RespBody" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/schema.GetObjectTimelineResp" - } - } - } - ] + "$ref": "#/definitions/handler.RespBody" } } } @@ -7615,96 +8294,266 @@ const docTemplate = `{ "ssl_enabled": { "type": "boolean" }, - "ssl_key": { + "ssl_key": { + "type": "string" + }, + "ssl_mode": { + "type": "string" + }, + "ssl_root_cert": { + "type": "string" + } + } + }, + "install.InitBaseInfoReq": { + "type": "object", + "required": [ + "contact_email", + "email", + "external_content_display", + "lang", + "name", + "password", + "site_name", + "site_url" + ], + "properties": { + "contact_email": { + "type": "string", + "maxLength": 500 + }, + "email": { + "type": "string", + "maxLength": 500 + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "lang": { + "type": "string", + "maxLength": 30 + }, + "login_required": { + "type": "boolean" + }, + "name": { + "type": "string", + "maxLength": 30, + "minLength": 2 + }, + "password": { + "type": "string", + "maxLength": 32, + "minLength": 8 + }, + "site_name": { + "type": "string", + "maxLength": 30 + }, + "site_url": { + "type": "string", + "maxLength": 512 + } + } + }, + "pager.PageModel": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "list": {} + } + }, + "plugin.EmbedConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "platform": { + "type": "string" + } + } + }, + "plugin.RenderConfig": { + "type": "object", + "properties": { + "select_theme": { + "type": "string" + } + } + }, + "schema.AIConversationAdminDeleteReq": { + "type": "object", + "required": [ + "conversation_id" + ], + "properties": { + "conversation_id": { + "type": "string" + } + } + }, + "schema.AIConversationAdminDetailResp": { + "type": "object", + "properties": { + "conversation_id": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "records": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationRecord" + } + }, + "topic": { + "type": "string" + }, + "user_info": { + "$ref": "#/definitions/schema.AIConversationUserInfo" + } + } + }, + "schema.AIConversationAdminListItem": { + "type": "object", + "properties": { + "created_at": { + "type": "integer" + }, + "helpful_count": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "topic": { + "type": "string" + }, + "unhelpful_count": { + "type": "integer" + }, + "user_info": { + "$ref": "#/definitions/schema.AIConversationUserInfo" + } + } + }, + "schema.AIConversationDetailResp": { + "type": "object", + "properties": { + "conversation_id": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "records": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationRecord" + } + }, + "topic": { "type": "string" }, - "ssl_mode": { + "updated_at": { + "type": "integer" + } + } + }, + "schema.AIConversationListItem": { + "type": "object", + "properties": { + "conversation_id": { "type": "string" }, - "ssl_root_cert": { + "created_at": { + "type": "integer" + }, + "topic": { "type": "string" } } }, - "install.InitBaseInfoReq": { + "schema.AIConversationRecord": { "type": "object", - "required": [ - "contact_email", - "email", - "external_content_display", - "lang", - "name", - "password", - "site_name", - "site_url" - ], "properties": { - "contact_email": { - "type": "string", - "maxLength": 500 - }, - "email": { - "type": "string", - "maxLength": 500 - }, - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "lang": { - "type": "string", - "maxLength": 30 + "chat_completion_id": { + "type": "string" }, - "login_required": { - "type": "boolean" + "content": { + "type": "string" }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 2 + "created_at": { + "type": "integer" }, - "password": { - "type": "string", - "maxLength": 32, - "minLength": 8 + "helpful": { + "type": "integer" }, - "site_name": { - "type": "string", - "maxLength": 30 + "role": { + "type": "string" }, - "site_url": { - "type": "string", - "maxLength": 512 + "unhelpful": { + "type": "integer" } } }, - "pager.PageModel": { + "schema.AIConversationUserInfo": { "type": "object", "properties": { - "count": { + "avatar": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "rank": { "type": "integer" }, - "list": {} + "username": { + "type": "string" + } } }, - "plugin.EmbedConfig": { + "schema.AIConversationVoteReq": { "type": "object", + "required": [ + "chat_completion_id", + "vote_type" + ], "properties": { - "enable": { + "cancel": { "type": "boolean" }, - "platform": { + "chat_completion_id": { "type": "string" + }, + "vote_type": { + "type": "string", + "enum": [ + "helpful", + "unhelpful" + ] } } }, - "plugin.RenderConfig": { + "schema.AIPromptConfig": { "type": "object", "properties": { - "select_theme": { + "en_us": { + "type": "string" + }, + "zh_cn": { "type": "string" } } @@ -7799,6 +8648,34 @@ const docTemplate = `{ } } }, + "schema.AddAPIKeyReq": { + "type": "object", + "required": [ + "description", + "scope" + ], + "properties": { + "description": { + "type": "string", + "maxLength": 150 + }, + "scope": { + "type": "string", + "enum": [ + "read-only", + "global" + ] + } + } + }, + "schema.AddAPIKeyResp": { + "type": "object", + "properties": { + "access_key": { + "type": "string" + } + } + }, "schema.AddCommentReq": { "type": "object", "required": [ @@ -8279,6 +9156,14 @@ const docTemplate = `{ } } }, + "schema.DeleteAPIKeyReq": { + "type": "object", + "properties": { + "id": { + "type": "integer" + } + } + }, "schema.DeletePermanentlyReq": { "type": "object", "required": [ @@ -8395,6 +9280,60 @@ const docTemplate = `{ } } }, + "schema.GetAIModelResp": { + "type": "object", + "properties": { + "created": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "object": { + "type": "string" + }, + "owned_by": { + "type": "string" + } + } + }, + "schema.GetAIProviderResp": { + "type": "object", + "properties": { + "default_api_host": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "schema.GetAPIKeyResp": { + "type": "object", + "properties": { + "access_key": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "last_used_at": { + "type": "integer" + }, + "scope": { + "type": "string" + } + } + }, "schema.GetAnswerInfoResp": { "type": "object", "properties": { @@ -10478,6 +11417,69 @@ const docTemplate = `{ } } }, + "schema.SiteAIProvider": { + "type": "object", + "properties": { + "api_host": { + "type": "string", + "maxLength": 512 + }, + "api_key": { + "type": "string", + "maxLength": 256 + }, + "model": { + "type": "string", + "maxLength": 100 + }, + "provider": { + "type": "string", + "maxLength": 50 + } + } + }, + "schema.SiteAIReq": { + "type": "object", + "properties": { + "ai_providers": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteAIProvider" + } + }, + "chosen_provider": { + "type": "string", + "maxLength": 50 + }, + "enabled": { + "type": "boolean" + }, + "prompt_config": { + "$ref": "#/definitions/schema.AIPromptConfig" + } + } + }, + "schema.SiteAIResp": { + "type": "object", + "properties": { + "ai_providers": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteAIProvider" + } + }, + "chosen_provider": { + "type": "string", + "maxLength": 50 + }, + "enabled": { + "type": "boolean" + }, + "prompt_config": { + "$ref": "#/definitions/schema.AIPromptConfig" + } + } + }, "schema.SiteBrandingReq": { "type": "object", "properties": { @@ -10639,6 +11641,9 @@ const docTemplate = `{ "schema.SiteInfoResp": { "type": "object", "properties": { + "ai_enabled": { + "type": "boolean" + }, "branding": { "$ref": "#/definitions/schema.SiteBrandingResp" }, @@ -10654,6 +11659,9 @@ const docTemplate = `{ "login": { "$ref": "#/definitions/schema.SiteLoginResp" }, + "mcp_enabled": { + "type": "boolean" + }, "revision": { "type": "string" }, @@ -10848,6 +11856,31 @@ const docTemplate = `{ } } }, + "schema.SiteMCPReq": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "schema.SiteMCPResp": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "http_header": { + "type": "string" + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, "schema.SiteSeoReq": { "type": "object", "required": [ @@ -10892,6 +11925,13 @@ const docTemplate = `{ "type": "string", "maxLength": 100 }, + "layout": { + "type": "string", + "enum": [ + "Full-width", + "Fixed-width" + ] + }, "theme": { "type": "string", "maxLength": 255 @@ -10908,6 +11948,9 @@ const docTemplate = `{ "color_scheme": { "type": "string" }, + "layout": { + "type": "string" + }, "theme": { "type": "string" }, @@ -11262,6 +12305,22 @@ const docTemplate = `{ } } }, + "schema.UpdateAPIKeyReq": { + "type": "object", + "required": [ + "description", + "id" + ], + "properties": { + "description": { + "type": "string", + "maxLength": 150 + }, + "id": { + "type": "integer" + } + } + }, "schema.UpdateBadgeStatusReq": { "type": "object", "required": [ diff --git a/docs/swagger.json b/docs/swagger.json index e0f6378e4..67148ea44 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -23,6 +23,297 @@ "responses": {} } }, + "/answer/admin/api/ai-config": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get AI configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get AI configuration", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteAIResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update AI configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update AI configuration", + "parameters": [ + { + "description": "AI config", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteAIReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/ai-models": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get AI models", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get AI models", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetAIModelResp" + } + } + } + } + ] + } + } + } + } + }, + "/answer/admin/api/ai-provider": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get AI provider configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get AI provider configuration", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetAIProviderResp" + } + } + } + } + ] + } + } + } + } + }, + "/answer/admin/api/ai/conversation": { + "get": { + "description": "get conversation detail for admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation-admin" + ], + "summary": "get conversation detail for admin", + "parameters": [ + { + "type": "string", + "description": "conversation id", + "name": "conversation_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.AIConversationAdminDetailResp" + } + } + } + ] + } + } + } + }, + "delete": { + "description": "delete conversation and its related records for admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation-admin" + ], + "summary": "delete conversation for admin", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AIConversationAdminDeleteReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/ai/conversation/page": { + "get": { + "description": "get conversation list for admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation-admin" + ], + "summary": "get conversation list for admin", + "parameters": [ + { + "type": "integer", + "description": "page", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "page size", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/pager.PageModel" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationAdminListItem" + } + } + } + } + ] + } + } + } + ] + } + } + } + } + }, "/answer/admin/api/answer/page": { "get": { "security": [ @@ -88,40 +379,196 @@ } } }, - "/answer/admin/api/answer/status": { - "put": { + "/answer/admin/api/answer/status": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update answer status", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update answer status", + "parameters": [ + { + "description": "AdminUpdateAnswerStatusReq", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AdminUpdateAnswerStatusReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/api-key": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update apikey", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update apikey", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.UpdateAPIKeyReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + }, + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "add apikey", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "add apikey", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AddAPIKeyReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.AddAPIKeyResp" + } + } + } + ] + } + } + } + }, + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "delete apikey", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "delete apikey", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.DeleteAPIKeyReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/api-key/all": { + "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "update answer status", - "consumes": [ - "application/json" - ], + "description": "get all api keys", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update answer status", - "parameters": [ - { - "description": "AdminUpdateAnswerStatusReq", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/schema.AdminUpdateAnswerStatusReq" - } - } - ], + "summary": "get all api keys", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/handler.RespBody" + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetAPIKeyResp" + } + } + } + } + ] } } } @@ -332,6 +779,77 @@ } } }, + "/answer/admin/api/mcp-config": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get MCP configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get MCP configuration", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteMCPResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update MCP configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update MCP configuration", + "parameters": [ + { + "description": "MCP config", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteMCPReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/plugin/config": { "get": { "security": [ @@ -1946,9 +2464,172 @@ "inactive" ], "type": "string", - "description": "user status", - "name": "status", - "in": "query" + "description": "user status", + "name": "status", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/pager.PageModel" + }, + { + "type": "object", + "properties": { + "records": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetUserPageResp" + } + } + } + } + ] + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/activity/timeline": { + "get": { + "description": "get object timeline", + "produces": [ + "application/json" + ], + "tags": [ + "Comment" + ], + "summary": "get object timeline", + "parameters": [ + { + "type": "string", + "description": "object id", + "name": "object_id", + "in": "query" + }, + { + "type": "string", + "description": "tag slug name", + "name": "tag_slug_name", + "in": "query" + }, + { + "enum": [ + "question", + "answer", + "tag" + ], + "type": "string", + "description": "object type", + "name": "object_type", + "in": "query" + }, + { + "type": "boolean", + "description": "is show vote", + "name": "show_vote", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.GetObjectTimelineResp" + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/activity/timeline/detail": { + "get": { + "description": "get object timeline detail", + "produces": [ + "application/json" + ], + "tags": [ + "Comment" + ], + "summary": "get object timeline detail", + "parameters": [ + { + "type": "string", + "description": "revision id", + "name": "revision_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.GetObjectTimelineResp" + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/ai/conversation": { + "get": { + "description": "get conversation detail", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation" + ], + "summary": "get conversation detail", + "parameters": [ + { + "type": "string", + "description": "conversation id", + "name": "conversation_id", + "in": "query", + "required": true } ], "responses": { @@ -1963,22 +2644,7 @@ "type": "object", "properties": { "data": { - "allOf": [ - { - "$ref": "#/definitions/pager.PageModel" - }, - { - "type": "object", - "properties": { - "records": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.GetUserPageResp" - } - } - } - } - ] + "$ref": "#/definitions/schema.AIConversationDetailResp" } } } @@ -1988,44 +2654,30 @@ } } }, - "/answer/api/v1/activity/timeline": { + "/answer/api/v1/ai/conversation/page": { "get": { - "description": "get object timeline", + "description": "get conversation list", + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "Comment" + "ai-conversation" ], - "summary": "get object timeline", + "summary": "get conversation list", "parameters": [ { - "type": "string", - "description": "object id", - "name": "object_id", - "in": "query" - }, - { - "type": "string", - "description": "tag slug name", - "name": "tag_slug_name", - "in": "query" - }, - { - "enum": [ - "question", - "answer", - "tag" - ], - "type": "string", - "description": "object type", - "name": "object_type", + "type": "integer", + "description": "page", + "name": "page", "in": "query" }, { - "type": "boolean", - "description": "is show vote", - "name": "show_vote", + "type": "integer", + "description": "page size", + "name": "page_size", "in": "query" } ], @@ -2041,7 +2693,22 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.GetObjectTimelineResp" + "allOf": [ + { + "$ref": "#/definitions/pager.PageModel" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationListItem" + } + } + } + } + ] } } } @@ -2051,42 +2718,35 @@ } } }, - "/answer/api/v1/activity/timeline/detail": { - "get": { - "description": "get object timeline detail", + "/answer/api/v1/ai/conversation/vote": { + "post": { + "description": "vote record", + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "Comment" + "ai-conversation" ], - "summary": "get object timeline detail", + "summary": "vote record", "parameters": [ { - "type": "string", - "description": "revision id", - "name": "revision_id", - "in": "query", - "required": true + "description": "vote request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AIConversationVoteReq" + } } ], "responses": { "200": { "description": "OK", "schema": { - "allOf": [ - { - "$ref": "#/definitions/handler.RespBody" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/schema.GetObjectTimelineResp" - } - } - } - ] + "$ref": "#/definitions/handler.RespBody" } } } @@ -7607,96 +8267,266 @@ "ssl_enabled": { "type": "boolean" }, - "ssl_key": { + "ssl_key": { + "type": "string" + }, + "ssl_mode": { + "type": "string" + }, + "ssl_root_cert": { + "type": "string" + } + } + }, + "install.InitBaseInfoReq": { + "type": "object", + "required": [ + "contact_email", + "email", + "external_content_display", + "lang", + "name", + "password", + "site_name", + "site_url" + ], + "properties": { + "contact_email": { + "type": "string", + "maxLength": 500 + }, + "email": { + "type": "string", + "maxLength": 500 + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "lang": { + "type": "string", + "maxLength": 30 + }, + "login_required": { + "type": "boolean" + }, + "name": { + "type": "string", + "maxLength": 30, + "minLength": 2 + }, + "password": { + "type": "string", + "maxLength": 32, + "minLength": 8 + }, + "site_name": { + "type": "string", + "maxLength": 30 + }, + "site_url": { + "type": "string", + "maxLength": 512 + } + } + }, + "pager.PageModel": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "list": {} + } + }, + "plugin.EmbedConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "platform": { + "type": "string" + } + } + }, + "plugin.RenderConfig": { + "type": "object", + "properties": { + "select_theme": { + "type": "string" + } + } + }, + "schema.AIConversationAdminDeleteReq": { + "type": "object", + "required": [ + "conversation_id" + ], + "properties": { + "conversation_id": { + "type": "string" + } + } + }, + "schema.AIConversationAdminDetailResp": { + "type": "object", + "properties": { + "conversation_id": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "records": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationRecord" + } + }, + "topic": { + "type": "string" + }, + "user_info": { + "$ref": "#/definitions/schema.AIConversationUserInfo" + } + } + }, + "schema.AIConversationAdminListItem": { + "type": "object", + "properties": { + "created_at": { + "type": "integer" + }, + "helpful_count": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "topic": { + "type": "string" + }, + "unhelpful_count": { + "type": "integer" + }, + "user_info": { + "$ref": "#/definitions/schema.AIConversationUserInfo" + } + } + }, + "schema.AIConversationDetailResp": { + "type": "object", + "properties": { + "conversation_id": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "records": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationRecord" + } + }, + "topic": { "type": "string" }, - "ssl_mode": { + "updated_at": { + "type": "integer" + } + } + }, + "schema.AIConversationListItem": { + "type": "object", + "properties": { + "conversation_id": { "type": "string" }, - "ssl_root_cert": { + "created_at": { + "type": "integer" + }, + "topic": { "type": "string" } } }, - "install.InitBaseInfoReq": { + "schema.AIConversationRecord": { "type": "object", - "required": [ - "contact_email", - "email", - "external_content_display", - "lang", - "name", - "password", - "site_name", - "site_url" - ], "properties": { - "contact_email": { - "type": "string", - "maxLength": 500 - }, - "email": { - "type": "string", - "maxLength": 500 - }, - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "lang": { - "type": "string", - "maxLength": 30 + "chat_completion_id": { + "type": "string" }, - "login_required": { - "type": "boolean" + "content": { + "type": "string" }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 2 + "created_at": { + "type": "integer" }, - "password": { - "type": "string", - "maxLength": 32, - "minLength": 8 + "helpful": { + "type": "integer" }, - "site_name": { - "type": "string", - "maxLength": 30 + "role": { + "type": "string" }, - "site_url": { - "type": "string", - "maxLength": 512 + "unhelpful": { + "type": "integer" } } }, - "pager.PageModel": { + "schema.AIConversationUserInfo": { "type": "object", "properties": { - "count": { + "avatar": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "rank": { "type": "integer" }, - "list": {} + "username": { + "type": "string" + } } }, - "plugin.EmbedConfig": { + "schema.AIConversationVoteReq": { "type": "object", + "required": [ + "chat_completion_id", + "vote_type" + ], "properties": { - "enable": { + "cancel": { "type": "boolean" }, - "platform": { + "chat_completion_id": { "type": "string" + }, + "vote_type": { + "type": "string", + "enum": [ + "helpful", + "unhelpful" + ] } } }, - "plugin.RenderConfig": { + "schema.AIPromptConfig": { "type": "object", "properties": { - "select_theme": { + "en_us": { + "type": "string" + }, + "zh_cn": { "type": "string" } } @@ -7791,6 +8621,34 @@ } } }, + "schema.AddAPIKeyReq": { + "type": "object", + "required": [ + "description", + "scope" + ], + "properties": { + "description": { + "type": "string", + "maxLength": 150 + }, + "scope": { + "type": "string", + "enum": [ + "read-only", + "global" + ] + } + } + }, + "schema.AddAPIKeyResp": { + "type": "object", + "properties": { + "access_key": { + "type": "string" + } + } + }, "schema.AddCommentReq": { "type": "object", "required": [ @@ -8271,6 +9129,14 @@ } } }, + "schema.DeleteAPIKeyReq": { + "type": "object", + "properties": { + "id": { + "type": "integer" + } + } + }, "schema.DeletePermanentlyReq": { "type": "object", "required": [ @@ -8387,6 +9253,60 @@ } } }, + "schema.GetAIModelResp": { + "type": "object", + "properties": { + "created": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "object": { + "type": "string" + }, + "owned_by": { + "type": "string" + } + } + }, + "schema.GetAIProviderResp": { + "type": "object", + "properties": { + "default_api_host": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "schema.GetAPIKeyResp": { + "type": "object", + "properties": { + "access_key": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "last_used_at": { + "type": "integer" + }, + "scope": { + "type": "string" + } + } + }, "schema.GetAnswerInfoResp": { "type": "object", "properties": { @@ -10470,6 +11390,69 @@ } } }, + "schema.SiteAIProvider": { + "type": "object", + "properties": { + "api_host": { + "type": "string", + "maxLength": 512 + }, + "api_key": { + "type": "string", + "maxLength": 256 + }, + "model": { + "type": "string", + "maxLength": 100 + }, + "provider": { + "type": "string", + "maxLength": 50 + } + } + }, + "schema.SiteAIReq": { + "type": "object", + "properties": { + "ai_providers": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteAIProvider" + } + }, + "chosen_provider": { + "type": "string", + "maxLength": 50 + }, + "enabled": { + "type": "boolean" + }, + "prompt_config": { + "$ref": "#/definitions/schema.AIPromptConfig" + } + } + }, + "schema.SiteAIResp": { + "type": "object", + "properties": { + "ai_providers": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteAIProvider" + } + }, + "chosen_provider": { + "type": "string", + "maxLength": 50 + }, + "enabled": { + "type": "boolean" + }, + "prompt_config": { + "$ref": "#/definitions/schema.AIPromptConfig" + } + } + }, "schema.SiteBrandingReq": { "type": "object", "properties": { @@ -10631,6 +11614,9 @@ "schema.SiteInfoResp": { "type": "object", "properties": { + "ai_enabled": { + "type": "boolean" + }, "branding": { "$ref": "#/definitions/schema.SiteBrandingResp" }, @@ -10646,6 +11632,9 @@ "login": { "$ref": "#/definitions/schema.SiteLoginResp" }, + "mcp_enabled": { + "type": "boolean" + }, "revision": { "type": "string" }, @@ -10840,6 +11829,31 @@ } } }, + "schema.SiteMCPReq": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "schema.SiteMCPResp": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "http_header": { + "type": "string" + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, "schema.SiteSeoReq": { "type": "object", "required": [ @@ -10884,6 +11898,13 @@ "type": "string", "maxLength": 100 }, + "layout": { + "type": "string", + "enum": [ + "Full-width", + "Fixed-width" + ] + }, "theme": { "type": "string", "maxLength": 255 @@ -10900,6 +11921,9 @@ "color_scheme": { "type": "string" }, + "layout": { + "type": "string" + }, "theme": { "type": "string" }, @@ -11254,6 +12278,22 @@ } } }, + "schema.UpdateAPIKeyReq": { + "type": "object", + "required": [ + "description", + "id" + ], + "properties": { + "description": { + "type": "string", + "maxLength": 150 + }, + "id": { + "type": "integer" + } + } + }, "schema.UpdateBadgeStatusReq": { "type": "object", "required": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 42df5cbf1..03e3508be 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,3 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + basePath: / definitions: constant.NotificationChannelKey: @@ -140,6 +157,117 @@ definitions: select_theme: type: string type: object + schema.AIConversationAdminDeleteReq: + properties: + conversation_id: + type: string + required: + - conversation_id + type: object + schema.AIConversationAdminDetailResp: + properties: + conversation_id: + type: string + created_at: + type: integer + records: + items: + $ref: '#/definitions/schema.AIConversationRecord' + type: array + topic: + type: string + user_info: + $ref: '#/definitions/schema.AIConversationUserInfo' + type: object + schema.AIConversationAdminListItem: + properties: + created_at: + type: integer + helpful_count: + type: integer + id: + type: string + topic: + type: string + unhelpful_count: + type: integer + user_info: + $ref: '#/definitions/schema.AIConversationUserInfo' + type: object + schema.AIConversationDetailResp: + properties: + conversation_id: + type: string + created_at: + type: integer + records: + items: + $ref: '#/definitions/schema.AIConversationRecord' + type: array + topic: + type: string + updated_at: + type: integer + type: object + schema.AIConversationListItem: + properties: + conversation_id: + type: string + created_at: + type: integer + topic: + type: string + type: object + schema.AIConversationRecord: + properties: + chat_completion_id: + type: string + content: + type: string + created_at: + type: integer + helpful: + type: integer + role: + type: string + unhelpful: + type: integer + type: object + schema.AIConversationUserInfo: + properties: + avatar: + type: string + display_name: + type: string + id: + type: string + rank: + type: integer + username: + type: string + type: object + schema.AIConversationVoteReq: + properties: + cancel: + type: boolean + chat_completion_id: + type: string + vote_type: + enum: + - helpful + - unhelpful + type: string + required: + - chat_completion_id + - vote_type + type: object + schema.AIPromptConfig: + properties: + en_us: + type: string + zh_cn: + type: string + type: object schema.AcceptAnswerReq: properties: answer_id: @@ -199,6 +327,25 @@ definitions: verify: type: boolean type: object + schema.AddAPIKeyReq: + properties: + description: + maxLength: 150 + type: string + scope: + enum: + - read-only + - global + type: string + required: + - description + - scope + type: object + schema.AddAPIKeyResp: + properties: + access_key: + type: string + type: object schema.AddCommentReq: properties: captcha_code: @@ -529,6 +676,11 @@ definitions: name: type: string type: object + schema.DeleteAPIKeyReq: + properties: + id: + type: integer + type: object schema.DeletePermanentlyReq: properties: type: @@ -612,6 +764,41 @@ definitions: description: if user is followed object will be true,otherwise false type: boolean type: object + schema.GetAIModelResp: + properties: + created: + type: integer + id: + type: string + object: + type: string + owned_by: + type: string + type: object + schema.GetAIProviderResp: + properties: + default_api_host: + type: string + display_name: + type: string + name: + type: string + type: object + schema.GetAPIKeyResp: + properties: + access_key: + type: string + created_at: + type: integer + description: + type: string + id: + type: integer + last_used_at: + type: integer + scope: + type: string + type: object schema.GetAnswerInfoResp: properties: info: @@ -2055,6 +2242,49 @@ definitions: required: - user_id type: object + schema.SiteAIProvider: + properties: + api_host: + maxLength: 512 + type: string + api_key: + maxLength: 256 + type: string + model: + maxLength: 100 + type: string + provider: + maxLength: 50 + type: string + type: object + schema.SiteAIReq: + properties: + ai_providers: + items: + $ref: '#/definitions/schema.SiteAIProvider' + type: array + chosen_provider: + maxLength: 50 + type: string + enabled: + type: boolean + prompt_config: + $ref: '#/definitions/schema.AIPromptConfig' + type: object + schema.SiteAIResp: + properties: + ai_providers: + items: + $ref: '#/definitions/schema.SiteAIProvider' + type: array + chosen_provider: + maxLength: 50 + type: string + enabled: + type: boolean + prompt_config: + $ref: '#/definitions/schema.AIPromptConfig' + type: object schema.SiteBrandingReq: properties: favicon: @@ -2171,6 +2401,8 @@ definitions: type: object schema.SiteInfoResp: properties: + ai_enabled: + type: boolean branding: $ref: '#/definitions/schema.SiteBrandingResp' custom_css_html: @@ -2181,6 +2413,8 @@ definitions: $ref: '#/definitions/schema.SiteInterfaceResp' login: $ref: '#/definitions/schema.SiteLoginResp' + mcp_enabled: + type: boolean revision: type: string site_legal: @@ -2312,6 +2546,22 @@ definitions: login_required: type: boolean type: object + schema.SiteMCPReq: + properties: + enabled: + type: boolean + type: object + schema.SiteMCPResp: + properties: + enabled: + type: boolean + http_header: + type: string + type: + type: string + url: + type: string + type: object schema.SiteSeoReq: properties: permalink: @@ -2341,6 +2591,11 @@ definitions: color_scheme: maxLength: 100 type: string + layout: + enum: + - Full-width + - Fixed-width + type: string theme: maxLength: 255 type: string @@ -2354,6 +2609,8 @@ definitions: properties: color_scheme: type: string + layout: + type: string theme: type: string theme_config: @@ -2595,6 +2852,17 @@ definitions: url_title: type: string type: object + schema.UpdateAPIKeyReq: + properties: + description: + maxLength: 150 + type: string + id: + type: integer + required: + - description + - id + type: object schema.UpdateBadgeStatusReq: properties: id: @@ -3183,6 +3451,174 @@ paths: summary: if config file not exist try to redirect to install page tags: - installation + /answer/admin/api/ai-config: + get: + description: get AI configuration + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteAIResp' + type: object + security: + - ApiKeyAuth: [] + summary: get AI configuration + tags: + - admin + put: + description: update AI configuration + parameters: + - description: AI config + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteAIReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update AI configuration + tags: + - admin + /answer/admin/api/ai-models: + post: + description: get AI models + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + items: + $ref: '#/definitions/schema.GetAIModelResp' + type: array + type: object + security: + - ApiKeyAuth: [] + summary: get AI models + tags: + - admin + /answer/admin/api/ai-provider: + get: + description: get AI provider configuration + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + items: + $ref: '#/definitions/schema.GetAIProviderResp' + type: array + type: object + security: + - ApiKeyAuth: [] + summary: get AI provider configuration + tags: + - admin + /answer/admin/api/ai/conversation: + delete: + consumes: + - application/json + description: delete conversation and its related records for admin + parameters: + - description: apikey + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.AIConversationAdminDeleteReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + summary: delete conversation for admin + tags: + - ai-conversation-admin + get: + consumes: + - application/json + description: get conversation detail for admin + parameters: + - description: conversation id + in: query + name: conversation_id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.AIConversationAdminDetailResp' + type: object + summary: get conversation detail for admin + tags: + - ai-conversation-admin + /answer/admin/api/ai/conversation/page: + get: + consumes: + - application/json + description: get conversation list for admin + parameters: + - description: page + in: query + name: page + type: integer + - description: page size + in: query + name: page_size + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + allOf: + - $ref: '#/definitions/pager.PageModel' + - properties: + list: + items: + $ref: '#/definitions/schema.AIConversationAdminListItem' + type: array + type: object + type: object + summary: get conversation list for admin + tags: + - ai-conversation-admin /answer/admin/api/answer/page: get: consumes: @@ -3249,6 +3685,97 @@ paths: summary: update answer status tags: - admin + /answer/admin/api/api-key: + delete: + description: delete apikey + parameters: + - description: apikey + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.DeleteAPIKeyReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: delete apikey + tags: + - admin + post: + description: add apikey + parameters: + - description: apikey + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.AddAPIKeyReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.AddAPIKeyResp' + type: object + security: + - ApiKeyAuth: [] + summary: add apikey + tags: + - admin + put: + description: update apikey + parameters: + - description: apikey + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.UpdateAPIKeyReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update apikey + tags: + - admin + /answer/admin/api/api-key/all: + get: + description: get all api keys + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + items: + $ref: '#/definitions/schema.GetAPIKeyResp' + type: array + type: object + security: + - ApiKeyAuth: [] + summary: get all api keys + tags: + - admin /answer/admin/api/badge/status: put: consumes: @@ -3374,6 +3901,47 @@ paths: summary: Get language options tags: - Lang + /answer/admin/api/mcp-config: + get: + description: get MCP configuration + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteMCPResp' + type: object + security: + - ApiKeyAuth: [] + summary: get MCP configuration + tags: + - admin + put: + description: update MCP configuration + parameters: + - description: MCP config + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteMCPReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update MCP configuration + tags: + - admin /answer/admin/api/plugin/config: get: description: get plugin config @@ -4417,6 +4985,90 @@ paths: summary: get object timeline detail tags: - Comment + /answer/api/v1/ai/conversation: + get: + consumes: + - application/json + description: get conversation detail + parameters: + - description: conversation id + in: query + name: conversation_id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.AIConversationDetailResp' + type: object + summary: get conversation detail + tags: + - ai-conversation + /answer/api/v1/ai/conversation/page: + get: + consumes: + - application/json + description: get conversation list + parameters: + - description: page + in: query + name: page + type: integer + - description: page size + in: query + name: page_size + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + allOf: + - $ref: '#/definitions/pager.PageModel' + - properties: + list: + items: + $ref: '#/definitions/schema.AIConversationListItem' + type: array + type: object + type: object + summary: get conversation list + tags: + - ai-conversation + /answer/api/v1/ai/conversation/vote: + post: + consumes: + - application/json + description: vote record + parameters: + - description: vote request + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.AIConversationVoteReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + summary: vote record + tags: + - ai-conversation /answer/api/v1/answer: delete: consumes: diff --git a/go.mod b/go.mod index 52d64c738..5c48abfdb 100644 --- a/go.mod +++ b/go.mod @@ -30,6 +30,7 @@ require ( github.com/go-playground/locales v0.14.1 github.com/go-playground/universal-translator v0.18.1 github.com/go-playground/validator/v10 v10.22.1 + github.com/go-resty/resty/v2 v2.17.1 github.com/go-sql-driver/mysql v1.8.1 github.com/goccy/go-json v0.10.3 github.com/google/uuid v1.6.0 @@ -37,11 +38,14 @@ require ( github.com/grokify/html-strip-tags-go v0.1.0 github.com/jinzhu/copier v0.4.0 github.com/jinzhu/now v1.1.5 + github.com/joho/godotenv v1.5.1 github.com/lib/pq v1.10.9 + github.com/mark3labs/mcp-go v0.43.2 github.com/microcosm-cc/bluemonday v1.0.27 github.com/mozillazg/go-pinyin v0.20.0 github.com/ory/dockertest/v3 v3.11.0 github.com/robfig/cron/v3 v3.0.1 + github.com/sashabaranov/go-openai v1.41.2 github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405 github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822083413-c0075a2d401f @@ -79,6 +83,8 @@ require ( github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/andybalholm/brotli v1.1.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/buger/jsonparser v1.1.1 // indirect github.com/bytedance/sonic v1.12.2 // indirect github.com/bytedance/sonic/loader v0.2.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect @@ -117,7 +123,7 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/joho/godotenv v1.5.1 // indirect + github.com/invopop/jsonschema v0.13.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect @@ -146,7 +152,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.7.0 // indirect + github.com/spf13/cast v1.7.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.19.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect @@ -155,9 +161,11 @@ require ( github.com/tidwall/pretty v1.2.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect + github.com/yosida95/uritemplate/v3 v3.0.2 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/arch v0.10.0 // indirect diff --git a/go.sum b/go.sum index 69d97751e..bf30d85b3 100644 --- a/go.sum +++ b/go.sum @@ -54,10 +54,14 @@ github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg= @@ -197,6 +201,8 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4= +github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= @@ -301,6 +307,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= +github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= @@ -410,6 +418,8 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mark3labs/mcp-go v0.43.2 h1:21PUSlWWiSbUPQwXIJ5WKlETixpFpq+WBpbMGDSVy/I= +github.com/mark3labs/mcp-go v0.43.2/go.mod h1:YnJfOL382MIWDx1kMY+2zsRHU/q78dBg9aFb8W6Thdw= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -543,6 +553,8 @@ github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sashabaranov/go-openai v1.41.2 h1:vfPRBZNMpnqu8ELsclWcAvF19lDNgh1t6TVfFFOPiSM= +github.com/sashabaranov/go-openai v1.41.2/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405 h1:2ieGkj4z/YPXVyQ2ayZUg3GwE1pYWd5f1RB6DzAOXKM= github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405/go.mod h1:rIxVzVLKlBwLxO+lC+k/I4HJfRQcemg/f/76Xmmzsec= @@ -576,8 +588,8 @@ github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9yS github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= -github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= @@ -630,6 +642,8 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -638,6 +652,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= +github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -801,6 +817,8 @@ golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/internal/base/constant/ai_config.go b/internal/base/constant/ai_config.go new file mode 100644 index 000000000..aa733bbaf --- /dev/null +++ b/internal/base/constant/ai_config.go @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package constant + +const ( + AIConfigProvider = "ai_config.provider" +) + +const ( + DefaultAIPromptConfigZhCN = `你是一个智能助手,可以帮助用户查询系统中的信息。用户问题:%s + +你可以使用以下工具来查询系统信息: +- get_questions: 搜索系统中已存在的问题,使用这个工具可以获取问题列表后注意需要使用 get_answers_by_question_id 获取问题的答案 +- get_answers_by_question_id: 根据问题ID获取该问题的所有答案 +- get_comments: 搜索评论信息 +- get_tags: 搜索标签信息 +- get_tag_detail: 获取特定标签的详细信息 +- get_user: 搜索用户信息 + +请根据用户的问题智能地使用这些工具来提供准确的答案。如果需要查询系统信息,请先使用相应的工具获取数据。` + DefaultAIPromptConfigEnUS = `You are an intelligent assistant that can help users query information in the system. User question: %s + +You can use the following tools to query system information: +- get_questions: Search for existing questions in the system. After using this tool to get the question list, you need to use get_answers_by_question_id to get the answers to the questions +- get_answers_by_question_id: Get all answers for a question based on question ID +- get_comments: Search for comment information +- get_tags: Search for tag information +- get_tag_detail: Get detailed information about a specific tag +- get_user: Search for user information + +Please intelligently use these tools based on the user's question to provide accurate answers. If you need to query system information, please use the appropriate tools to get the data first.` +) diff --git a/internal/base/constant/site_type.go b/internal/base/constant/site_type.go index 65b487c5d..5ddce116b 100644 --- a/internal/base/constant/site_type.go +++ b/internal/base/constant/site_type.go @@ -31,4 +31,7 @@ const ( SiteTypeTheme = "theme" SiteTypePrivileges = "privileges" SiteTypeUsers = "users" + SiteTypeAI = "ai" + SiteTypeFeatureToggle = "feature-toggle" + SiteTypeMCP = "mcp" ) diff --git a/internal/base/middleware/mcp_auth.go b/internal/base/middleware/mcp_auth.go new file mode 100644 index 000000000..6da056bae --- /dev/null +++ b/internal/base/middleware/mcp_auth.go @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package middleware + +import ( + "github.com/apache/answer/internal/base/handler" + "github.com/apache/answer/internal/base/reason" + "github.com/gin-gonic/gin" + "github.com/segmentfault/pacman/errors" + "github.com/segmentfault/pacman/log" +) + +// AuthMcpEnable check mcp is enabled +func (am *AuthUserMiddleware) AuthMcpEnable() gin.HandlerFunc { + return func(ctx *gin.Context) { + mcpConfig, err := am.siteInfoCommonService.GetSiteMCP(ctx) + if err != nil { + handler.HandleResponse(ctx, errors.InternalServer(reason.UnknownError), nil) + ctx.Abort() + return + } + if mcpConfig != nil && mcpConfig.Enabled { + ctx.Next() + return + } + handler.HandleResponse(ctx, errors.Forbidden(reason.ForbiddenError), nil) + ctx.Abort() + log.Error("abort mcp auth middleware, get mcp config error: ", err) + } +} diff --git a/internal/base/reason/reason.go b/internal/base/reason/reason.go index 97aaa75a9..b4c569a03 100644 --- a/internal/base/reason/reason.go +++ b/internal/base/reason/reason.go @@ -117,6 +117,7 @@ const ( UserStatusSuspendedForever = "error.user.status_suspended_forever" UserStatusSuspendedUntil = "error.user.status_suspended_until" UserStatusDeleted = "error.user.status_deleted" + ErrFeatureDisabled = "error.feature.disabled" ) // user external login reasons diff --git a/internal/base/translator/provider.go b/internal/base/translator/provider.go index 1a465b1e8..4f0059e36 100644 --- a/internal/base/translator/provider.go +++ b/internal/base/translator/provider.go @@ -242,16 +242,14 @@ func inspectTranslatorNode(node any, path []string, isRoot bool) error { return nil case []any: for idx, child := range data { - nextPath := append(path, fmt.Sprintf("[%d]", idx)) - if err := inspectTranslatorNode(child, nextPath, false); err != nil { + if err := inspectTranslatorNode(child, append(path, fmt.Sprintf("[%d]", idx)), false); err != nil { return err } } return nil case []map[string]any: for idx, child := range data { - nextPath := append(path, fmt.Sprintf("[%d]", idx)) - if err := inspectTranslatorNode(child, nextPath, false); err != nil { + if err := inspectTranslatorNode(child, append(path, fmt.Sprintf("[%d]", idx)), false); err != nil { return err } } diff --git a/internal/controller/ai_controller.go b/internal/controller/ai_controller.go new file mode 100644 index 000000000..aa7d2819b --- /dev/null +++ b/internal/controller/ai_controller.go @@ -0,0 +1,756 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package controller + +import ( + "context" + "encoding/json" + "fmt" + "maps" + "net/http" + "strings" + "time" + + "github.com/apache/answer/internal/base/constant" + "github.com/apache/answer/internal/base/handler" + "github.com/apache/answer/internal/base/middleware" + "github.com/apache/answer/internal/schema" + "github.com/apache/answer/internal/schema/mcp_tools" + "github.com/apache/answer/internal/service/ai_conversation" + answercommon "github.com/apache/answer/internal/service/answer_common" + "github.com/apache/answer/internal/service/comment" + "github.com/apache/answer/internal/service/content" + "github.com/apache/answer/internal/service/feature_toggle" + questioncommon "github.com/apache/answer/internal/service/question_common" + "github.com/apache/answer/internal/service/siteinfo_common" + tagcommonser "github.com/apache/answer/internal/service/tag_common" + usercommon "github.com/apache/answer/internal/service/user_common" + "github.com/apache/answer/pkg/token" + "github.com/gin-gonic/gin" + "github.com/mark3labs/mcp-go/mcp" + "github.com/sashabaranov/go-openai" + "github.com/segmentfault/pacman/errors" + "github.com/segmentfault/pacman/i18n" + "github.com/segmentfault/pacman/log" +) + +type AIController struct { + searchService *content.SearchService + siteInfoService siteinfo_common.SiteInfoCommonService + tagCommonService *tagcommonser.TagCommonService + questioncommon *questioncommon.QuestionCommon + commentRepo comment.CommentRepo + userCommon *usercommon.UserCommon + answerRepo answercommon.AnswerRepo + mcpController *MCPController + aiConversationService ai_conversation.AIConversationService + featureToggleSvc *feature_toggle.FeatureToggleService +} + +// NewAIController new site info controller. +func NewAIController( + searchService *content.SearchService, + siteInfoService siteinfo_common.SiteInfoCommonService, + tagCommonService *tagcommonser.TagCommonService, + questioncommon *questioncommon.QuestionCommon, + commentRepo comment.CommentRepo, + userCommon *usercommon.UserCommon, + answerRepo answercommon.AnswerRepo, + mcpController *MCPController, + aiConversationService ai_conversation.AIConversationService, + featureToggleSvc *feature_toggle.FeatureToggleService, +) *AIController { + return &AIController{ + searchService: searchService, + siteInfoService: siteInfoService, + tagCommonService: tagCommonService, + questioncommon: questioncommon, + commentRepo: commentRepo, + userCommon: userCommon, + answerRepo: answerRepo, + mcpController: mcpController, + aiConversationService: aiConversationService, + featureToggleSvc: featureToggleSvc, + } +} + +func (c *AIController) ensureAIChatEnabled(ctx *gin.Context) bool { + if c.featureToggleSvc == nil { + return true + } + if err := c.featureToggleSvc.EnsureEnabled(ctx, feature_toggle.FeatureAIChatbot); err != nil { + handler.HandleResponse(ctx, err, nil) + return false + } + return true +} + +type ChatCompletionsRequest struct { + Messages []Message `validate:"required,gte=1" json:"messages"` + ConversationID string `json:"conversation_id"` + UserID string `json:"-"` +} + +type Message struct { + Role string `json:"role" binding:"required"` + Content string `json:"content" binding:"required"` +} + +type ChatCompletionsResponse struct { + ID string `json:"id"` + Object string `json:"object"` + Created int64 `json:"created"` + Model string `json:"model"` + Choices []Choice `json:"choices"` + Usage Usage `json:"usage"` +} + +type StreamResponse struct { + ChatCompletionID string `json:"chat_completion_id"` + Object string `json:"object"` + Created int64 `json:"created"` + Model string `json:"model"` + Choices []StreamChoice `json:"choices"` +} + +type Choice struct { + Index int `json:"index"` + Message Message `json:"message"` + FinishReason string `json:"finish_reason"` +} + +type StreamChoice struct { + Index int `json:"index"` + Delta Delta `json:"delta"` + FinishReason *string `json:"finish_reason"` +} + +type Delta struct { + Role string `json:"role,omitempty"` + Content string `json:"content,omitempty"` +} + +type Usage struct { + PromptTokens int `json:"prompt_tokens"` + CompletionTokens int `json:"completion_tokens"` + TotalTokens int `json:"total_tokens"` +} + +type ConversationContext struct { + ConversationID string + UserID string + UserQuestion string + Messages []*ai_conversation.ConversationMessage + IsNewConversation bool + Model string +} + +func (c *ConversationContext) GetOpenAIMessages() []openai.ChatCompletionMessage { + messages := make([]openai.ChatCompletionMessage, len(c.Messages)) + for i, msg := range c.Messages { + messages[i] = openai.ChatCompletionMessage{ + Role: msg.Role, + Content: msg.Content, + } + } + return messages +} + +// sendStreamData +func sendStreamData(w http.ResponseWriter, data StreamResponse) { + jsonData, err := json.Marshal(data) + if err != nil { + return + } + + _, _ = fmt.Fprintf(w, "data: %s\n\n", string(jsonData)) + if f, ok := w.(http.Flusher); ok { + f.Flush() + } +} + +func (c *AIController) ChatCompletions(ctx *gin.Context) { + if !c.ensureAIChatEnabled(ctx) { + return + } + aiConfig, err := c.siteInfoService.GetSiteAI(context.Background()) + if err != nil { + log.Errorf("Failed to get AI config: %v", err) + handler.HandleResponse(ctx, errors.BadRequest("AI service configuration error"), nil) + return + } + + if !aiConfig.Enabled { + handler.HandleResponse(ctx, errors.ServiceUnavailable("AI service is not enabled"), nil) + return + } + + aiProvider := aiConfig.GetProvider() + + req := &ChatCompletionsRequest{} + if handler.BindAndCheck(ctx, req) { + return + } + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + data, _ := json.Marshal(req) + log.Infof("ai chat request data: %s", string(data)) + + ctx.Header("Content-Type", "text/event-stream") + ctx.Header("Cache-Control", "no-cache") + ctx.Header("Connection", "keep-alive") + ctx.Header("Access-Control-Allow-Origin", "*") + ctx.Header("Access-Control-Allow-Headers", "Cache-Control") + + ctx.Status(http.StatusOK) + + w := ctx.Writer + + if f, ok := w.(http.Flusher); ok { + f.Flush() + } + + chatcmplID := "chatcmpl-" + token.GenerateToken() + created := time.Now().Unix() + + firstResponse := StreamResponse{ + ChatCompletionID: chatcmplID, + Object: "chat.completion.chunk", + Created: time.Now().Unix(), + Model: aiProvider.Model, + Choices: []StreamChoice{{Index: 0, Delta: Delta{Role: "assistant"}, FinishReason: nil}}, + } + + sendStreamData(w, firstResponse) + + conversationCtx := c.initializeConversationContext(ctx, aiProvider.Model, req) + if conversationCtx == nil { + log.Error("Failed to initialize conversation context") + c.sendErrorResponse(w, chatcmplID, aiProvider.Model, "Failed to initialize conversation context") + return + } + + c.redirectRequestToAI(ctx, w, chatcmplID, conversationCtx) + + finishReason := "stop" + endResponse := StreamResponse{ + ChatCompletionID: chatcmplID, + Object: "chat.completion.chunk", + Created: created, + Model: aiProvider.Model, + Choices: []StreamChoice{{Index: 0, Delta: Delta{}, FinishReason: &finishReason}}, + } + + sendStreamData(w, endResponse) + + _, _ = fmt.Fprintf(w, "data: [DONE]\n\n") + if f, ok := w.(http.Flusher); ok { + f.Flush() + } + + c.saveConversationRecord(ctx, chatcmplID, conversationCtx) +} + +func (c *AIController) redirectRequestToAI(ctx *gin.Context, w http.ResponseWriter, id string, conversationCtx *ConversationContext) { + client := c.createOpenAIClient() + + c.handleAIConversation(ctx, w, id, client, conversationCtx) +} + +// createOpenAIClient +func (c *AIController) createOpenAIClient() *openai.Client { + config := openai.DefaultConfig("") + config.BaseURL = "" + + aiConfig, err := c.siteInfoService.GetSiteAI(context.Background()) + if err != nil { + log.Errorf("Failed to get AI config: %v", err) + return openai.NewClientWithConfig(config) + } + + if !aiConfig.Enabled { + log.Warn("AI feature is disabled") + return openai.NewClientWithConfig(config) + } + + aiProvider := aiConfig.GetProvider() + + config = openai.DefaultConfig(aiProvider.APIKey) + config.BaseURL = aiProvider.APIHost + if !strings.HasSuffix(config.BaseURL, "/v1") { + config.BaseURL += "/v1" + } + return openai.NewClientWithConfig(config) +} + +// getPromptByLanguage +func (c *AIController) getPromptByLanguage(language i18n.Language, question string) string { + aiConfig, err := c.siteInfoService.GetSiteAI(context.Background()) + if err != nil { + log.Errorf("Failed to get AI config: %v", err) + return c.getDefaultPrompt(language, question) + } + + var promptTemplate string + + switch language { + case i18n.LanguageChinese: + promptTemplate = aiConfig.PromptConfig.ZhCN + case i18n.LanguageEnglish: + promptTemplate = aiConfig.PromptConfig.EnUS + default: + promptTemplate = aiConfig.PromptConfig.EnUS + } + + if promptTemplate == "" { + return c.getDefaultPrompt(language, question) + } + + return fmt.Sprintf(promptTemplate, question) +} + +// getDefaultPrompt prompt +func (c *AIController) getDefaultPrompt(language i18n.Language, question string) string { + switch language { + case i18n.LanguageChinese: + return fmt.Sprintf(constant.DefaultAIPromptConfigZhCN, question) + case i18n.LanguageEnglish: + return fmt.Sprintf(constant.DefaultAIPromptConfigEnUS, question) + default: + return fmt.Sprintf(constant.DefaultAIPromptConfigEnUS, question) + } +} + +// initializeConversationContext +func (c *AIController) initializeConversationContext(ctx *gin.Context, model string, req *ChatCompletionsRequest) *ConversationContext { + if len(req.ConversationID) == 0 { + req.ConversationID = token.GenerateToken() + } + conversationCtx := &ConversationContext{ + UserID: req.UserID, + Messages: make([]*ai_conversation.ConversationMessage, 0), + ConversationID: req.ConversationID, + Model: model, + } + + conversationDetail, exist, err := c.aiConversationService.GetConversationDetail(ctx, &schema.AIConversationDetailReq{ + ConversationID: req.ConversationID, + UserID: req.UserID, + }) + if err != nil { + log.Errorf("Failed to get conversation detail: %v", err) + return nil + } + if !exist { + conversationCtx.UserQuestion = req.Messages[0].Content + conversationCtx.Messages = c.buildInitialMessages(ctx, req) + conversationCtx.IsNewConversation = true + return conversationCtx + } + conversationCtx.IsNewConversation = false + + for _, record := range conversationDetail.Records { + conversationCtx.Messages = append(conversationCtx.Messages, &ai_conversation.ConversationMessage{ + ChatCompletionID: record.ChatCompletionID, + Role: record.Role, + Content: record.Content, + }) + } + conversationCtx.Messages = append(conversationCtx.Messages, &ai_conversation.ConversationMessage{ + Role: req.Messages[0].Role, + Content: req.Messages[0].Content, + }) + return conversationCtx +} + +// buildInitialMessages +func (c *AIController) buildInitialMessages(ctx *gin.Context, req *ChatCompletionsRequest) []*ai_conversation.ConversationMessage { + question := "" + if len(req.Messages) == 1 { + question = req.Messages[0].Content + } else { + messages := make([]*ai_conversation.ConversationMessage, len(req.Messages)) + for i, msg := range req.Messages { + messages[i] = &ai_conversation.ConversationMessage{ + Role: msg.Role, + Content: msg.Content, + } + } + return messages + } + + currentLang := handler.GetLangByCtx(ctx) + + prompt := c.getPromptByLanguage(currentLang, question) + + return []*ai_conversation.ConversationMessage{{Role: openai.ChatMessageRoleUser, Content: prompt}} +} + +// saveConversationRecord +func (c *AIController) saveConversationRecord(ctx context.Context, chatcmplID string, conversationCtx *ConversationContext) { + if conversationCtx == nil || len(conversationCtx.Messages) == 0 { + return + } + + if conversationCtx.IsNewConversation { + topic := conversationCtx.UserQuestion + if topic == "" { + log.Warn("No user message found for new conversation") + return + } + + err := c.aiConversationService.CreateConversation(ctx, conversationCtx.UserID, conversationCtx.ConversationID, topic) + if err != nil { + log.Errorf("Failed to create conversation: %v", err) + return + } + } + + err := c.aiConversationService.SaveConversationRecords(ctx, conversationCtx.ConversationID, chatcmplID, conversationCtx.Messages) + if err != nil { + log.Errorf("Failed to save conversation records: %v", err) + } +} + +func (c *AIController) handleAIConversation(ctx *gin.Context, w http.ResponseWriter, id string, client *openai.Client, conversationCtx *ConversationContext) { + maxRounds := 10 + messages := conversationCtx.GetOpenAIMessages() + + for round := 0; round < maxRounds; round++ { + log.Debugf("AI conversation round: %d", round+1) + + aiReq := openai.ChatCompletionRequest{ + Model: conversationCtx.Model, + Messages: messages, + Tools: c.getMCPTools(), + Stream: true, + } + + toolCalls, newMessages, finished, aiResponse := c.processAIStream(ctx, w, id, conversationCtx.Model, client, aiReq, messages) + messages = newMessages + + if aiResponse != "" { + conversationCtx.Messages = append(conversationCtx.Messages, &ai_conversation.ConversationMessage{ + Role: "assistant", + Content: aiResponse, + }) + } + + if finished { + return + } + + if len(toolCalls) > 0 { + messages = c.executeToolCalls(ctx, w, id, conversationCtx.Model, toolCalls, messages) + } else { + return + } + } + + log.Warnf("AI conversation reached maximum rounds limit: %d", maxRounds) +} + +// processAIStream +func (c *AIController) processAIStream( + _ *gin.Context, w http.ResponseWriter, id, model string, client *openai.Client, aiReq openai.ChatCompletionRequest, messages []openai.ChatCompletionMessage) ( + []openai.ToolCall, []openai.ChatCompletionMessage, bool, string) { + stream, err := client.CreateChatCompletionStream(context.Background(), aiReq) + if err != nil { + log.Errorf("Failed to create stream: %v", err) + c.sendErrorResponse(w, id, model, "Failed to create AI stream") + return nil, messages, true, "" + } + defer func() { + _ = stream.Close() + }() + + var currentToolCalls []openai.ToolCall + var accumulatedContent strings.Builder + var accumulatedMessage openai.ChatCompletionMessage + toolCallsMap := make(map[int]*openai.ToolCall) + + for { + response, err := stream.Recv() + if err != nil { + if err.Error() == "EOF" { + log.Info("Stream finished") + break + } + log.Errorf("Stream error: %v", err) + break + } + + choice := response.Choices[0] + + if len(choice.Delta.ToolCalls) > 0 { + for _, deltaToolCall := range choice.Delta.ToolCalls { + index := *deltaToolCall.Index + + if _, exists := toolCallsMap[index]; !exists { + toolCallsMap[index] = &openai.ToolCall{ + ID: deltaToolCall.ID, + Type: deltaToolCall.Type, + Function: openai.FunctionCall{ + Name: deltaToolCall.Function.Name, + Arguments: deltaToolCall.Function.Arguments, + }, + } + } else { + if deltaToolCall.Function.Arguments != "" { + toolCallsMap[index].Function.Arguments += deltaToolCall.Function.Arguments + } + if deltaToolCall.Function.Name != "" { + toolCallsMap[index].Function.Name = deltaToolCall.Function.Name + } + } + } + } + + if choice.Delta.Content != "" { + accumulatedContent.WriteString(choice.Delta.Content) + + contentResponse := StreamResponse{ + ChatCompletionID: id, + Object: "chat.completion.chunk", + Created: time.Now().Unix(), + Model: model, + Choices: []StreamChoice{ + { + Index: 0, + Delta: Delta{ + Content: choice.Delta.Content, + }, + FinishReason: nil, + }, + }, + } + sendStreamData(w, contentResponse) + } + + if len(choice.FinishReason) > 0 { + if choice.FinishReason == "tool_calls" { + for _, toolCall := range toolCallsMap { + currentToolCalls = append(currentToolCalls, *toolCall) + } + return currentToolCalls, messages, false, accumulatedContent.String() + } else { + aiResponseContent := accumulatedContent.String() + if aiResponseContent != "" { + accumulatedMessage = openai.ChatCompletionMessage{ + Role: openai.ChatMessageRoleAssistant, + Content: aiResponseContent, + } + messages = append(messages, accumulatedMessage) + } + return nil, messages, true, aiResponseContent + } + } + } + + aiResponseContent := accumulatedContent.String() + if aiResponseContent != "" { + accumulatedMessage = openai.ChatCompletionMessage{ + Role: openai.ChatMessageRoleAssistant, + Content: aiResponseContent, + } + messages = append(messages, accumulatedMessage) + } + + if len(toolCallsMap) > 0 { + for _, toolCall := range toolCallsMap { + currentToolCalls = append(currentToolCalls, *toolCall) + } + return currentToolCalls, messages, false, aiResponseContent + } + + return currentToolCalls, messages, len(currentToolCalls) == 0, aiResponseContent +} + +// executeToolCalls +func (c *AIController) executeToolCalls(ctx *gin.Context, _ http.ResponseWriter, _, _ string, toolCalls []openai.ToolCall, messages []openai.ChatCompletionMessage) []openai.ChatCompletionMessage { + validToolCalls := make([]openai.ToolCall, 0) + for _, toolCall := range toolCalls { + if toolCall.ID == "" || toolCall.Function.Name == "" { + log.Errorf("Invalid tool call: missing required fields. ID: %s, Function: %v", toolCall.ID, toolCall.Function) + continue + } + + if toolCall.Function.Arguments == "" { + toolCall.Function.Arguments = "{}" + } + + validToolCalls = append(validToolCalls, toolCall) + log.Debugf("Valid tool call: ID=%s, Name=%s, Arguments=%s", toolCall.ID, toolCall.Function.Name, toolCall.Function.Arguments) + } + + if len(validToolCalls) == 0 { + log.Warn("No valid tool calls found") + return messages + } + + assistantMsg := openai.ChatCompletionMessage{ + Role: openai.ChatMessageRoleAssistant, + ToolCalls: validToolCalls, + } + messages = append(messages, assistantMsg) + + for _, toolCall := range validToolCalls { + if toolCall.Function.Name != "" { + var args map[string]interface{} + if err := json.Unmarshal([]byte(toolCall.Function.Arguments), &args); err != nil { + log.Errorf("Failed to parse tool arguments for %s: %v, arguments: %s", toolCall.Function.Name, err, toolCall.Function.Arguments) + errorResult := fmt.Sprintf("Error parsing tool arguments: %v", err) + toolMessage := openai.ChatCompletionMessage{ + Role: openai.ChatMessageRoleTool, + Content: errorResult, + ToolCallID: toolCall.ID, + } + messages = append(messages, toolMessage) + continue + } + + result, err := c.callMCPTool(ctx, toolCall.Function.Name, args) + if err != nil { + log.Errorf("Failed to call MCP tool %s: %v", toolCall.Function.Name, err) + result = fmt.Sprintf("Error calling tool %s: %v", toolCall.Function.Name, err) + } + + toolMessage := openai.ChatCompletionMessage{ + Role: openai.ChatMessageRoleTool, + Content: result, + ToolCallID: toolCall.ID, + } + messages = append(messages, toolMessage) + } + } + + return messages +} + +// sendErrorResponse send error response in stream +func (c *AIController) sendErrorResponse(w http.ResponseWriter, id, model, errorMsg string) { + errorResponse := StreamResponse{ + ChatCompletionID: id, + Object: "chat.completion.chunk", + Created: time.Now().Unix(), + Model: model, + Choices: []StreamChoice{ + { + Index: 0, + Delta: Delta{ + Content: fmt.Sprintf("Error: %s", errorMsg), + }, + FinishReason: nil, + }, + }, + } + sendStreamData(w, errorResponse) +} + +// getMCPTools +func (c *AIController) getMCPTools() []openai.Tool { + openaiTools := make([]openai.Tool, 0) + for _, mcpTool := range mcp_tools.MCPToolsList { + openaiTool := c.convertMCPToolToOpenAI(mcpTool) + openaiTools = append(openaiTools, openaiTool) + } + + return openaiTools +} + +// convertMCPToolToOpenAI +func (c *AIController) convertMCPToolToOpenAI(mcpTool mcp.Tool) openai.Tool { + properties := make(map[string]interface{}) + required := make([]string, 0) + + maps.Copy(properties, mcpTool.InputSchema.Properties) + + required = append(required, mcpTool.InputSchema.Required...) + + parameters := map[string]interface{}{ + "type": "object", + "properties": properties, + } + + if len(required) > 0 { + parameters["required"] = required + } + + return openai.Tool{ + Type: openai.ToolTypeFunction, + Function: &openai.FunctionDefinition{ + Name: mcpTool.Name, + Description: mcpTool.Description, + Parameters: parameters, + }, + } +} + +// callMCPTool +func (c *AIController) callMCPTool(ctx context.Context, toolName string, arguments map[string]interface{}) (string, error) { + request := mcp.CallToolRequest{ + Request: mcp.Request{}, + Params: struct { + Name string `json:"name"` + Arguments any `json:"arguments,omitempty"` + Meta *mcp.Meta `json:"_meta,omitempty"` + }{ + Name: toolName, + Arguments: arguments, + }, + } + + var result *mcp.CallToolResult + var err error + + log.Debugf("Calling MCP tool: %s with arguments: %v", toolName, arguments) + + switch toolName { + case "get_questions": + result, err = c.mcpController.MCPQuestionsHandler()(ctx, request) + case "get_answers_by_question_id": + result, err = c.mcpController.MCPAnswersHandler()(ctx, request) + case "get_comments": + result, err = c.mcpController.MCPCommentsHandler()(ctx, request) + case "get_tags": + result, err = c.mcpController.MCPTagsHandler()(ctx, request) + case "get_tag_detail": + result, err = c.mcpController.MCPTagDetailsHandler()(ctx, request) + case "get_user": + result, err = c.mcpController.MCPUserDetailsHandler()(ctx, request) + default: + return "", fmt.Errorf("unknown tool: %s", toolName) + } + + if err != nil { + return "", err + } + + data, _ := json.Marshal(result) + log.Debugf("MCP tool %s called successfully, result: %v", toolName, string(data)) + + if result != nil && len(result.Content) > 0 { + if textContent, ok := result.Content[0].(mcp.TextContent); ok { + return textContent.Text, nil + } + } + + return "No result found", nil +} diff --git a/internal/controller/ai_conversation_controller.go b/internal/controller/ai_conversation_controller.go new file mode 100644 index 000000000..1b8debd78 --- /dev/null +++ b/internal/controller/ai_conversation_controller.go @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package controller + +import ( + "github.com/apache/answer/internal/base/handler" + "github.com/apache/answer/internal/base/middleware" + "github.com/apache/answer/internal/schema" + "github.com/apache/answer/internal/service/ai_conversation" + "github.com/apache/answer/internal/service/feature_toggle" + "github.com/gin-gonic/gin" +) + +// AIConversationController ai conversation controller +type AIConversationController struct { + aiConversationService ai_conversation.AIConversationService + featureToggleSvc *feature_toggle.FeatureToggleService +} + +// NewAIConversationController creates a new AI conversation controller +func NewAIConversationController( + aiConversationService ai_conversation.AIConversationService, + featureToggleSvc *feature_toggle.FeatureToggleService, +) *AIConversationController { + return &AIConversationController{ + aiConversationService: aiConversationService, + featureToggleSvc: featureToggleSvc, + } +} + +func (ctrl *AIConversationController) ensureEnabled(ctx *gin.Context) bool { + if ctrl.featureToggleSvc == nil { + return true + } + if err := ctrl.featureToggleSvc.EnsureEnabled(ctx, feature_toggle.FeatureAIChatbot); err != nil { + handler.HandleResponse(ctx, err, nil) + return false + } + return true +} + +// GetConversationList gets conversation list +// @Summary get conversation list +// @Description get conversation list +// @Tags ai-conversation +// @Accept json +// @Produce json +// @Param page query int false "page" +// @Param page_size query int false "page size" +// @Success 200 {object} handler.RespBody{data=pager.PageModel{list=[]schema.AIConversationListItem}} +// @Router /answer/api/v1/ai/conversation/page [get] +func (ctrl *AIConversationController) GetConversationList(ctx *gin.Context) { + if !ctrl.ensureEnabled(ctx) { + return + } + req := &schema.AIConversationListReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + resp, err := ctrl.aiConversationService.GetConversationList(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// GetConversationDetail gets conversation detail +// @Summary get conversation detail +// @Description get conversation detail +// @Tags ai-conversation +// @Accept json +// @Produce json +// @Param conversation_id query string true "conversation id" +// @Success 200 {object} handler.RespBody{data=schema.AIConversationDetailResp} +// @Router /answer/api/v1/ai/conversation [get] +func (ctrl *AIConversationController) GetConversationDetail(ctx *gin.Context) { + if !ctrl.ensureEnabled(ctx) { + return + } + req := &schema.AIConversationDetailReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + resp, _, err := ctrl.aiConversationService.GetConversationDetail(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// VoteRecord vote record +// @Summary vote record +// @Description vote record +// @Tags ai-conversation +// @Accept json +// @Produce json +// @Param data body schema.AIConversationVoteReq true "vote request" +// @Success 200 {object} handler.RespBody +// @Router /answer/api/v1/ai/conversation/vote [post] +func (ctrl *AIConversationController) VoteRecord(ctx *gin.Context) { + if !ctrl.ensureEnabled(ctx) { + return + } + req := &schema.AIConversationVoteReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + err := ctrl.aiConversationService.VoteRecord(ctx, req) + handler.HandleResponse(ctx, err, nil) +} diff --git a/internal/controller/controller.go b/internal/controller/controller.go index b5c3f91c4..c31763bea 100644 --- a/internal/controller/controller.go +++ b/internal/controller/controller.go @@ -54,4 +54,7 @@ var ProviderSetController = wire.NewSet( NewBadgeController, NewRenderController, NewSidebarController, + NewMCPController, + NewAIController, + NewAIConversationController, ) diff --git a/internal/controller/mcp_controller.go b/internal/controller/mcp_controller.go new file mode 100644 index 000000000..d52f57979 --- /dev/null +++ b/internal/controller/mcp_controller.go @@ -0,0 +1,351 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package controller + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + "github.com/apache/answer/internal/base/pager" + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/schema" + answercommon "github.com/apache/answer/internal/service/answer_common" + "github.com/apache/answer/internal/service/comment" + "github.com/apache/answer/internal/service/content" + "github.com/apache/answer/internal/service/feature_toggle" + questioncommon "github.com/apache/answer/internal/service/question_common" + "github.com/apache/answer/internal/service/siteinfo_common" + tagcommonser "github.com/apache/answer/internal/service/tag_common" + usercommon "github.com/apache/answer/internal/service/user_common" + "github.com/mark3labs/mcp-go/mcp" + "github.com/segmentfault/pacman/log" +) + +type MCPController struct { + searchService *content.SearchService + siteInfoService siteinfo_common.SiteInfoCommonService + tagCommonService *tagcommonser.TagCommonService + questioncommon *questioncommon.QuestionCommon + commentRepo comment.CommentRepo + userCommon *usercommon.UserCommon + answerRepo answercommon.AnswerRepo + featureToggleSvc *feature_toggle.FeatureToggleService +} + +// NewMCPController new site info controller. +func NewMCPController( + searchService *content.SearchService, + siteInfoService siteinfo_common.SiteInfoCommonService, + tagCommonService *tagcommonser.TagCommonService, + questioncommon *questioncommon.QuestionCommon, + commentRepo comment.CommentRepo, + userCommon *usercommon.UserCommon, + answerRepo answercommon.AnswerRepo, + featureToggleSvc *feature_toggle.FeatureToggleService, +) *MCPController { + return &MCPController{ + searchService: searchService, + siteInfoService: siteInfoService, + tagCommonService: tagCommonService, + questioncommon: questioncommon, + commentRepo: commentRepo, + userCommon: userCommon, + answerRepo: answerRepo, + featureToggleSvc: featureToggleSvc, + } +} + +func (c *MCPController) ensureMCPEnabled(ctx context.Context) error { + if c.featureToggleSvc == nil { + return nil + } + return c.featureToggleSvc.EnsureEnabled(ctx, feature_toggle.FeatureMCP) +} + +func (c *MCPController) MCPQuestionsHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchCond(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + searchResp, err := c.searchService.Search(ctx, &schema.SearchDTO{ + Query: cond.ToQueryString() + " is:question", + Page: 1, + Size: 5, + Order: "newest", + }) + if err != nil { + return nil, err + } + + resp := make([]*schema.MCPSearchQuestionInfoResp, 0) + for _, question := range searchResp.SearchResults { + t := &schema.MCPSearchQuestionInfoResp{ + QuestionID: question.Object.QuestionID, + Title: question.Object.Title, + Content: question.Object.Excerpt, + Link: fmt.Sprintf("%s/questions/%s", siteGeneral.SiteUrl, question.Object.QuestionID), + } + resp = append(resp, t) + } + + data, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(data)), nil + } +} + +func (c *MCPController) MCPQuestionDetailHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchQuestionDetail(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + question, err := c.questioncommon.Info(ctx, cond.QuestionID, "") + if err != nil { + log.Errorf("get question failed: %v", err) + return mcp.NewToolResultText("No question found."), nil + } + + resp := &schema.MCPSearchQuestionInfoResp{ + QuestionID: question.ID, + Title: question.Title, + Content: question.Content, + Link: fmt.Sprintf("%s/questions/%s", siteGeneral.SiteUrl, question.ID), + } + res, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(res)), nil + } +} + +func (c *MCPController) MCPAnswersHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchAnswerCond(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + if len(cond.QuestionID) > 0 { + answerList, err := c.answerRepo.GetAnswerList(ctx, &entity.Answer{QuestionID: cond.QuestionID}) + if err != nil { + log.Errorf("get answers failed: %v", err) + return nil, err + } + resp := make([]*schema.MCPSearchAnswerInfoResp, 0) + for _, answer := range answerList { + t := &schema.MCPSearchAnswerInfoResp{ + QuestionID: answer.QuestionID, + AnswerID: answer.ID, + AnswerContent: answer.OriginalText, + Link: fmt.Sprintf("%s/questions/%s/answers/%s", siteGeneral.SiteUrl, answer.QuestionID, answer.ID), + } + resp = append(resp, t) + } + data, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(data)), nil + } + + answerList, err := c.answerRepo.GetAnswerList(ctx, &entity.Answer{QuestionID: cond.QuestionID}) + if err != nil { + log.Errorf("get answers failed: %v", err) + return nil, err + } + resp := make([]*schema.MCPSearchAnswerInfoResp, 0) + for _, answer := range answerList { + t := &schema.MCPSearchAnswerInfoResp{ + QuestionID: answer.QuestionID, + AnswerID: answer.ID, + AnswerContent: answer.OriginalText, + Link: fmt.Sprintf("%s/questions/%s/answers/%s", siteGeneral.SiteUrl, answer.QuestionID, answer.ID), + } + resp = append(resp, t) + } + data, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(data)), nil + } +} + +func (c *MCPController) MCPCommentsHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchCommentCond(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + dto := &comment.CommentQuery{ + PageCond: pager.PageCond{Page: 1, PageSize: 5}, + QueryCond: "newest", + ObjectID: cond.ObjectID, + } + commentList, total, err := c.commentRepo.GetCommentPage(ctx, dto) + if err != nil { + return nil, err + } + if total == 0 { + return mcp.NewToolResultText("No comments found."), nil + } + + resp := make([]*schema.MCPSearchCommentInfoResp, 0) + for _, comment := range commentList { + t := &schema.MCPSearchCommentInfoResp{ + CommentID: comment.ID, + Content: comment.OriginalText, + ObjectID: comment.ObjectID, + Link: fmt.Sprintf("%s/comments/%s", siteGeneral.SiteUrl, comment.ID), + } + resp = append(resp, t) + } + data, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(data)), nil + } +} + +func (c *MCPController) MCPTagsHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchTagCond(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + tags, total, err := c.tagCommonService.GetTagPage(ctx, 1, 10, &entity.Tag{DisplayName: cond.TagName}, "newest") + if err != nil { + log.Errorf("get tags failed: %v", err) + return nil, err + } + + if total == 0 { + res := strings.Builder{} + res.WriteString("No tags found.\n") + return mcp.NewToolResultText(res.String()), nil + } + + resp := make([]*schema.MCPSearchTagResp, 0) + for _, tag := range tags { + t := &schema.MCPSearchTagResp{ + TagName: tag.SlugName, + DisplayName: tag.DisplayName, + Description: tag.OriginalText, + Link: fmt.Sprintf("%s/tags/%s", siteGeneral.SiteUrl, tag.SlugName), + } + resp = append(resp, t) + } + data, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(data)), nil + } +} + +func (c *MCPController) MCPTagDetailsHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchTagCond(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + tag, exist, err := c.tagCommonService.GetTagBySlugName(ctx, cond.TagName) + if err != nil { + log.Errorf("get tag failed: %v", err) + return nil, err + } + if !exist { + return mcp.NewToolResultText("Tag not found."), nil + } + + resp := &schema.MCPSearchTagResp{ + TagName: tag.SlugName, + DisplayName: tag.DisplayName, + Description: tag.OriginalText, + Link: fmt.Sprintf("%s/tags/%s", siteGeneral.SiteUrl, tag.SlugName), + } + res, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(res)), nil + } +} + +func (c *MCPController) MCPUserDetailsHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchUserCond(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + user, exist, err := c.userCommon.GetUserBasicInfoByUserName(ctx, cond.Username) + if err != nil { + log.Errorf("get user failed: %v", err) + return nil, err + } + if !exist { + return mcp.NewToolResultText("User not found."), nil + } + + resp := &schema.MCPSearchUserInfoResp{ + Username: user.Username, + DisplayName: user.DisplayName, + Avatar: user.Avatar, + Link: fmt.Sprintf("%s/users/%s", siteGeneral.SiteUrl, user.Username), + } + res, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(res)), nil + } +} diff --git a/internal/controller/siteinfo_controller.go b/internal/controller/siteinfo_controller.go index a336fb242..c650b9c67 100644 --- a/internal/controller/siteinfo_controller.go +++ b/internal/controller/siteinfo_controller.go @@ -94,6 +94,13 @@ func (sc *SiteInfoController) GetSiteInfo(ctx *gin.Context) { if legal, err := sc.siteInfoService.GetSiteLegal(ctx); err == nil { resp.Legal = &schema.SiteLegalSimpleResp{ExternalContentDisplay: legal.ExternalContentDisplay} } + if aiConf, err := sc.siteInfoService.GetSiteAI(ctx); err == nil { + resp.AIEnabled = aiConf.Enabled + } + + if mcpConf, err := sc.siteInfoService.GetSiteMCP(ctx); err == nil { + resp.MCPEnabled = mcpConf.Enabled + } handler.HandleResponse(ctx, nil, resp) } diff --git a/internal/controller_admin/ai_conversation_admin_controller.go b/internal/controller_admin/ai_conversation_admin_controller.go new file mode 100644 index 000000000..5802a7a8d --- /dev/null +++ b/internal/controller_admin/ai_conversation_admin_controller.go @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package controller_admin + +import ( + "github.com/apache/answer/internal/base/handler" + "github.com/apache/answer/internal/schema" + "github.com/apache/answer/internal/service/ai_conversation" + "github.com/apache/answer/internal/service/feature_toggle" + "github.com/gin-gonic/gin" +) + +// AIConversationAdminController ai conversation admin controller +type AIConversationAdminController struct { + aiConversationService ai_conversation.AIConversationService + featureToggleSvc *feature_toggle.FeatureToggleService +} + +// NewAIConversationAdminController new AI conversation admin controller +func NewAIConversationAdminController( + aiConversationService ai_conversation.AIConversationService, + featureToggleSvc *feature_toggle.FeatureToggleService, +) *AIConversationAdminController { + return &AIConversationAdminController{ + aiConversationService: aiConversationService, + featureToggleSvc: featureToggleSvc, + } +} + +func (ctrl *AIConversationAdminController) ensureEnabled(ctx *gin.Context) bool { + if ctrl.featureToggleSvc == nil { + return true + } + if err := ctrl.featureToggleSvc.EnsureEnabled(ctx, feature_toggle.FeatureAIChatbot); err != nil { + handler.HandleResponse(ctx, err, nil) + return false + } + return true +} + +// GetConversationList gets conversation list +// @Summary get conversation list for admin +// @Description get conversation list for admin +// @Tags ai-conversation-admin +// @Accept json +// @Produce json +// @Param page query int false "page" +// @Param page_size query int false "page size" +// @Success 200 {object} handler.RespBody{data=pager.PageModel{list=[]schema.AIConversationAdminListItem}} +// @Router /answer/admin/api/ai/conversation/page [get] +func (ctrl *AIConversationAdminController) GetConversationList(ctx *gin.Context) { + if !ctrl.ensureEnabled(ctx) { + return + } + req := &schema.AIConversationAdminListReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + resp, err := ctrl.aiConversationService.GetConversationListForAdmin(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// GetConversationDetail get conversation detail +// @Summary get conversation detail for admin +// @Description get conversation detail for admin +// @Tags ai-conversation-admin +// @Accept json +// @Produce json +// @Param conversation_id query string true "conversation id" +// @Success 200 {object} handler.RespBody{data=schema.AIConversationAdminDetailResp} +// @Router /answer/admin/api/ai/conversation [get] +func (ctrl *AIConversationAdminController) GetConversationDetail(ctx *gin.Context) { + if !ctrl.ensureEnabled(ctx) { + return + } + req := &schema.AIConversationAdminDetailReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + resp, err := ctrl.aiConversationService.GetConversationDetailForAdmin(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// DeleteConversation delete conversation +// @Summary delete conversation for admin +// @Description delete conversation and its related records for admin +// @Tags ai-conversation-admin +// @Accept json +// @Produce json +// @Param data body schema.AIConversationAdminDeleteReq true "apikey" +// @Success 200 {object} handler.RespBody +// @Router /answer/admin/api/ai/conversation [delete] +func (ctrl *AIConversationAdminController) DeleteConversation(ctx *gin.Context) { + if !ctrl.ensureEnabled(ctx) { + return + } + req := &schema.AIConversationAdminDeleteReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + err := ctrl.aiConversationService.DeleteConversationForAdmin(ctx, req) + handler.HandleResponse(ctx, err, nil) +} diff --git a/internal/controller_admin/controller.go b/internal/controller_admin/controller.go index ebf32cbfc..de0c7ec88 100644 --- a/internal/controller_admin/controller.go +++ b/internal/controller_admin/controller.go @@ -29,4 +29,6 @@ var ProviderSetController = wire.NewSet( NewRoleController, NewPluginController, NewBadgeController, + NewAdminAPIKeyController, + NewAIConversationAdminController, ) diff --git a/internal/controller_admin/e_api_key_controller.go b/internal/controller_admin/e_api_key_controller.go new file mode 100644 index 000000000..1b32b5350 --- /dev/null +++ b/internal/controller_admin/e_api_key_controller.go @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package controller_admin + +import ( + "github.com/apache/answer/internal/base/handler" + "github.com/apache/answer/internal/base/middleware" + "github.com/apache/answer/internal/schema" + "github.com/apache/answer/internal/service/apikey" + "github.com/gin-gonic/gin" +) + +// AdminAPIKeyController site info controller +type AdminAPIKeyController struct { + apiKeyService *apikey.APIKeyService +} + +// NewAdminAPIKeyController new site info controller +func NewAdminAPIKeyController(apiKeyService *apikey.APIKeyService) *AdminAPIKeyController { + return &AdminAPIKeyController{ + apiKeyService: apiKeyService, + } +} + +// GetAllAPIKeys get all api keys +// @Summary get all api keys +// @Description get all api keys +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=[]schema.GetAPIKeyResp} +// @Router /answer/admin/api/api-key/all [get] +func (sc *AdminAPIKeyController) GetAllAPIKeys(ctx *gin.Context) { + resp, err := sc.apiKeyService.GetAPIKeyList(ctx, &schema.GetAPIKeyReq{}) + handler.HandleResponse(ctx, err, resp) +} + +// AddAPIKey add apikey +// @Summary add apikey +// @Description add apikey +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Param data body schema.AddAPIKeyReq true "apikey" +// @Success 200 {object} handler.RespBody{data=schema.AddAPIKeyResp} +// @Router /answer/admin/api/api-key [post] +func (sc *AdminAPIKeyController) AddAPIKey(ctx *gin.Context) { + req := &schema.AddAPIKeyReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + resp, err := sc.apiKeyService.AddAPIKey(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// UpdateAPIKey update apikey +// @Summary update apikey +// @Description update apikey +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Param data body schema.UpdateAPIKeyReq true "apikey" +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/api-key [put] +func (sc *AdminAPIKeyController) UpdateAPIKey(ctx *gin.Context) { + req := &schema.UpdateAPIKeyReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + err := sc.apiKeyService.UpdateAPIKey(ctx, req) + handler.HandleResponse(ctx, err, nil) +} + +// DeleteAPIKey delete apikey +// @Summary delete apikey +// @Description delete apikey +// @Security ApiKeyAuth +// @Tags admin +// @Param data body schema.DeleteAPIKeyReq true "apikey" +// @Produce json +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/api-key [delete] +func (sc *AdminAPIKeyController) DeleteAPIKey(ctx *gin.Context) { + req := &schema.DeleteAPIKeyReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + err := sc.apiKeyService.DeleteAPIKey(ctx, req) + handler.HandleResponse(ctx, err, nil) +} diff --git a/internal/controller_admin/siteinfo_controller.go b/internal/controller_admin/siteinfo_controller.go index 8a92daba3..17eab648a 100644 --- a/internal/controller_admin/siteinfo_controller.go +++ b/internal/controller_admin/siteinfo_controller.go @@ -459,3 +459,105 @@ func (sc *SiteInfoController) UpdatePrivilegesConfig(ctx *gin.Context) { err := sc.siteInfoService.UpdatePrivilegesConfig(ctx, req) handler.HandleResponse(ctx, err, nil) } + +// GetAIConfig get AI configuration +// @Summary get AI configuration +// @Description get AI configuration +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=schema.SiteAIResp} +// @Router /answer/admin/api/ai-config [get] +func (sc *SiteInfoController) GetAIConfig(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteAI(ctx) + handler.HandleResponse(ctx, err, resp) +} + +// UpdateAIConfig update AI configuration +// @Summary update AI configuration +// @Description update AI configuration +// @Security ApiKeyAuth +// @Tags admin +// @Param data body schema.SiteAIReq true "AI config" +// @Produce json +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/ai-config [put] +func (sc *SiteInfoController) UpdateAIConfig(ctx *gin.Context) { + req := &schema.SiteAIReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + err := sc.siteInfoService.SaveSiteAI(ctx, req) + handler.HandleResponse(ctx, err, nil) +} + +// GetAIProvider get AI provider configuration +// @Summary get AI provider configuration +// @Description get AI provider configuration +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=[]schema.GetAIProviderResp} +// @Router /answer/admin/api/ai-provider [get] +func (sc *SiteInfoController) GetAIProvider(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetAIProvider(ctx) + if err != nil { + handler.HandleResponse(ctx, err, nil) + return + } + handler.HandleResponse(ctx, nil, resp) +} + +// RequestAIModels get AI models +// @Summary get AI models +// @Description get AI models +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=[]schema.GetAIModelResp} +// @Router /answer/admin/api/ai-models [post] +func (sc *SiteInfoController) RequestAIModels(ctx *gin.Context) { + req := &schema.GetAIModelsReq{} + if handler.BindAndCheck(ctx, req) { + return + } + resp, err := sc.siteInfoService.GetAIModels(ctx, req) + if err != nil { + handler.HandleResponse(ctx, err, nil) + return + } + handler.HandleResponse(ctx, nil, resp) +} + +// GetMCPConfig get MCP configuration +// @Summary get MCP configuration +// @Description get MCP configuration +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=schema.SiteMCPResp} +// @Router /answer/admin/api/mcp-config [get] +func (sc *SiteInfoController) GetMCPConfig(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteMCP(ctx) + handler.HandleResponse(ctx, err, resp) +} + +// UpdateMCPConfig update MCP configuration +// @Summary update MCP configuration +// @Description update MCP configuration +// @Security ApiKeyAuth +// @Tags admin +// @Param data body schema.SiteMCPReq true "MCP config" +// @Produce json +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/mcp-config [put] +func (sc *SiteInfoController) UpdateMCPConfig(ctx *gin.Context) { + req := &schema.SiteMCPReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + err := sc.siteInfoService.SaveSiteMCP(ctx, req) + handler.HandleResponse(ctx, err, nil) +} diff --git a/internal/entity/ai_conversation.go b/internal/entity/ai_conversation.go new file mode 100644 index 000000000..7a610f7ba --- /dev/null +++ b/internal/entity/ai_conversation.go @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package entity + +import "time" + +// AIConversation AI +type AIConversation struct { + ID int `xorm:"not null pk autoincr INT(11) id"` + CreatedAt time.Time `xorm:"created not null default CURRENT_TIMESTAMP TIMESTAMP created_at"` + UpdatedAt time.Time `xorm:"updated not null default CURRENT_TIMESTAMP TIMESTAMP updated_at"` + ConversationID string `xorm:"not null unique VARCHAR(255) conversation_id"` + Topic string `xorm:"not null MEDIUMTEXT topic"` + UserID string `xorm:"not null default 0 BIGINT(20) user_id"` +} + +// TableName returns the table name +func (AIConversation) TableName() string { + return "ai_conversation" +} diff --git a/internal/entity/ai_conversation_record.go b/internal/entity/ai_conversation_record.go new file mode 100644 index 000000000..14dea3470 --- /dev/null +++ b/internal/entity/ai_conversation_record.go @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package entity + +import "time" + +// AIConversationRecord AI Conversation Record +type AIConversationRecord struct { + ID int `xorm:"not null pk autoincr INT(11) id"` + CreatedAt time.Time `xorm:"created not null default CURRENT_TIMESTAMP TIMESTAMP created_at"` + UpdatedAt time.Time `xorm:"updated not null default CURRENT_TIMESTAMP TIMESTAMP updated_at"` + ConversationID string `xorm:"not null VARCHAR(255) conversation_id"` + ChatCompletionID string `xorm:"not null VARCHAR(255) chat_completion_id"` + Role string `xorm:"not null default '' VARCHAR(128) role"` + Content string `xorm:"not null MEDIUMTEXT content"` + Helpful int `xorm:"not null default 0 INT(11) helpful"` + Unhelpful int `xorm:"not null default 0 INT(11) unhelpful"` +} + +// TableName returns the table name +func (AIConversationRecord) TableName() string { + return "ai_conversation_record" +} diff --git a/internal/entity/api_key_entity.go b/internal/entity/api_key_entity.go new file mode 100644 index 000000000..6d7713fec --- /dev/null +++ b/internal/entity/api_key_entity.go @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package entity + +import ( + "time" +) + +// APIKey entity +type APIKey struct { + ID int `xorm:"not null pk autoincr INT(11) id"` + CreatedAt time.Time `xorm:"created not null default CURRENT_TIMESTAMP TIMESTAMP created_at"` + UpdatedAt time.Time `xorm:"updated not null default CURRENT_TIMESTAMP TIMESTAMP updated_at"` + LastUsedAt time.Time `xorm:"not null default CURRENT_TIMESTAMP TIMESTAMP last_used_at"` + Description string `xorm:"not null MEDIUMTEXT description"` + AccessKey string `xorm:"not null unique VARCHAR(255) access_key"` + Scope string `xorm:"not null VARCHAR(255) scope"` + UserID string `xorm:"not null default 0 BIGINT(20) user_id"` + Hidden int `xorm:"not null default 0 INT(11) hidden"` +} + +// TableName category table name +func (c *APIKey) TableName() string { + return "api_key" +} diff --git a/internal/migrations/migrations.go b/internal/migrations/migrations.go index 9fda8c34d..9daba69fe 100644 --- a/internal/migrations/migrations.go +++ b/internal/migrations/migrations.go @@ -105,6 +105,7 @@ var migrations = []Migration{ NewMigration("v1.6.0", "move user config to interface", moveUserConfigToInterface, true), NewMigration("v1.7.0", "add optional tags", addOptionalTags, true), NewMigration("v1.7.2", "expand avatar column length", expandAvatarColumnLength, false), + NewMigration("v1.8.1", "ai feat", aiFeat, true), } func GetMigrations() []Migration { diff --git a/internal/migrations/v32.go b/internal/migrations/v32.go new file mode 100644 index 000000000..89b970475 --- /dev/null +++ b/internal/migrations/v32.go @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package migrations + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/apache/answer/internal/base/constant" + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/schema" + "github.com/segmentfault/pacman/log" + "xorm.io/xorm" +) + +func aiFeat(ctx context.Context, x *xorm.Engine) error { + if err := addAIConversationTables(ctx, x); err != nil { + return fmt.Errorf("add ai conversation tables failed: %w", err) + } + if err := addAPIKey(ctx, x); err != nil { + return fmt.Errorf("add api key failed: %w", err) + } + log.Info("AI feature migration completed successfully") + return nil +} + +func addAIConversationTables(ctx context.Context, x *xorm.Engine) error { + if err := x.Context(ctx).Sync(new(entity.AIConversation)); err != nil { + return fmt.Errorf("sync ai_conversation table failed: %w", err) + } + + if err := x.Context(ctx).Sync(new(entity.AIConversationRecord)); err != nil { + return fmt.Errorf("sync ai_conversation_record table failed: %w", err) + } + + return nil +} + +func addAPIKey(ctx context.Context, x *xorm.Engine) error { + err := x.Context(ctx).Sync(new(entity.APIKey)) + if err != nil { + return err + } + + defaultConfigTable := []*entity.Config{ + {ID: 10000, Key: "ai_config.provider", Value: `[{"default_api_host":"https://api.openai.com","display_name":"OpenAI","name":"openai"},{"default_api_host":"https://generativelanguage.googleapis.com","display_name":"Gemini","name":"gemini"},{"default_api_host":"https://api.anthropic.com","display_name":"Anthropic","name":"anthropic"}]`}, + } + for _, c := range defaultConfigTable { + exist, err := x.Context(ctx).Get(&entity.Config{Key: c.Key}) + if err != nil { + return fmt.Errorf("get config failed: %w", err) + } + if exist { + continue + } + if _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { + log.Errorf("insert %+v config failed: %s", c, err) + return fmt.Errorf("add config failed: %w", err) + } + } + + aiSiteInfo := &entity.SiteInfo{ + Type: constant.SiteTypeAI, + } + exist, err := x.Context(ctx).Get(aiSiteInfo) + if err != nil { + return fmt.Errorf("get config failed: %w", err) + } + if exist { + content := &schema.SiteAIReq{} + _ = json.Unmarshal([]byte(aiSiteInfo.Content), content) + content.PromptConfig = &schema.AIPromptConfig{ + ZhCN: constant.DefaultAIPromptConfigZhCN, + EnUS: constant.DefaultAIPromptConfigEnUS, + } + data, _ := json.Marshal(content) + aiSiteInfo.Content = string(data) + _, err = x.Context(ctx).ID(aiSiteInfo.ID).Cols("content").Update(aiSiteInfo) + if err != nil { + return fmt.Errorf("update site info failed: %w", err) + } + } else { + content := &schema.SiteAIReq{ + PromptConfig: &schema.AIPromptConfig{ + ZhCN: constant.DefaultAIPromptConfigZhCN, + EnUS: constant.DefaultAIPromptConfigEnUS, + }, + } + data, _ := json.Marshal(content) + aiSiteInfo.Content = string(data) + aiSiteInfo.Type = constant.SiteTypeAI + if _, err = x.Context(ctx).Insert(aiSiteInfo); err != nil { + return fmt.Errorf("insert site info failed: %w", err) + } + log.Infof("insert site info %+v", aiSiteInfo) + } + return nil +} diff --git a/internal/repo/ai_conversation/ai_conversation_repo.go b/internal/repo/ai_conversation/ai_conversation_repo.go new file mode 100644 index 000000000..9947eb6cc --- /dev/null +++ b/internal/repo/ai_conversation/ai_conversation_repo.go @@ -0,0 +1,205 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package ai_conversation + +import ( + "context" + + "github.com/apache/answer/internal/base/data" + "github.com/apache/answer/internal/base/pager" + "github.com/apache/answer/internal/base/reason" + "github.com/apache/answer/internal/entity" + "github.com/segmentfault/pacman/errors" + "github.com/segmentfault/pacman/log" + "xorm.io/builder" + "xorm.io/xorm" +) + +// AIConversationRepo +type AIConversationRepo interface { + CreateConversation(ctx context.Context, conversation *entity.AIConversation) error + GetConversation(ctx context.Context, conversationID string) (*entity.AIConversation, bool, error) + UpdateConversation(ctx context.Context, conversation *entity.AIConversation) error + GetConversationsPage(ctx context.Context, page, pageSize int, cond *entity.AIConversation) (list []*entity.AIConversation, total int64, err error) + CreateRecord(ctx context.Context, record *entity.AIConversationRecord) error + GetRecordsByConversationID(ctx context.Context, conversationID string) ([]*entity.AIConversationRecord, error) + UpdateRecordVote(ctx context.Context, cond *entity.AIConversationRecord) error + GetRecord(ctx context.Context, recordID int) (*entity.AIConversationRecord, bool, error) + GetRecordByChatCompletionID(ctx context.Context, role, chatCompletionID string) (*entity.AIConversationRecord, bool, error) + GetConversationsForAdmin(ctx context.Context, page, pageSize int, cond *entity.AIConversation) (list []*entity.AIConversation, total int64, err error) + GetConversationWithVoteStats(ctx context.Context, conversationID string) (helpful, unhelpful int64, err error) + DeleteConversation(ctx context.Context, conversationID string) error +} + +type aiConversationRepo struct { + data *data.Data +} + +// NewAIConversationRepo new AIConversationRepo +func NewAIConversationRepo(data *data.Data) AIConversationRepo { + return &aiConversationRepo{ + data: data, + } +} + +// CreateConversation creates a conversation +func (r *aiConversationRepo) CreateConversation(ctx context.Context, conversation *entity.AIConversation) error { + _, err := r.data.DB.Context(ctx).Insert(conversation) + if err != nil { + log.Errorf("create ai conversation failed: %v", err) + return err + } + return nil +} + +// GetConversation gets a conversation +func (r *aiConversationRepo) GetConversation(ctx context.Context, conversationID string) (*entity.AIConversation, bool, error) { + conversation := &entity.AIConversation{} + exist, err := r.data.DB.Context(ctx).Where(builder.Eq{"conversation_id": conversationID}).Get(conversation) + if err != nil { + log.Errorf("get ai conversation failed: %v", err) + return nil, false, err + } + return conversation, exist, nil +} + +// UpdateConversation updates a conversation +func (r *aiConversationRepo) UpdateConversation(ctx context.Context, conversation *entity.AIConversation) error { + _, err := r.data.DB.Context(ctx).ID(conversation.ID).Update(conversation) + if err != nil { + log.Errorf("update ai conversation failed: %v", err) + return err + } + return nil +} + +// GetConversationsPage get conversations by user ID +func (r *aiConversationRepo) GetConversationsPage(ctx context.Context, page, pageSize int, cond *entity.AIConversation) (list []*entity.AIConversation, total int64, err error) { + list = make([]*entity.AIConversation, 0) + total, err = pager.Help(page, pageSize, &list, cond, r.data.DB.Context(ctx).Desc("id")) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return list, total, err +} + +// CreateRecord creates a conversation record +func (r *aiConversationRepo) CreateRecord(ctx context.Context, record *entity.AIConversationRecord) error { + _, err := r.data.DB.Context(ctx).Insert(record) + if err != nil { + log.Errorf("create ai conversation record failed: %v", err) + return err + } + return nil +} + +// GetRecordsByConversationID get records by conversation ID +func (r *aiConversationRepo) GetRecordsByConversationID(ctx context.Context, conversationID string) ([]*entity.AIConversationRecord, error) { + records := make([]*entity.AIConversationRecord, 0) + err := r.data.DB.Context(ctx). + Where(builder.Eq{"conversation_id": conversationID}). + OrderBy("created_at ASC"). + Find(&records) + if err != nil { + log.Errorf("get ai conversation records failed: %v", err) + return nil, err + } + return records, nil +} + +// UpdateRecordVote update record vote +func (r *aiConversationRepo) UpdateRecordVote(ctx context.Context, cond *entity.AIConversationRecord) (err error) { + _, err = r.data.DB.Context(ctx).ID(cond.ID).MustCols("helpful", "unhelpful").Update(cond) + if err != nil { + log.Errorf("update ai conversation record vote failed: %v", err) + return err + } + return nil +} + +// GetRecord get record +func (r *aiConversationRepo) GetRecord(ctx context.Context, recordID int) (*entity.AIConversationRecord, bool, error) { + record := &entity.AIConversationRecord{} + exist, err := r.data.DB.Context(ctx).ID(recordID).Get(record) + if err != nil { + log.Errorf("get ai conversation record failed: %v", err) + return nil, false, err + } + return record, exist, nil +} + +// GetRecordByChatCompletionID gets record by chat completion ID +func (r *aiConversationRepo) GetRecordByChatCompletionID(ctx context.Context, role, chatCompletionID string) (*entity.AIConversationRecord, bool, error) { + record := &entity.AIConversationRecord{} + exist, err := r.data.DB.Context(ctx).Where(builder.Eq{"role": role}). + Where(builder.Eq{"chat_completion_id": chatCompletionID}).Get(record) + if err != nil { + log.Errorf("get ai conversation record by chat completion id failed: %v", err) + return nil, false, err + } + return record, exist, nil +} + +// GetConversationsForAdmin gets conversation list for admin +func (r *aiConversationRepo) GetConversationsForAdmin(ctx context.Context, page, pageSize int, cond *entity.AIConversation) (list []*entity.AIConversation, total int64, err error) { + list = make([]*entity.AIConversation, 0) + total, err = pager.Help(page, pageSize, &list, cond, r.data.DB.Context(ctx).Desc("id")) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return list, total, err +} + +// GetConversationWithVoteStats gets conversation vote statistics +func (r *aiConversationRepo) GetConversationWithVoteStats(ctx context.Context, conversationID string) (helpful, unhelpful int64, err error) { + res, err := r.data.DB.Context(ctx).SumsInt(&entity.AIConversationRecord{ConversationID: conversationID}, "helpful", "unhelpful") + if err != nil { + log.Errorf("get ai conversation vote stats failed: %v", err) + return 0, 0, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + if len(res) < 2 { + log.Errorf("get ai conversation vote stats failed: invalid result length %d", len(res)) + return 0, 0, nil + } + return res[0], res[1], nil +} + +// DeleteConversation deletes a conversation and its related records +func (r *aiConversationRepo) DeleteConversation(ctx context.Context, conversationID string) error { + _, err := r.data.DB.Transaction(func(session *xorm.Session) (result any, err error) { + if _, err := session.Context(ctx).Where("conversation_id = ?", conversationID).Delete(&entity.AIConversationRecord{}); err != nil { + log.Errorf("delete ai conversation records failed: %v", err) + return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + + if _, err := session.Context(ctx).Where("conversation_id = ?", conversationID).Delete(&entity.AIConversation{}); err != nil { + log.Errorf("delete ai conversation failed: %v", err) + return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + + return nil, nil + }) + + if err != nil { + return err + } + + return nil +} diff --git a/internal/repo/api_key/api_key_repo.go b/internal/repo/api_key/api_key_repo.go new file mode 100644 index 000000000..2309384a9 --- /dev/null +++ b/internal/repo/api_key/api_key_repo.go @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package api_key + +import ( + "context" + + "github.com/apache/answer/internal/base/data" + "github.com/apache/answer/internal/base/reason" + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/service/apikey" + "github.com/segmentfault/pacman/errors" +) + +type apiKeyRepo struct { + data *data.Data +} + +// NewAPIKeyRepo creates a new apiKey repository +func NewAPIKeyRepo(data *data.Data) apikey.APIKeyRepo { + return &apiKeyRepo{ + data: data, + } +} + +func (ar *apiKeyRepo) GetAPIKeyList(ctx context.Context) (keys []*entity.APIKey, err error) { + keys = make([]*entity.APIKey, 0) + err = ar.data.DB.Context(ctx).Where("hidden = ?", 0).Find(&keys) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return +} + +func (ar *apiKeyRepo) GetAPIKey(ctx context.Context, apiKey string) (key *entity.APIKey, exist bool, err error) { + key = &entity.APIKey{} + exist, err = ar.data.DB.Context(ctx).Where("access_key = ?", apiKey).Get(key) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return +} + +func (ar *apiKeyRepo) UpdateAPIKey(ctx context.Context, apiKey entity.APIKey) (err error) { + _, err = ar.data.DB.Context(ctx).ID(apiKey.ID).Update(&apiKey) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return +} + +func (ar *apiKeyRepo) AddAPIKey(ctx context.Context, apiKey entity.APIKey) (err error) { + _, err = ar.data.DB.Context(ctx).Insert(&apiKey) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return +} + +func (ar *apiKeyRepo) DeleteAPIKey(ctx context.Context, id int) (err error) { + _, err = ar.data.DB.Context(ctx).ID(id).Delete(&entity.APIKey{}) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return +} diff --git a/internal/repo/provider.go b/internal/repo/provider.go index 02f27f62f..510a94aaa 100644 --- a/internal/repo/provider.go +++ b/internal/repo/provider.go @@ -23,7 +23,9 @@ import ( "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/repo/activity" "github.com/apache/answer/internal/repo/activity_common" + "github.com/apache/answer/internal/repo/ai_conversation" "github.com/apache/answer/internal/repo/answer" + "github.com/apache/answer/internal/repo/api_key" "github.com/apache/answer/internal/repo/auth" "github.com/apache/answer/internal/repo/badge" "github.com/apache/answer/internal/repo/badge_award" @@ -109,4 +111,6 @@ var ProviderSetRepo = wire.NewSet( badge_group.NewBadgeGroupRepo, badge_award.NewBadgeAwardRepo, file_record.NewFileRecordRepo, + api_key.NewAPIKeyRepo, + ai_conversation.NewAIConversationRepo, ) diff --git a/internal/repo/site_info/siteinfo_repo.go b/internal/repo/site_info/siteinfo_repo.go index 5f95b7486..379a59c91 100644 --- a/internal/repo/site_info/siteinfo_repo.go +++ b/internal/repo/site_info/siteinfo_repo.go @@ -63,10 +63,12 @@ func (sr *siteInfoRepo) SaveByType(ctx context.Context, siteType string, data *e } // GetByType get site info by type -func (sr *siteInfoRepo) GetByType(ctx context.Context, siteType string) (siteInfo *entity.SiteInfo, exist bool, err error) { - siteInfo = sr.getCache(ctx, siteType) - if siteInfo != nil { - return siteInfo, true, nil +func (sr *siteInfoRepo) GetByType(ctx context.Context, siteType string, withoutCache ...bool) (siteInfo *entity.SiteInfo, exist bool, err error) { + if len(withoutCache) == 0 { + siteInfo = sr.getCache(ctx, siteType) + if siteInfo != nil { + return siteInfo, true, nil + } } siteInfo = &entity.SiteInfo{} exist, err = sr.data.DB.Context(ctx).Where(builder.Eq{"type": siteType}).Get(siteInfo) diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go index 1191492b9..6b0f4fdb0 100644 --- a/internal/router/answer_api_router.go +++ b/internal/router/answer_api_router.go @@ -27,36 +27,40 @@ import ( ) type AnswerAPIRouter struct { - langController *controller.LangController - userController *controller.UserController - commentController *controller.CommentController - reportController *controller.ReportController - voteController *controller.VoteController - tagController *controller.TagController - followController *controller.FollowController - collectionController *controller.CollectionController - questionController *controller.QuestionController - answerController *controller.AnswerController - searchController *controller.SearchController - revisionController *controller.RevisionController - rankController *controller.RankController - adminUserController *controller_admin.UserAdminController - reasonController *controller.ReasonController - themeController *controller_admin.ThemeController - adminSiteInfoController *controller_admin.SiteInfoController - siteInfoController *controller.SiteInfoController - notificationController *controller.NotificationController - dashboardController *controller.DashboardController - uploadController *controller.UploadController - activityController *controller.ActivityController - roleController *controller_admin.RoleController - pluginController *controller_admin.PluginController - permissionController *controller.PermissionController - userPluginController *controller.UserPluginController - reviewController *controller.ReviewController - metaController *controller.MetaController - badgeController *controller.BadgeController - adminBadgeController *controller_admin.BadgeController + langController *controller.LangController + userController *controller.UserController + commentController *controller.CommentController + reportController *controller.ReportController + voteController *controller.VoteController + tagController *controller.TagController + followController *controller.FollowController + collectionController *controller.CollectionController + questionController *controller.QuestionController + answerController *controller.AnswerController + searchController *controller.SearchController + revisionController *controller.RevisionController + rankController *controller.RankController + adminUserController *controller_admin.UserAdminController + reasonController *controller.ReasonController + themeController *controller_admin.ThemeController + adminSiteInfoController *controller_admin.SiteInfoController + siteInfoController *controller.SiteInfoController + notificationController *controller.NotificationController + dashboardController *controller.DashboardController + uploadController *controller.UploadController + activityController *controller.ActivityController + roleController *controller_admin.RoleController + pluginController *controller_admin.PluginController + permissionController *controller.PermissionController + userPluginController *controller.UserPluginController + reviewController *controller.ReviewController + metaController *controller.MetaController + badgeController *controller.BadgeController + adminBadgeController *controller_admin.BadgeController + apiKeyController *controller_admin.AdminAPIKeyController + aiController *controller.AIController + aiConversationController *controller.AIConversationController + aiConversationAdminController *controller_admin.AIConversationAdminController } func NewAnswerAPIRouter( @@ -90,38 +94,46 @@ func NewAnswerAPIRouter( metaController *controller.MetaController, badgeController *controller.BadgeController, adminBadgeController *controller_admin.BadgeController, + apiKeyController *controller_admin.AdminAPIKeyController, + aiController *controller.AIController, + aiConversationController *controller.AIConversationController, + aiConversationAdminController *controller_admin.AIConversationAdminController, ) *AnswerAPIRouter { return &AnswerAPIRouter{ - langController: langController, - userController: userController, - commentController: commentController, - reportController: reportController, - voteController: voteController, - tagController: tagController, - followController: followController, - collectionController: collectionController, - questionController: questionController, - answerController: answerController, - searchController: searchController, - revisionController: revisionController, - rankController: rankController, - adminUserController: adminUserController, - reasonController: reasonController, - themeController: themeController, - adminSiteInfoController: adminSiteInfoController, - notificationController: notificationController, - siteInfoController: siteInfoController, - dashboardController: dashboardController, - uploadController: uploadController, - activityController: activityController, - roleController: roleController, - pluginController: pluginController, - permissionController: permissionController, - userPluginController: userPluginController, - reviewController: reviewController, - metaController: metaController, - badgeController: badgeController, - adminBadgeController: adminBadgeController, + langController: langController, + userController: userController, + commentController: commentController, + reportController: reportController, + voteController: voteController, + tagController: tagController, + followController: followController, + collectionController: collectionController, + questionController: questionController, + answerController: answerController, + searchController: searchController, + revisionController: revisionController, + rankController: rankController, + adminUserController: adminUserController, + reasonController: reasonController, + themeController: themeController, + adminSiteInfoController: adminSiteInfoController, + notificationController: notificationController, + siteInfoController: siteInfoController, + dashboardController: dashboardController, + uploadController: uploadController, + activityController: activityController, + roleController: roleController, + pluginController: pluginController, + permissionController: permissionController, + userPluginController: userPluginController, + reviewController: reviewController, + metaController: metaController, + badgeController: badgeController, + adminBadgeController: adminBadgeController, + apiKeyController: apiKeyController, + aiController: aiController, + aiConversationController: aiConversationController, + aiConversationAdminController: aiConversationAdminController, } } @@ -310,6 +322,14 @@ func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) { // meta r.PUT("/meta/reaction", a.metaController.AddOrUpdateReaction) + + // AI chat + r.POST("/chat/completions", a.aiController.ChatCompletions) + + // AI conversation + r.GET("/ai/conversation/page", a.aiConversationController.GetConversationList) + r.GET("/ai/conversation", a.aiConversationController.GetConversationDetail) + r.POST("/ai/conversation/vote", a.aiConversationController.VoteRecord) } func (a *AnswerAPIRouter) RegisterAnswerAdminAPIRouter(r *gin.RouterGroup) { @@ -381,4 +401,25 @@ func (a *AnswerAPIRouter) RegisterAnswerAdminAPIRouter(r *gin.RouterGroup) { // badge r.GET("/badges", a.adminBadgeController.GetBadgeList) r.PUT("/badge/status", a.adminBadgeController.UpdateBadgeStatus) + + // api key + r.GET("/api-key/all", a.apiKeyController.GetAllAPIKeys) + r.POST("/api-key", a.apiKeyController.AddAPIKey) + r.PUT("/api-key", a.apiKeyController.UpdateAPIKey) + r.DELETE("/api-key", a.apiKeyController.DeleteAPIKey) + + // ai config + r.GET("/ai-config", a.adminSiteInfoController.GetAIConfig) + r.PUT("/ai-config", a.adminSiteInfoController.UpdateAIConfig) + r.GET("/ai-provider", a.adminSiteInfoController.GetAIProvider) + r.POST("/ai-models", a.adminSiteInfoController.RequestAIModels) + + // mcp config + r.GET("/mcp-config", a.adminSiteInfoController.GetMCPConfig) + r.PUT("/mcp-config", a.adminSiteInfoController.UpdateMCPConfig) + + // AI conversation management + r.GET("/ai/conversation/page", a.aiConversationAdminController.GetConversationList) + r.GET("/ai/conversation", a.aiConversationAdminController.GetConversationDetail) + r.DELETE("/ai/conversation", a.aiConversationAdminController.DeleteConversation) } diff --git a/internal/schema/ai_config_schema.go b/internal/schema/ai_config_schema.go new file mode 100644 index 000000000..6ac686343 --- /dev/null +++ b/internal/schema/ai_config_schema.go @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package schema + +// GetAIProviderResp get AI providers response +type GetAIProviderResp struct { + Name string `json:"name"` + DisplayName string `json:"display_name"` + DefaultAPIHost string `json:"default_api_host"` +} + +// GetAIModelsResp get AI model response +type GetAIModelsResp struct { + Object string `json:"object"` + Data []struct { + Id string `json:"id"` + Object string `json:"object"` + Created int `json:"created"` + OwnedBy string `json:"owned_by"` + } `json:"data"` +} + +type GetAIModelsReq struct { + APIHost string `json:"api_host"` + APIKey string `json:"api_key"` +} + +// GetAIModelResp get AI model response +type GetAIModelResp struct { + Id string `json:"id"` + Object string `json:"object"` + Created int `json:"created"` + OwnedBy string `json:"owned_by"` +} diff --git a/internal/schema/ai_conversation_schema.go b/internal/schema/ai_conversation_schema.go new file mode 100644 index 000000000..fd34278a1 --- /dev/null +++ b/internal/schema/ai_conversation_schema.go @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package schema + +import ( + "github.com/apache/answer/internal/base/validator" +) + +// AIConversationListReq ai conversation list req +type AIConversationListReq struct { + Page int `validate:"omitempty,min=1" form:"page"` + PageSize int `validate:"omitempty,min=1" form:"page_size"` + UserID string `validate:"omitempty" json:"-"` +} + +// AIConversationListItem ai conversation list item +type AIConversationListItem struct { + ConversationID string `json:"conversation_id"` + Topic string `json:"topic"` + CreatedAt int64 `json:"created_at"` +} + +// AIConversationDetailReq ai conversation detail req +type AIConversationDetailReq struct { + ConversationID string `validate:"required" form:"conversation_id" json:"conversation_id"` + UserID string `validate:"omitempty" json:"-"` +} + +// AIConversationRecord ai conversation record +type AIConversationRecord struct { + ChatCompletionID string `json:"chat_completion_id"` + Role string `json:"role"` + Content string `json:"content"` + Helpful int `json:"helpful"` + Unhelpful int `json:"unhelpful"` + CreatedAt int64 `json:"created_at"` +} + +// AIConversationDetailResp ai conversation detail resp +type AIConversationDetailResp struct { + ConversationID string `json:"conversation_id"` + Topic string `json:"topic"` + Records []*AIConversationRecord `json:"records"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` +} + +// AIConversationVoteReq ai conversation vote req +type AIConversationVoteReq struct { + ChatCompletionID string `validate:"required" json:"chat_completion_id"` + VoteType string `validate:"required,oneof=helpful unhelpful" json:"vote_type"` + Cancel bool `validate:"omitempty" json:"cancel"` + UserID string `validate:"omitempty" json:"-"` +} + +// AIConversationAdminListReq ai conversation admin list req +type AIConversationAdminListReq struct { + Page int `validate:"omitempty,min=1" form:"page"` + PageSize int `validate:"omitempty,min=1" form:"page_size"` +} + +// AIConversationAdminListItem ai conversation admin list item +type AIConversationAdminListItem struct { + ID string `json:"id"` + Topic string `json:"topic"` + UserInfo AIConversationUserInfo `json:"user_info"` + HelpfulCount int64 `json:"helpful_count"` + UnhelpfulCount int64 `json:"unhelpful_count"` + CreatedAt int64 `json:"created_at"` +} + +// AIConversationUserInfo ai conversation user info +type AIConversationUserInfo struct { + ID string `json:"id"` + Username string `json:"username"` + DisplayName string `json:"display_name"` + Avatar string `json:"avatar"` + Rank int `json:"rank"` +} + +// AIConversationAdminDetailReq ai conversation admin detail req +type AIConversationAdminDetailReq struct { + ConversationID string `validate:"required" form:"conversation_id" json:"conversation_id"` +} + +// AIConversationAdminDetailResp ai conversation admin detail resp +type AIConversationAdminDetailResp struct { + ConversationID string `json:"conversation_id"` + Topic string `json:"topic"` + UserInfo AIConversationUserInfo `json:"user_info"` + Records []AIConversationRecord `json:"records"` + CreatedAt int64 `json:"created_at"` +} + +// AIConversationAdminDeleteReq admin delete ai +type AIConversationAdminDeleteReq struct { + ConversationID string `validate:"required" json:"conversation_id"` +} + +func (req *AIConversationDetailReq) Check() (errFields []*validator.FormErrorField, err error) { + return nil, nil +} + +func (req *AIConversationVoteReq) Check() (errFields []*validator.FormErrorField, err error) { + return nil, nil +} diff --git a/internal/schema/api_key_schema.go b/internal/schema/api_key_schema.go new file mode 100644 index 000000000..e9dde7847 --- /dev/null +++ b/internal/schema/api_key_schema.go @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package schema + +// GetAPIKeyReq get api key request +type GetAPIKeyReq struct { + UserID string `json:"-"` +} + +// GetAPIKeyResp get api keys response +type GetAPIKeyResp struct { + ID int `json:"id"` + AccessKey string `json:"access_key"` + Description string `json:"description"` + Scope string `json:"scope"` + CreatedAt int64 `json:"created_at"` + LastUsedAt int64 `json:"last_used_at"` +} + +// AddAPIKeyReq add api key request +type AddAPIKeyReq struct { + Description string `validate:"required,notblank,lte=150" json:"description"` + Scope string `validate:"required,oneof=read-only global" json:"scope"` + UserID string `json:"-"` +} + +// AddAPIKeyResp add api key response +type AddAPIKeyResp struct { + AccessKey string `json:"access_key"` +} + +// UpdateAPIKeyReq update api key request +type UpdateAPIKeyReq struct { + ID int `validate:"required" json:"id"` + Description string `validate:"required,notblank,lte=150" json:"description"` + UserID string `json:"-"` +} + +// DeleteAPIKeyReq delete api key request +type DeleteAPIKeyReq struct { + ID int `json:"id"` + UserID string `json:"-"` +} diff --git a/internal/schema/mcp_schema.go b/internal/schema/mcp_schema.go new file mode 100644 index 000000000..bead21c9d --- /dev/null +++ b/internal/schema/mcp_schema.go @@ -0,0 +1,194 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package schema + +import ( + "strings" + + "github.com/apache/answer/pkg/converter" + "github.com/mark3labs/mcp-go/mcp" +) + +const ( + MCPSearchCondKeyword = "keyword" + MCPSearchCondUsername = "username" + MCPSearchCondScore = "score" + MCPSearchCondTag = "tag" + MCPSearchCondPage = "page" + MCPSearchCondPageSize = "page_size" + MCPSearchCondTagName = "tag_name" + MCPSearchCondQuestionID = "question_id" + MCPSearchCondObjectID = "object_id" +) + +type MCPSearchCond struct { + Keyword string `json:"keyword"` + Username string `json:"username"` + Score int `json:"score"` + Tags []string `json:"tags"` + QuestionID string `json:"question_id"` +} + +type MCPSearchQuestionDetail struct { + QuestionID string `json:"question_id"` +} + +type MCPSearchCommentCond struct { + ObjectID string `json:"object_id"` +} + +type MCPSearchTagCond struct { + TagName string `json:"tag_name"` +} + +type MCPSearchUserCond struct { + Username string `json:"username"` +} + +type MCPSearchQuestionInfoResp struct { + QuestionID string `json:"question_id"` + Title string `json:"title"` + Content string `json:"content"` + Link string `json:"link"` +} + +type MCPSearchAnswerInfoResp struct { + QuestionID string `json:"question_id"` + QuestionTitle string `json:"question_title,omitempty"` + AnswerID string `json:"answer_id"` + AnswerContent string `json:"answer_content"` + Link string `json:"link"` +} + +type MCPSearchTagResp struct { + TagName string `json:"tag_name"` + DisplayName string `json:"display_name"` + Description string `json:"description"` + Link string `json:"link"` +} + +type MCPSearchUserInfoResp struct { + Username string `json:"username"` + DisplayName string `json:"display_name"` + Avatar string `json:"avatar"` + Link string `json:"link"` +} + +type MCPSearchCommentInfoResp struct { + CommentID string `json:"comment_id"` + Content string `json:"content"` + ObjectID string `json:"object_id"` + Link string `json:"link"` +} + +func NewMCPSearchCond(request mcp.CallToolRequest) *MCPSearchCond { + cond := &MCPSearchCond{} + if keyword, ok := getRequestValue(request, MCPSearchCondKeyword); ok { + cond.Keyword = keyword + } + if username, ok := getRequestValue(request, MCPSearchCondUsername); ok { + cond.Username = username + } + if score, ok := getRequestNumber(request, MCPSearchCondScore); ok { + cond.Score = score + } + if tag, ok := getRequestValue(request, MCPSearchCondTag); ok { + cond.Tags = strings.Split(tag, ",") + } + if questionID, ok := getRequestValue(request, MCPSearchCondQuestionID); ok { + cond.QuestionID = questionID + } + return cond +} + +func NewMCPSearchAnswerCond(request mcp.CallToolRequest) *MCPSearchCond { + cond := &MCPSearchCond{} + if questionID, ok := getRequestValue(request, MCPSearchCondQuestionID); ok { + cond.QuestionID = questionID + } + return cond +} + +func NewMCPSearchQuestionDetail(request mcp.CallToolRequest) *MCPSearchQuestionDetail { + cond := &MCPSearchQuestionDetail{} + if questionID, ok := getRequestValue(request, MCPSearchCondQuestionID); ok { + cond.QuestionID = questionID + } + return cond +} + +func NewMCPSearchCommentCond(request mcp.CallToolRequest) *MCPSearchCommentCond { + cond := &MCPSearchCommentCond{} + if keyword, ok := getRequestValue(request, MCPSearchCondObjectID); ok { + cond.ObjectID = keyword + } + return cond +} + +func NewMCPSearchTagCond(request mcp.CallToolRequest) *MCPSearchTagCond { + cond := &MCPSearchTagCond{} + if tagName, ok := getRequestValue(request, MCPSearchCondTagName); ok { + cond.TagName = tagName + } + return cond +} + +func NewMCPSearchUserCond(request mcp.CallToolRequest) *MCPSearchUserCond { + cond := &MCPSearchUserCond{} + if username, ok := getRequestValue(request, MCPSearchCondUsername); ok { + cond.Username = username + } + return cond +} + +func getRequestValue(request mcp.CallToolRequest, key string) (string, bool) { + value, ok := request.GetArguments()[key].(string) + if !ok { + return "", false + } + return value, true +} + +func getRequestNumber(request mcp.CallToolRequest, key string) (int, bool) { + value, ok := request.GetArguments()[key].(float64) + if !ok { + return 0, false + } + return int(value), true +} + +func (cond *MCPSearchCond) ToQueryString() string { + var queryBuilder strings.Builder + if len(cond.Keyword) > 0 { + queryBuilder.WriteString(cond.Keyword) + } + if len(cond.Username) > 0 { + queryBuilder.WriteString(" user:" + cond.Username) + } + if cond.Score > 0 { + queryBuilder.WriteString(" score:" + converter.IntToString(int64(cond.Score))) + } + if len(cond.Tags) > 0 { + for _, tag := range cond.Tags { + queryBuilder.WriteString(" [" + tag + "]") + } + } + return strings.TrimSpace(queryBuilder.String()) +} diff --git a/internal/schema/mcp_tools/mcp_tools.go b/internal/schema/mcp_tools/mcp_tools.go new file mode 100644 index 000000000..949a738c7 --- /dev/null +++ b/internal/schema/mcp_tools/mcp_tools.go @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package mcp_tools + +import ( + "github.com/apache/answer/internal/schema" + "github.com/mark3labs/mcp-go/mcp" +) + +var ( + MCPToolsList = []mcp.Tool{ + NewQuestionsTool(), + NewAnswersTool(), + NewCommentsTool(), + NewTagsTool(), + NewTagDetailTool(), + NewUserTool(), + } +) + +func NewQuestionsTool() mcp.Tool { + listFilesTool := mcp.NewTool("get_questions", + mcp.WithDescription("Searching for questions that already existed in the system. After the search, you can use the get_answers_by_question_id tool to get answers for the questions."), + mcp.WithString(schema.MCPSearchCondKeyword, + mcp.Description("Keyword to search for questions. Multiple keywords separated by spaces"), + ), + mcp.WithString(schema.MCPSearchCondUsername, + mcp.Description("Search for questions that contain only those created by the specified user"), + ), + mcp.WithString(schema.MCPSearchCondTag, + mcp.Description("Filter by tag (semicolon separated for multiple tags)"), + ), + mcp.WithString(schema.MCPSearchCondScore, + mcp.Description("Minimum score that the question must have"), + ), + ) + return listFilesTool +} + +func NewAnswersTool() mcp.Tool { + listFilesTool := mcp.NewTool("get_answers_by_question_id", + mcp.WithDescription("Search for all answers corresponding to the question ID. The question ID is provided by get_questions tool."), + mcp.WithString(schema.MCPSearchCondQuestionID, + mcp.Description("The ID of the question to which the answer belongs. The question ID is provided by get_questions tool."), + ), + ) + return listFilesTool +} + +func NewCommentsTool() mcp.Tool { + listFilesTool := mcp.NewTool("get_comments", + mcp.WithDescription("Searching for comments that already existed in the system"), + mcp.WithString(schema.MCPSearchCondObjectID, + mcp.Description("Queries comments on an object, either a question or an answer. object_id is the id of the object."), + ), + ) + return listFilesTool +} + +func NewTagsTool() mcp.Tool { + listFilesTool := mcp.NewTool("get_tags", + mcp.WithDescription("Searching for tags that already existed in the system"), + mcp.WithString(schema.MCPSearchCondTagName, + mcp.Description("Tag name"), + ), + ) + return listFilesTool +} + +func NewTagDetailTool() mcp.Tool { + listFilesTool := mcp.NewTool("get_tag_detail", + mcp.WithDescription("Get detailed information about a specific tag"), + mcp.WithString(schema.MCPSearchCondTagName, + mcp.Description("Tag name"), + ), + ) + return listFilesTool +} + +func NewUserTool() mcp.Tool { + listFilesTool := mcp.NewTool("get_user", + mcp.WithDescription("Searching for users that already existed in the system"), + mcp.WithString(schema.MCPSearchCondUsername, + mcp.Description("Username"), + ), + ) + return listFilesTool +} diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index 9eb919a0c..034543a37 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -194,6 +194,56 @@ func (s *SiteSeoResp) IsShortLink() bool { s.Permalink == constant.PermalinkQuestionIDByShortID } +// AIPromptConfig AI prompt configuration for different languages +type AIPromptConfig struct { + ZhCN string `json:"zh_cn"` + EnUS string `json:"en_us"` +} + +// SiteAIReq AI configuration request +type SiteAIReq struct { + Enabled bool `validate:"omitempty" form:"enabled" json:"enabled"` + ChosenProvider string `validate:"omitempty,lte=50" form:"chosen_provider" json:"chosen_provider"` + SiteAIProviders []*SiteAIProvider `validate:"omitempty,dive" form:"ai_providers" json:"ai_providers"` + PromptConfig *AIPromptConfig `validate:"omitempty" form:"prompt_config" json:"prompt_config,omitempty"` +} + +func (s *SiteAIResp) GetProvider() *SiteAIProvider { + if !s.Enabled || s.ChosenProvider == "" { + return &SiteAIProvider{} + } + if len(s.SiteAIProviders) == 0 { + return &SiteAIProvider{} + } + for _, provider := range s.SiteAIProviders { + if provider.Provider == s.ChosenProvider { + return provider + } + } + return &SiteAIProvider{} +} + +type SiteAIProvider struct { + Provider string `validate:"omitempty,lte=50" form:"provider" json:"provider"` + APIHost string `validate:"omitempty,lte=512" form:"api_host" json:"api_host"` + APIKey string `validate:"omitempty,lte=256" form:"api_key" json:"api_key"` + Model string `validate:"omitempty,lte=100" form:"model" json:"model"` +} + +// SiteAIResp AI configuration response +type SiteAIResp SiteAIReq + +type SiteMCPReq struct { + Enabled bool `validate:"omitempty" form:"enabled" json:"enabled"` +} + +type SiteMCPResp struct { + Enabled bool `json:"enabled"` + Type string `json:"type"` + URL string `json:"url"` + HTTPHeader string `json:"http_header"` +} + // SiteGeneralResp site general response type SiteGeneralResp SiteGeneralReq @@ -266,6 +316,8 @@ type SiteInfoResp struct { Legal *SiteLegalSimpleResp `json:"site_legal"` Version string `json:"version"` Revision string `json:"revision"` + AIEnabled bool `json:"ai_enabled"` + MCPEnabled bool `json:"mcp_enabled"` } type TemplateSiteInfoResp struct { General *SiteGeneralResp `json:"general"` diff --git a/internal/service/ai_conversation/ai_conversation_service.go b/internal/service/ai_conversation/ai_conversation_service.go new file mode 100644 index 000000000..d095ac0e9 --- /dev/null +++ b/internal/service/ai_conversation/ai_conversation_service.go @@ -0,0 +1,372 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package ai_conversation + +import ( + "context" + "strings" + "time" + + "github.com/apache/answer/internal/base/pager" + "github.com/apache/answer/internal/base/reason" + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/repo/ai_conversation" + "github.com/apache/answer/internal/schema" + usercommon "github.com/apache/answer/internal/service/user_common" + "github.com/segmentfault/pacman/errors" + "github.com/segmentfault/pacman/log" +) + +// AIConversationService +type AIConversationService interface { + CreateConversation(ctx context.Context, userID, conversationID, topic string) error + SaveConversationRecords(ctx context.Context, conversationID, chatcmplID string, records []*ConversationMessage) error + GetConversationList(ctx context.Context, req *schema.AIConversationListReq) (*pager.PageModel, error) + GetConversationDetail(ctx context.Context, req *schema.AIConversationDetailReq) (resp *schema.AIConversationDetailResp, exist bool, err error) + VoteRecord(ctx context.Context, req *schema.AIConversationVoteReq) error + GetConversationListForAdmin(ctx context.Context, req *schema.AIConversationAdminListReq) (*pager.PageModel, error) + GetConversationDetailForAdmin(ctx context.Context, req *schema.AIConversationAdminDetailReq) (*schema.AIConversationAdminDetailResp, error) + DeleteConversationForAdmin(ctx context.Context, req *schema.AIConversationAdminDeleteReq) error +} + +// ConversationMessage +type ConversationMessage struct { + ChatCompletionID string `json:"chat_completion_id"` + Role string `json:"role"` + Content string `json:"content"` +} + +// aiConversationService +type aiConversationService struct { + aiConversationRepo ai_conversation.AIConversationRepo + userCommon *usercommon.UserCommon +} + +// NewAIConversationService +func NewAIConversationService( + aiConversationRepo ai_conversation.AIConversationRepo, + userCommon *usercommon.UserCommon, +) AIConversationService { + return &aiConversationService{ + aiConversationRepo: aiConversationRepo, + userCommon: userCommon, + } +} + +// CreateConversation +func (s *aiConversationService) CreateConversation(ctx context.Context, userID, conversationID, topic string) error { + conversation := &entity.AIConversation{ + ConversationID: conversationID, + Topic: topic, + UserID: userID, + } + err := s.aiConversationRepo.CreateConversation(ctx, conversation) + if err != nil { + log.Errorf("create conversation failed: %v", err) + return err + } + + return nil +} + +// SaveConversationRecords +func (s *aiConversationService) SaveConversationRecords(ctx context.Context, conversationID, chatcmplID string, records []*ConversationMessage) error { + conversation, exist, err := s.aiConversationRepo.GetConversation(ctx, conversationID) + if err != nil { + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + if !exist { + return errors.BadRequest(reason.ObjectNotFound) + } + + content := strings.Builder{} + + for _, record := range records { + if len(record.ChatCompletionID) > 0 { + continue + } + if record.Role == "user" { + aiRecord := &entity.AIConversationRecord{ + ConversationID: conversationID, + ChatCompletionID: chatcmplID, + Role: "user", + Content: record.Content, + } + + err = s.aiConversationRepo.CreateRecord(ctx, aiRecord) + if err != nil { + log.Errorf("create conversation record failed: %v", err) + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + continue + } + + content.WriteString(record.Content) + content.WriteString("\n") + } + aiRecord := &entity.AIConversationRecord{ + ConversationID: conversationID, + ChatCompletionID: chatcmplID, + Role: "assistant", + Content: content.String(), + Helpful: 0, + Unhelpful: 0, + } + + err = s.aiConversationRepo.CreateRecord(ctx, aiRecord) + if err != nil { + log.Errorf("create conversation record failed: %v", err) + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + + conversation.UpdatedAt = time.Now() + err = s.aiConversationRepo.UpdateConversation(ctx, conversation) + if err != nil { + log.Errorf("update conversation failed: %v", err) + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + + return nil +} + +// GetConversationList +func (s *aiConversationService) GetConversationList(ctx context.Context, req *schema.AIConversationListReq) (*pager.PageModel, error) { + conversations, total, err := s.aiConversationRepo.GetConversationsPage(ctx, req.Page, req.PageSize, &entity.AIConversation{UserID: req.UserID}) + if err != nil { + return nil, errors.InternalServer(reason.DatabaseError).WithError(err) + } + + list := make([]schema.AIConversationListItem, 0, len(conversations)) + for _, conversation := range conversations { + list = append(list, schema.AIConversationListItem{ + ConversationID: conversation.ConversationID, + CreatedAt: conversation.CreatedAt.Unix(), + Topic: conversation.Topic, + }) + } + + return pager.NewPageModel(total, list), nil +} + +// GetConversationDetail +func (s *aiConversationService) GetConversationDetail(ctx context.Context, req *schema.AIConversationDetailReq) ( + resp *schema.AIConversationDetailResp, exist bool, err error) { + conversation, exist, err := s.aiConversationRepo.GetConversation(ctx, req.ConversationID) + if err != nil { + return nil, false, errors.InternalServer(reason.DatabaseError).WithError(err) + } + if !exist || conversation.UserID != req.UserID { + return nil, false, nil + } + + records, err := s.aiConversationRepo.GetRecordsByConversationID(ctx, req.ConversationID) + if err != nil { + return nil, false, errors.InternalServer(reason.DatabaseError).WithError(err) + } + + recordList := make([]*schema.AIConversationRecord, 0, len(records)) + for i, record := range records { + if i == 0 { + record.Content = conversation.Topic + } + recordList = append(recordList, &schema.AIConversationRecord{ + ChatCompletionID: record.ChatCompletionID, + Role: record.Role, + Content: record.Content, + Helpful: record.Helpful, + Unhelpful: record.Unhelpful, + CreatedAt: record.CreatedAt.Unix(), + }) + } + + return &schema.AIConversationDetailResp{ + ConversationID: conversation.ConversationID, + Topic: conversation.Topic, + Records: recordList, + CreatedAt: conversation.CreatedAt.Unix(), + UpdatedAt: conversation.UpdatedAt.Unix(), + }, true, nil +} + +// VoteRecord +func (s *aiConversationService) VoteRecord(ctx context.Context, req *schema.AIConversationVoteReq) error { + record, exist, err := s.aiConversationRepo.GetRecordByChatCompletionID(ctx, "assistant", req.ChatCompletionID) + if err != nil { + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + if !exist { + return errors.BadRequest(reason.ObjectNotFound) + } + + conversation, exist, err := s.aiConversationRepo.GetConversation(ctx, record.ConversationID) + if err != nil { + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + if !exist { + return errors.BadRequest(reason.ObjectNotFound) + } + + if conversation.UserID != req.UserID { + return errors.Forbidden(reason.UnauthorizedError) + } + + if record.Role != "assistant" { + return errors.BadRequest("Only AI responses can be voted") + } + + if req.VoteType == "helpful" { + if req.Cancel { + record.Helpful = 0 + } else { + record.Helpful = 1 + record.Unhelpful = 0 + } + } else { + if req.Cancel { + record.Unhelpful = 0 + } else { + record.Unhelpful = 1 + record.Helpful = 0 + } + } + + err = s.aiConversationRepo.UpdateRecordVote(ctx, record) + if err != nil { + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + + return nil +} + +// GetConversationListForAdmin +func (s *aiConversationService) GetConversationListForAdmin( + ctx context.Context, req *schema.AIConversationAdminListReq) (*pager.PageModel, error) { + conversations, total, err := s.aiConversationRepo.GetConversationsForAdmin(ctx, req.Page, req.PageSize, &entity.AIConversation{}) + if err != nil { + return nil, errors.InternalServer(reason.DatabaseError).WithError(err) + } + + list := make([]*schema.AIConversationAdminListItem, 0, len(conversations)) + for _, conversation := range conversations { + userInfo, err := s.getUserInfo(ctx, conversation.UserID) + if err != nil { + log.Errorf("get user info failed for user %s: %v", conversation.UserID, err) + continue + } + + helpful, unhelpful, err := s.aiConversationRepo.GetConversationWithVoteStats(ctx, conversation.ConversationID) + if err != nil { + log.Errorf("get conversation vote stats failed for conversation %s: %v", conversation.ConversationID, err) + continue + } + + list = append(list, &schema.AIConversationAdminListItem{ + ID: conversation.ConversationID, + Topic: conversation.Topic, + UserInfo: userInfo, + HelpfulCount: helpful, + UnhelpfulCount: unhelpful, + CreatedAt: conversation.CreatedAt.Unix(), + }) + } + + return pager.NewPageModel(total, list), nil +} + +// GetConversationDetailForAdmin +func (s *aiConversationService) GetConversationDetailForAdmin(ctx context.Context, req *schema.AIConversationAdminDetailReq) (*schema.AIConversationAdminDetailResp, error) { + conversation, exist, err := s.aiConversationRepo.GetConversation(ctx, req.ConversationID) + if err != nil { + return nil, errors.InternalServer(reason.DatabaseError).WithError(err) + } + if !exist { + return nil, errors.BadRequest(reason.ObjectNotFound) + } + + userInfo, err := s.getUserInfo(ctx, conversation.UserID) + if err != nil { + return nil, errors.InternalServer(reason.DatabaseError).WithError(err) + } + + records, err := s.aiConversationRepo.GetRecordsByConversationID(ctx, req.ConversationID) + if err != nil { + return nil, errors.InternalServer(reason.DatabaseError).WithError(err) + } + + recordList := make([]schema.AIConversationRecord, 0, len(records)) + for i, record := range records { + if i == 0 { + record.Content = conversation.Topic + } + recordList = append(recordList, schema.AIConversationRecord{ + ChatCompletionID: record.ChatCompletionID, + Role: record.Role, + Content: record.Content, + Helpful: record.Helpful, + Unhelpful: record.Unhelpful, + CreatedAt: record.CreatedAt.Unix(), + }) + } + + return &schema.AIConversationAdminDetailResp{ + ConversationID: conversation.ConversationID, + Topic: conversation.Topic, + UserInfo: userInfo, + Records: recordList, + CreatedAt: conversation.CreatedAt.Unix(), + }, nil +} + +// getUserInfo +func (s *aiConversationService) getUserInfo(ctx context.Context, userID string) (schema.AIConversationUserInfo, error) { + userInfo := schema.AIConversationUserInfo{} + + user, exist, err := s.userCommon.GetUserBasicInfoByID(ctx, userID) + if err != nil { + return userInfo, err + } + if !exist { + return userInfo, errors.BadRequest(reason.ObjectNotFound) + } + + userInfo.ID = user.ID + userInfo.Username = user.Username + userInfo.DisplayName = user.DisplayName + userInfo.Avatar = user.Avatar + userInfo.Rank = user.Rank + return userInfo, nil +} + +// DeleteConversationForAdmin +func (s *aiConversationService) DeleteConversationForAdmin(ctx context.Context, req *schema.AIConversationAdminDeleteReq) error { + _, exist, err := s.aiConversationRepo.GetConversation(ctx, req.ConversationID) + if err != nil { + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + if !exist { + return errors.BadRequest(reason.ObjectNotFound) + } + + if err := s.aiConversationRepo.DeleteConversation(ctx, req.ConversationID); err != nil { + return err + } + + return nil +} diff --git a/internal/service/apikey/apikey_service.go b/internal/service/apikey/apikey_service.go new file mode 100644 index 000000000..43c1294ce --- /dev/null +++ b/internal/service/apikey/apikey_service.go @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package apikey + +import ( + "context" + "strings" + "time" + + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/schema" + "github.com/apache/answer/pkg/token" +) + +type APIKeyRepo interface { + GetAPIKeyList(ctx context.Context) (keys []*entity.APIKey, err error) + GetAPIKey(ctx context.Context, apiKey string) (key *entity.APIKey, exist bool, err error) + UpdateAPIKey(ctx context.Context, apiKey entity.APIKey) (err error) + AddAPIKey(ctx context.Context, apiKey entity.APIKey) (err error) + DeleteAPIKey(ctx context.Context, id int) (err error) +} + +type APIKeyService struct { + apiKeyRepo APIKeyRepo +} + +func NewAPIKeyService( + apiKeyRepo APIKeyRepo, +) *APIKeyService { + return &APIKeyService{ + apiKeyRepo: apiKeyRepo, + } +} + +func (s *APIKeyService) GetAPIKeyList(ctx context.Context, req *schema.GetAPIKeyReq) (resp []*schema.GetAPIKeyResp, err error) { + keys, err := s.apiKeyRepo.GetAPIKeyList(ctx) + if err != nil { + return nil, err + } + resp = make([]*schema.GetAPIKeyResp, 0) + for _, key := range keys { + // hide access key middle part, replace with * + if len(key.AccessKey) < 10 { + // If the access key is too short, do not mask it + key.AccessKey = strings.Repeat("*", len(key.AccessKey)) + } else { + key.AccessKey = key.AccessKey[:7] + strings.Repeat("*", 8) + key.AccessKey[len(key.AccessKey)-4:] + } + + resp = append(resp, &schema.GetAPIKeyResp{ + ID: key.ID, + AccessKey: key.AccessKey, + Description: key.Description, + Scope: key.Scope, + CreatedAt: key.CreatedAt.Unix(), + LastUsedAt: key.LastUsedAt.Unix(), + }) + } + return resp, nil +} + +func (s *APIKeyService) UpdateAPIKey(ctx context.Context, req *schema.UpdateAPIKeyReq) (err error) { + apiKey := entity.APIKey{ + ID: req.ID, + Description: req.Description, + } + err = s.apiKeyRepo.UpdateAPIKey(ctx, apiKey) + if err != nil { + return err + } + return nil +} + +func (s *APIKeyService) AddAPIKey(ctx context.Context, req *schema.AddAPIKeyReq) (resp *schema.AddAPIKeyResp, err error) { + ak := "sk_" + strings.ReplaceAll(token.GenerateToken(), "-", "") + apiKey := entity.APIKey{ + Description: req.Description, + AccessKey: ak, + Scope: req.Scope, + LastUsedAt: time.Now(), + UserID: req.UserID, + } + err = s.apiKeyRepo.AddAPIKey(ctx, apiKey) + if err != nil { + return nil, err + } + resp = &schema.AddAPIKeyResp{ + AccessKey: apiKey.AccessKey, + } + return resp, nil +} + +func (s *APIKeyService) DeleteAPIKey(ctx context.Context, req *schema.DeleteAPIKeyReq) (err error) { + err = s.apiKeyRepo.DeleteAPIKey(ctx, req.ID) + if err != nil { + return err + } + return nil +} diff --git a/internal/service/feature_toggle/feature_toggle_service.go b/internal/service/feature_toggle/feature_toggle_service.go new file mode 100644 index 000000000..b5bdad541 --- /dev/null +++ b/internal/service/feature_toggle/feature_toggle_service.go @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package feature_toggle + +import ( + "context" + "encoding/json" + + "github.com/apache/answer/internal/base/constant" + "github.com/apache/answer/internal/base/reason" + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/service/siteinfo_common" + "github.com/segmentfault/pacman/errors" +) + +// Feature keys +const ( + FeatureBadge = "badge" + FeatureCustomDomain = "custom_domain" + FeatureMCP = "mcp" + FeaturePrivateAPI = "private_api" + FeatureAIChatbot = "ai_chatbot" + FeatureArticle = "article" + FeatureCategory = "category" +) + +type toggleConfig struct { + Toggles map[string]bool `json:"toggles"` +} + +// FeatureToggleService persist and query feature switches. +type FeatureToggleService struct { + siteInfoRepo siteinfo_common.SiteInfoRepo +} + +// NewFeatureToggleService creates a new feature toggle service instance. +func NewFeatureToggleService(siteInfoRepo siteinfo_common.SiteInfoRepo) *FeatureToggleService { + return &FeatureToggleService{ + siteInfoRepo: siteInfoRepo, + } +} + +// UpdateAll overwrites the feature toggle configuration. +func (s *FeatureToggleService) UpdateAll(ctx context.Context, toggles map[string]bool) error { + cfg := &toggleConfig{ + Toggles: sanitizeToggleMap(toggles), + } + + data, err := json.Marshal(cfg) + if err != nil { + return err + } + + info := &entity.SiteInfo{ + Type: constant.SiteTypeFeatureToggle, + Content: string(data), + Status: 1, + } + + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeFeatureToggle, info) +} + +// GetAll returns all feature toggles. +func (s *FeatureToggleService) GetAll(ctx context.Context) (map[string]bool, error) { + siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeFeatureToggle, true) + if err != nil { + return nil, err + } + if !exist || siteInfo == nil || siteInfo.Content == "" { + return map[string]bool{}, nil + } + + cfg := &toggleConfig{} + if err := json.Unmarshal([]byte(siteInfo.Content), cfg); err != nil { + return map[string]bool{}, err + } + return sanitizeToggleMap(cfg.Toggles), nil +} + +// IsEnabled returns whether a feature is enabled. Missing config defaults to true. +func (s *FeatureToggleService) IsEnabled(ctx context.Context, feature string) (bool, error) { + toggles, err := s.GetAll(ctx) + if err != nil { + return false, err + } + if len(toggles) == 0 { + return true, nil + } + value, ok := toggles[feature] + if !ok { + return true, nil + } + return value, nil +} + +// EnsureEnabled returns error if feature disabled. +func (s *FeatureToggleService) EnsureEnabled(ctx context.Context, feature string) error { + enabled, err := s.IsEnabled(ctx, feature) + if err != nil { + return err + } + if !enabled { + return errors.BadRequest(reason.ErrFeatureDisabled) + } + return nil +} + +func sanitizeToggleMap(in map[string]bool) map[string]bool { + if in == nil { + return map[string]bool{} + } + return in +} diff --git a/internal/service/mock/siteinfo_repo_mock.go b/internal/service/mock/siteinfo_repo_mock.go index 0a1b31e84..e4e89d28e 100644 --- a/internal/service/mock/siteinfo_repo_mock.go +++ b/internal/service/mock/siteinfo_repo_mock.go @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + // Code generated by MockGen. DO NOT EDIT. // Source: ./siteinfo_service.go // @@ -43,9 +62,13 @@ func (m *MockSiteInfoRepo) EXPECT() *MockSiteInfoRepoMockRecorder { } // GetByType mocks base method. -func (m *MockSiteInfoRepo) GetByType(ctx context.Context, siteType string) (*entity.SiteInfo, bool, error) { +func (m *MockSiteInfoRepo) GetByType(ctx context.Context, siteType string, withoutCache ...bool) (*entity.SiteInfo, bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByType", ctx, siteType) + varargs := []any{ctx, siteType} + for _, a := range withoutCache { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetByType", varargs...) ret0, _ := ret[0].(*entity.SiteInfo) ret1, _ := ret[1].(bool) ret2, _ := ret[2].(error) @@ -53,9 +76,10 @@ func (m *MockSiteInfoRepo) GetByType(ctx context.Context, siteType string) (*ent } // GetByType indicates an expected call of GetByType. -func (mr *MockSiteInfoRepoMockRecorder) GetByType(ctx, siteType any) *gomock.Call { +func (mr *MockSiteInfoRepoMockRecorder) GetByType(ctx, siteType any, withoutCache ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByType", reflect.TypeOf((*MockSiteInfoRepo)(nil).GetByType), ctx, siteType) + varargs := append([]any{ctx, siteType}, withoutCache...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByType", reflect.TypeOf((*MockSiteInfoRepo)(nil).GetByType), varargs...) } // IsBrandingFileUsed mocks base method. @@ -139,6 +163,21 @@ func (mr *MockSiteInfoCommonServiceMockRecorder) FormatListAvatar(ctx, userList return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FormatListAvatar", reflect.TypeOf((*MockSiteInfoCommonService)(nil).FormatListAvatar), ctx, userList) } +// GetSiteAI mocks base method. +func (m *MockSiteInfoCommonService) GetSiteAI(ctx context.Context) (*schema.SiteAIResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteAI", ctx) + ret0, _ := ret[0].(*schema.SiteAIResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteAI indicates an expected call of GetSiteAI. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteAI(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteAI", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteAI), ctx) +} + // GetSiteBranding mocks base method. func (m *MockSiteInfoCommonService) GetSiteBranding(ctx context.Context) (*schema.SiteBrandingResp, error) { m.ctrl.T.Helper() @@ -243,6 +282,21 @@ func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx any) *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLogin", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLogin), ctx) } +// GetSiteMCP mocks base method. +func (m *MockSiteInfoCommonService) GetSiteMCP(ctx context.Context) (*schema.SiteMCPResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteMCP", ctx) + ret0, _ := ret[0].(*schema.SiteMCPResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteMCP indicates an expected call of GetSiteMCP. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteMCP(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteMCP", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteMCP), ctx) +} + // GetSiteSeo mocks base method. func (m *MockSiteInfoCommonService) GetSiteSeo(ctx context.Context) (*schema.SiteSeoResp, error) { m.ctrl.T.Helper() diff --git a/internal/service/provider.go b/internal/service/provider.go index f6d954709..3e43b0ae0 100644 --- a/internal/service/provider.go +++ b/internal/service/provider.go @@ -24,7 +24,9 @@ import ( "github.com/apache/answer/internal/service/activity" "github.com/apache/answer/internal/service/activity_common" "github.com/apache/answer/internal/service/activityqueue" + "github.com/apache/answer/internal/service/ai_conversation" answercommon "github.com/apache/answer/internal/service/answer_common" + "github.com/apache/answer/internal/service/apikey" "github.com/apache/answer/internal/service/auth" "github.com/apache/answer/internal/service/badge" "github.com/apache/answer/internal/service/collection" @@ -36,6 +38,7 @@ import ( "github.com/apache/answer/internal/service/dashboard" "github.com/apache/answer/internal/service/eventqueue" "github.com/apache/answer/internal/service/export" + "github.com/apache/answer/internal/service/feature_toggle" "github.com/apache/answer/internal/service/file_record" "github.com/apache/answer/internal/service/follow" "github.com/apache/answer/internal/service/importer" @@ -128,4 +131,7 @@ var ProviderSetService = wire.NewSet( badge.NewBadgeGroupService, importer.NewImporterService, file_record.NewFileRecordService, + apikey.NewAPIKeyService, + ai_conversation.NewAIConversationService, + feature_toggle.NewFeatureToggleService, ) diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index 1eb187067..38144a95a 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -39,7 +39,9 @@ import ( "github.com/apache/answer/internal/service/siteinfo_common" tagcommon "github.com/apache/answer/internal/service/tag_common" "github.com/apache/answer/plugin" + "github.com/go-resty/resty/v2" "github.com/jinzhu/copier" + "github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/log" ) @@ -275,6 +277,154 @@ func (s *SiteInfoService) SaveSiteUsers(ctx context.Context, req *schema.SiteUse return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeUsers, data) } +// GetSiteAI get site AI configuration +func (s *SiteInfoService) GetSiteAI(ctx context.Context) (resp *schema.SiteAIResp, err error) { + resp, err = s.siteInfoCommonService.GetSiteAI(ctx) + if err != nil { + return nil, err + } + aiProvider, err := s.GetAIProvider(ctx) + if err != nil { + return nil, err + } + providerMapping := make(map[string]*schema.SiteAIProvider) + for _, provider := range resp.SiteAIProviders { + providerMapping[provider.Provider] = provider + } + providers := make([]*schema.SiteAIProvider, 0) + for _, p := range aiProvider { + if provider, ok := providerMapping[p.Name]; ok { + providers = append(providers, provider) + } else { + providers = append(providers, &schema.SiteAIProvider{ + Provider: p.Name, + }) + } + } + resp.SiteAIProviders = providers + s.maskAIKeys(resp) + return resp, nil +} + +// SaveSiteAI save site AI configuration +func (s *SiteInfoService) SaveSiteAI(ctx context.Context, req *schema.SiteAIReq) (err error) { + if err := s.restoreMaskedAIKeys(ctx, req); err != nil { + return err + } + if req.PromptConfig == nil { + req.PromptConfig = &schema.AIPromptConfig{ + ZhCN: constant.DefaultAIPromptConfigZhCN, + EnUS: constant.DefaultAIPromptConfigEnUS, + } + } + + aiProvider, err := s.GetAIProvider(ctx) + if err != nil { + return err + } + + providerMapping := make(map[string]*schema.SiteAIProvider) + for _, provider := range req.SiteAIProviders { + providerMapping[provider.Provider] = provider + } + + providers := make([]*schema.SiteAIProvider, 0) + for _, p := range aiProvider { + if provider, ok := providerMapping[p.Name]; ok { + if len(provider.APIHost) == 0 && provider.Provider == req.ChosenProvider { + provider.APIHost = p.DefaultAPIHost + } + providers = append(providers, provider) + } else { + providers = append(providers, &schema.SiteAIProvider{ + Provider: p.Name, + APIHost: p.DefaultAPIHost, + }) + } + } + req.SiteAIProviders = providers + + content, _ := json.Marshal(req) + siteInfo := &entity.SiteInfo{ + Type: constant.SiteTypeAI, + Content: string(content), + Status: 1, + } + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeAI, siteInfo) +} + +func (s *SiteInfoService) maskAIKeys(resp *schema.SiteAIResp) { + for _, provider := range resp.SiteAIProviders { + if provider.APIKey == "" { + continue + } + provider.APIKey = strings.Repeat("*", len(provider.APIKey)) + } +} + +func (s *SiteInfoService) restoreMaskedAIKeys(ctx context.Context, req *schema.SiteAIReq) error { + hasMasked := false + for _, provider := range req.SiteAIProviders { + if provider.APIKey != "" && isAllMask(provider.APIKey) { + hasMasked = true + break + } + } + if !hasMasked { + return nil + } + + current, err := s.siteInfoCommonService.GetSiteAI(ctx) + if err != nil { + return err + } + currentMapping := make(map[string]*schema.SiteAIProvider) + for _, provider := range current.SiteAIProviders { + currentMapping[provider.Provider] = provider + } + for _, provider := range req.SiteAIProviders { + if provider.APIKey == "" || !isAllMask(provider.APIKey) { + continue + } + if stored, ok := currentMapping[provider.Provider]; ok { + provider.APIKey = stored.APIKey + } + } + return nil +} + +func isAllMask(value string) bool { + return strings.Trim(value, "*") == "" +} + +// GetSiteMCP get site MCP configuration +func (s *SiteInfoService) GetSiteMCP(ctx context.Context) (resp *schema.SiteMCPResp, err error) { + resp, err = s.siteInfoCommonService.GetSiteMCP(ctx) + if err != nil { + return nil, err + } + siteInfo, err := s.GetSiteGeneral(ctx) + if err != nil { + return nil, err + } + + resp.Type = "Server-Sent Event (SSE)" + resp.URL = fmt.Sprintf("%s/answer/api/v1/mcp/sse", siteInfo.SiteUrl) + resp.HTTPHeader = "Authorization={key}" + return +} + +// SaveSiteMCP save site MCP configuration +func (s *SiteInfoService) SaveSiteMCP(ctx context.Context, req *schema.SiteMCPReq) (err error) { + content, _ := json.Marshal(req) + siteInfo := &entity.SiteInfo{ + Type: constant.SiteTypeMCP, + Content: string(content), + Status: 1, + } + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeMCP, siteInfo) +} + // GetSMTPConfig get smtp config func (s *SiteInfoService) GetSMTPConfig(ctx context.Context) (resp *schema.GetSMTPConfigResp, err error) { emailConfig, err := s.emailService.GetEmailConfig(ctx) @@ -488,3 +638,76 @@ func (s *SiteInfoService) CleanUpRemovedBrandingFiles( } return nil } + +func (s *SiteInfoService) GetAIProvider(ctx context.Context) (resp []*schema.GetAIProviderResp, err error) { + resp = make([]*schema.GetAIProviderResp, 0) + aiProviderConfig, err := s.configService.GetStringValue(context.TODO(), constant.AIConfigProvider) + if err != nil { + log.Error(err) + return resp, nil + } + + _ = json.Unmarshal([]byte(aiProviderConfig), &resp) + return resp, nil +} + +func (s *SiteInfoService) GetAIModels(ctx context.Context, req *schema.GetAIModelsReq) (resp []*schema.GetAIModelResp, err error) { + resp = make([]*schema.GetAIModelResp, 0) + if req.APIKey != "" && isAllMask(req.APIKey) { + storedKey, err := s.getStoredAIKey(ctx, req.APIHost) + if err != nil { + return resp, err + } + if storedKey == "" { + return resp, errors.BadRequest("api_key is required") + } + req.APIKey = storedKey + } + + r := resty.New() + r.SetHeader("Authorization", fmt.Sprintf("Bearer %s", req.APIKey)) + r.SetHeader("Content-Type", "application/json") + respBody, err := r.R().Get(req.APIHost + "/v1/models") + if err != nil { + log.Error(err) + return resp, errors.BadRequest(fmt.Sprintf("failed to get AI models %s", err.Error())) + } + if !respBody.IsSuccess() { + log.Error(fmt.Sprintf("failed to get AI models, status code: %d, body: %s", respBody.StatusCode(), respBody.String())) + return resp, errors.BadRequest(fmt.Sprintf("failed to get AI models, response: %s", respBody.String())) + } + + data := schema.GetAIModelsResp{} + _ = json.Unmarshal(respBody.Body(), &data) + + for _, model := range data.Data { + resp = append(resp, &schema.GetAIModelResp{ + Id: model.Id, + Object: model.Object, + Created: model.Created, + OwnedBy: model.OwnedBy, + }) + } + return resp, nil +} + +func (s *SiteInfoService) getStoredAIKey(ctx context.Context, apiHost string) (string, error) { + current, err := s.siteInfoCommonService.GetSiteAI(ctx) + if err != nil { + return "", err + } + apiHost = strings.TrimRight(apiHost, "/") + for _, provider := range current.SiteAIProviders { + if strings.TrimRight(provider.APIHost, "/") == apiHost && provider.APIKey != "" { + return provider.APIKey, nil + } + } + if current.ChosenProvider != "" { + for _, provider := range current.SiteAIProviders { + if provider.Provider == current.ChosenProvider { + return provider.APIKey, nil + } + } + } + return "", nil +} diff --git a/internal/service/siteinfo_common/siteinfo_service.go b/internal/service/siteinfo_common/siteinfo_service.go index 8a4b13669..e81e7fe49 100644 --- a/internal/service/siteinfo_common/siteinfo_service.go +++ b/internal/service/siteinfo_common/siteinfo_service.go @@ -34,7 +34,7 @@ import ( //go:generate mockgen -source=./siteinfo_service.go -destination=../mock/siteinfo_repo_mock.go -package=mock type SiteInfoRepo interface { SaveByType(ctx context.Context, siteType string, data *entity.SiteInfo) (err error) - GetByType(ctx context.Context, siteType string) (siteInfo *entity.SiteInfo, exist bool, err error) + GetByType(ctx context.Context, siteType string, withoutCache ...bool) (siteInfo *entity.SiteInfo, exist bool, err error) IsBrandingFileUsed(ctx context.Context, filePath string) (bool, error) } @@ -58,6 +58,8 @@ type SiteInfoCommonService interface { GetSiteSeo(ctx context.Context) (resp *schema.SiteSeoResp, err error) GetSiteInfoByType(ctx context.Context, siteType string, resp any) (err error) IsBrandingFileUsed(ctx context.Context, filePath string) bool + GetSiteAI(ctx context.Context) (resp *schema.SiteAIResp, err error) + GetSiteMCP(ctx context.Context) (resp *schema.SiteMCPResp, err error) } // NewSiteInfoCommonService new site info common service @@ -249,3 +251,21 @@ func (s *siteInfoCommonService) IsBrandingFileUsed(ctx context.Context, filePath } return used } + +// GetSiteAI get site AI configuration +func (s *siteInfoCommonService) GetSiteAI(ctx context.Context) (resp *schema.SiteAIResp, err error) { + resp = &schema.SiteAIResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeAI, resp); err != nil { + return nil, err + } + return resp, nil +} + +// GetSiteMCP get site AI configuration +func (s *siteInfoCommonService) GetSiteMCP(ctx context.Context) (resp *schema.SiteMCPResp, err error) { + resp = &schema.SiteMCPResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeMCP, resp); err != nil { + return nil, err + } + return resp, nil +} From dc7f75212845dc851e95fe6cb7f2e19b9faf8550 Mon Sep 17 00:00:00 2001 From: dashuai Date: Fri, 23 Jan 2026 17:12:26 +0800 Subject: [PATCH 80/92] Support AI Assistant and MCP functions (#1477) 1. Add AI assistant-related business. 2. Add Mcp related configuration in the management background --- i18n/en_US.yaml | 79 +++ i18n/zh_CN.yaml | 79 +++ ui/package.json | 1 + ui/pnpm-lock.yaml | 13 + ui/src/common/constants.ts | 10 + ui/src/common/interface.ts | 71 +++ ui/src/components/BubbleAi/index.tsx | 259 ++++++++++ ui/src/components/BubbleUser/index.scss | 25 + ui/src/components/BubbleUser/index.tsx | 37 ++ ui/src/components/Modal/Modal.tsx | 6 +- ui/src/components/Sender/index.scss | 38 ++ ui/src/components/Sender/index.tsx | 172 +++++++ ui/src/components/SideNav/index.tsx | 14 +- ui/src/components/index.ts | 6 + .../AiAssistant/components/Action/index.tsx | 71 +++ .../components/DetailModal/index.tsx | 86 ++++ ui/src/pages/Admin/AiAssistant/index.tsx | 130 +++++ ui/src/pages/Admin/AiSettings/index.tsx | 486 ++++++++++++++++++ .../Admin/Apikeys/components/Action/index.tsx | 77 +++ .../components/AddOrEditModal/index.tsx | 184 +++++++ .../Apikeys/components/CreatedModal/index.tsx | 55 ++ .../pages/Admin/Apikeys/components/index.ts | 24 + ui/src/pages/Admin/Apikeys/index.tsx | 138 +++++ ui/src/pages/Admin/Mcp/index.tsx | 113 ++++ ui/src/pages/Admin/QaSettings/index.tsx | 19 + ui/src/pages/Admin/Security/index.tsx | 19 + ui/src/pages/Admin/TagsSettings/index.tsx | 19 + ui/src/pages/Admin/UsersSettings/index.tsx | 19 + .../components/ConversationList/index.tsx | 69 +++ ui/src/pages/AiAssistant/index.tsx | 380 ++++++++++++++ ui/src/pages/Questions/Ask/index.tsx | 6 +- ui/src/pages/Questions/EditAnswer/index.tsx | 8 +- .../pages/Search/components/AiCard/index.tsx | 170 ++++++ ui/src/pages/Search/components/index.ts | 3 +- ui/src/pages/Search/index.tsx | 4 + .../SideNavLayoutWithoutFooter/index.tsx | 46 ++ ui/src/pages/Tags/Create/index.tsx | 8 +- ui/src/pages/Tags/Edit/index.tsx | 8 +- ui/src/router/routes.ts | 36 ++ ui/src/services/admin/ai.ts | 87 ++++ ui/src/services/admin/apikeys.ts | 51 ++ ui/src/services/admin/index.ts | 3 + ui/src/services/admin/mcp.ts | 35 ++ ui/src/services/client/ai.ts | 40 ++ ui/src/services/client/index.ts | 1 + ui/src/stores/aiControl.ts | 40 ++ ui/src/stores/index.ts | 2 + ui/src/utils/guard.ts | 4 + ui/src/utils/requestAi.ts | 300 +++++++++++ 49 files changed, 3533 insertions(+), 18 deletions(-) create mode 100644 ui/src/components/BubbleAi/index.tsx create mode 100644 ui/src/components/BubbleUser/index.scss create mode 100644 ui/src/components/BubbleUser/index.tsx create mode 100644 ui/src/components/Sender/index.scss create mode 100644 ui/src/components/Sender/index.tsx create mode 100644 ui/src/pages/Admin/AiAssistant/components/Action/index.tsx create mode 100644 ui/src/pages/Admin/AiAssistant/components/DetailModal/index.tsx create mode 100644 ui/src/pages/Admin/AiAssistant/index.tsx create mode 100644 ui/src/pages/Admin/AiSettings/index.tsx create mode 100644 ui/src/pages/Admin/Apikeys/components/Action/index.tsx create mode 100644 ui/src/pages/Admin/Apikeys/components/AddOrEditModal/index.tsx create mode 100644 ui/src/pages/Admin/Apikeys/components/CreatedModal/index.tsx create mode 100644 ui/src/pages/Admin/Apikeys/components/index.ts create mode 100644 ui/src/pages/Admin/Apikeys/index.tsx create mode 100644 ui/src/pages/Admin/Mcp/index.tsx create mode 100644 ui/src/pages/AiAssistant/components/ConversationList/index.tsx create mode 100644 ui/src/pages/AiAssistant/index.tsx create mode 100644 ui/src/pages/Search/components/AiCard/index.tsx create mode 100644 ui/src/pages/SideNavLayoutWithoutFooter/index.tsx create mode 100644 ui/src/services/admin/ai.ts create mode 100644 ui/src/services/admin/apikeys.ts create mode 100644 ui/src/services/admin/mcp.ts create mode 100644 ui/src/services/client/ai.ts create mode 100644 ui/src/stores/aiControl.ts create mode 100644 ui/src/utils/requestAi.ts diff --git a/i18n/en_US.yaml b/i18n/en_US.yaml index ea6073664..9a0d198b3 100644 --- a/i18n/en_US.yaml +++ b/i18n/en_US.yaml @@ -857,6 +857,16 @@ ui: http_403: HTTP Error 403 logout: Log Out posts: Posts + ai_assistant: AI Assistant + ai_assistant: + description: Got a question? Ask it and get answers, perspectives, and recommendations. + recent_conversations: Recent Conversations + show_more: Show more + new: New chat + ai_generate: AI-generated from posts and may not be accurate. + copy: Copy + ask_a_follow_up: Ask a follow-up + ask_placeholder: Ask a question notifications: title: Notifications inbox: Inbox @@ -1823,6 +1833,11 @@ ui: policies: Policies security: Security files: Files + apikeys: API Keys + intelligence: Intelligence + ai_assistant: AI Assistant + ai_settings: AI Settings + mcp: MCP website_welcome: Welcome to {{site_name}} user_center: login: Login @@ -2298,6 +2313,70 @@ ui: show_logs: Show logs status: Status title: Badges + apikeys: + title: API Keys + add_api_key: Add API Key + desc: Description + scope: Scope + key: Key + created: Created + last_used: Last used + add_or_edit_modal: + add_title: Add API Key + edit_title: Edit API Key + description: Description + description_required: Description is required. + scope: Scope + global: Global + read-only: Read-only + created_modal: + title: API key created + api_key: API key + description: This key will not be displayed again. Make sure you take a copy before continuing. + delete_modal: + title: Delete API Key + content: Any applications or scripts using this key will no longer be able to access the API. This is permanent! + ai_settings: + enabled: + label: AI enabled + check: Enable AI features + text: The AI model must be configured correctly before it can be used. + provider: + label: Provider + api_host: + label: API host + msg: API host is required + api_key: + label: API key + check: Check + check_success: "Connection successful." + msg: API key is required + model: + label: Model + msg: Model is required + add_success: AI settings updated successfully. + conversations: + topic: Topic + helpful: Helpful + unhelpful: Unhelpful + created: Created + action: Action + empty: No conversations found. + delete_modal: + title: Delete conversation + content: Are you sure you want to delete this conversation? This is permanent! + delete_success: Conversation deleted successfully. + mcp: + mcp_server: + label: MCP server + switch: Enabled + type: + label: Type + url: + label: URL + http_header: + label: HTTP header + text: Please replace {key} with the API Key. form: optional: (optional) empty: cannot be empty diff --git a/i18n/zh_CN.yaml b/i18n/zh_CN.yaml index 59ef41be5..07589872e 100644 --- a/i18n/zh_CN.yaml +++ b/i18n/zh_CN.yaml @@ -846,6 +846,16 @@ ui: http_403: HTTP 错误 403 logout: 退出 posts: 帖子 + ai_assistant: AI 助手 + ai_assistant: + description: 有问题吗?尽管提问,即可获得解答、不同观点及实用建议。 + recent_conversations: 最近的对话 + show_more: 展示更多 + new: 新建对话 + ai_generate: 由帖子生成的 AI 内容,可能并不准确。 + copy: 复制 + ask_a_follow_up: 继续提问 + ask_placeholder: 提出问题 notifications: title: 通知 inbox: 收件箱 @@ -1785,6 +1795,11 @@ ui: policies: 政策 security: 安全 files: 文件 + apikeys: API Keys + intelligence: 人工智能 + ai_assistant: AI 助手 + ai_settings: AI 设置 + mcp: MCP website_welcome: 欢迎来到 {{site_name}} user_center: login: 登录 @@ -2259,6 +2274,70 @@ ui: show_logs: 显示日志 status: 状态 title: 徽章 + apikeys: + title: API Keys + add_api_key: 添加 API Key + desc: 描述 + scope: 范围 + key: Key + created: 创建时间 + last_used: 最后使用时间 + add_or_edit_modal: + add_title: 添加 API Key + edit_title: 编辑 API Key + description: 描述 + description_required: 描述必填. + scope: 范围 + global: 全局 + read-only: 只读 + created_modal: + title: API key 创建成功 + api_key: API key + description: 此密钥将不会再显示。请确保在继续之前复制一份。 + delete_modal: + title: 删除 API Key + content: 任何使用此密钥的应用程序或脚本将无法再访问 API。这是永久性的! + ai_settings: + enabled: + label: AI 启用 + check: 启用 AI 功能 + text: AI 模型必须正确配置才能使用。 + provider: + label: 提供者 + api_host: + label: API 主机 + msg: API 主机必填 + api_key: + label: API Key + check: 校验 + check_success: "连接成功." + msg: API key 必填 + model: + label: 模型 + msg: 模型必填 + add_success: AI 设置已成功更新. + conversations: + topic: 话题 + helpful: 有用的 + unhelpful: 无用的 + created: 创建于 + action: 操作 + empty: 没有会话记录。 + delete_modal: + title: 删除对话 + content: 你确定要删除此对话吗?这是永久的! + delete_success: 对话删除成功. + mcp: + mcp_server: + label: MCP 服务 + switch: 启用 + type: + label: 类型 + url: + label: URL + http_header: + label: HTTP header + text: 请将 {key} 替换为 API Key。 form: optional: (选填) empty: 不能为空 diff --git a/ui/package.json b/ui/package.json index b88fc12da..5abd241ac 100644 --- a/ui/package.json +++ b/ui/package.json @@ -46,6 +46,7 @@ "react-router-dom": "^7.0.2", "semver": "^7.3.8", "swr": "^1.3.0", + "uuid": "13.0.0", "zustand": "^5.0.2" }, "devDependencies": { diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index 89a37ab16..2ae03d036 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -95,6 +95,9 @@ importers: swr: specifier: ^1.3.0 version: 1.3.0(react@18.3.1) + uuid: + specifier: 13.0.0 + version: 13.0.0 zustand: specifier: ^5.0.2 version: 5.0.2(@types/react@18.3.16)(immer@9.0.21)(react@18.3.1)(use-sync-external-store@1.6.0(react@18.3.1)) @@ -1608,24 +1611,28 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [glibc] '@swc/core-linux-arm64-musl@1.15.3': resolution: {integrity: sha512-j4SJniZ/qaZ5g8op+p1G9K1z22s/EYGg1UXIb3+Cg4nsxEpF5uSIGEE4mHUfA70L0BR9wKT2QF/zv3vkhfpX4g==} engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [musl] '@swc/core-linux-x64-gnu@1.15.3': resolution: {integrity: sha512-aKttAZnz8YB1VJwPQZtyU8Uk0BfMP63iDMkvjhJzRZVgySmqt/apWSdnoIcZlUoGheBrcqbMC17GGUmur7OT5A==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [glibc] '@swc/core-linux-x64-musl@1.15.3': resolution: {integrity: sha512-oe8FctPu1gnUsdtGJRO2rvOUIkkIIaHqsO9xxN0bTR7dFTlPTGi2Fhk1tnvXeyAvCPxLIcwD8phzKg6wLv9yug==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [musl] '@swc/core-win32-arm64-msvc@1.15.3': resolution: {integrity: sha512-L9AjzP2ZQ/Xh58e0lTRMLvEDrcJpR7GwZqAtIeNLcTK7JVE+QineSyHp0kLkO1rttCHyCy0U74kDTj0dRz6raA==} @@ -6690,6 +6697,10 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + uuid@13.0.0: + resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} + hasBin: true + uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -14894,6 +14905,8 @@ snapshots: utils-merge@1.0.1: {} + uuid@13.0.0: {} + uuid@8.3.2: {} v8-compile-cache-lib@3.0.1: {} diff --git a/ui/src/common/constants.ts b/ui/src/common/constants.ts index 285da4747..2e10f1494 100644 --- a/ui/src/common/constants.ts +++ b/ui/src/common/constants.ts @@ -102,6 +102,14 @@ export const ADMIN_NAV_MENUS = [ { name: 'tags', path: 'tags/settings', pathPrefix: 'tags/' }, ], }, + { + name: 'intelligence', + icon: 'robot', + children: [ + { name: 'ai_settings', path: 'ai-settings' }, + { name: 'ai_assistant', path: 'ai-assistant' }, + ], + }, { name: 'community', icon: 'people-fill', @@ -135,6 +143,8 @@ export const ADMIN_NAV_MENUS = [ { name: 'login' }, { name: 'seo' }, { name: 'smtp' }, + { name: 'apikeys' }, + { name: 'mcp' }, ], }, { diff --git a/ui/src/common/interface.ts b/ui/src/common/interface.ts index aac89cce2..308726e80 100644 --- a/ui/src/common/interface.ts +++ b/ui/src/common/interface.ts @@ -427,6 +427,7 @@ export interface SiteSettings { version: string; revision: string; site_security: AdminSettingsSecurity; + ai_enabled: boolean; } export interface AdminSettingBranding { @@ -809,6 +810,76 @@ export interface BadgeDetailListRes { list: BadgeDetailListItem[]; } +export interface AdminApiKeysItem { + access_key: string; + created_at: number; + description: string; + id: number; + last_used_at: number; + scope: string; +} + +export interface AddOrEditApiKeyParams { + description: string; + scope?: string; + id?: number; +} + +export interface AiConfig { + enabled: boolean; + chosen_provider: string; + ai_providers: Array<{ + provider: string; + api_host: string; + api_key: string; + model: string; + }>; +} + +export interface AiProviderItem { + name: string; + display_name: string; + default_api_host: string; +} + +export interface ConversationListItem { + conversation_id: string; + created_at: number; + topic: string; +} + +export interface AdminConversationListItem { + id: string; + topic: string; + helpful_count: number; + unhelpful_count: number; + created_at: number; + user_info: UserInfoBase; +} + +export interface ConversationDetailItem { + chat_completion_id: string; + content: string; + role: string; + helpful: number; + unhelpful: number; + created_at: number; +} + +export interface ConversationDetail { + conversation_id: string; + created_at: number; + records: ConversationDetailItem[]; + topic: string; + updated_at: number; +} + +export interface VoteConversationParams { + cancel: boolean; + chat_completion_id: string; + vote_type: 'helpful' | 'unhelpful'; +} + export interface AdminQuestionSetting { min_tags: number; min_content: number; diff --git a/ui/src/components/BubbleAi/index.tsx b/ui/src/components/BubbleAi/index.tsx new file mode 100644 index 000000000..453a61c5b --- /dev/null +++ b/ui/src/components/BubbleAi/index.tsx @@ -0,0 +1,259 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { FC, useEffect, useState, useRef } from 'react'; +import { Button } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; + +import { marked } from 'marked'; +import copy from 'copy-to-clipboard'; + +import { voteConversation } from '@/services'; +import { Icon, htmlRender } from '@/components'; + +interface IProps { + canType?: boolean; + chatId: string; + isLast: boolean; + isCompleted: boolean; + content: string; + minHeight?: number; + actionData: { + helpful: number; + unhelpful: number; + }; +} + +const BubbleAi: FC = ({ + canType = false, + isLast, + isCompleted, + content, + chatId = '', + actionData, + minHeight = 0, +}) => { + const { t } = useTranslation('translation', { keyPrefix: 'ai_assistant' }); + const [displayContent, setDisplayContent] = useState(''); + const [copyText, setCopyText] = useState(t('copy')); + const [isHelpful, setIsHelpful] = useState(false); + const [isUnhelpful, setIsUnhelpful] = useState(false); + const [canShowAction, setCanShowAction] = useState(false); + const typewriterRef = useRef<{ + timer: NodeJS.Timeout | null; + index: number; + isTyping: boolean; + }>({ + timer: null, + index: 0, + isTyping: false, + }); + const fmtContainer = useRef(null); + // add ref for ScrollIntoView + const containerRef = useRef(null); + + const handleCopy = () => { + const res = copy(displayContent); + if (res) { + setCopyText(t('copied', { keyPrefix: 'messages' })); + setTimeout(() => { + setCopyText(t('copy')); + }, 1200); + } + }; + + const handleVote = (voteType: 'helpful' | 'unhelpful') => { + const isCancel = + (voteType === 'helpful' && isHelpful) || + (voteType === 'unhelpful' && isUnhelpful); + voteConversation({ + chat_completion_id: chatId, + cancel: isCancel, + vote_type: voteType, + }).then(() => { + setIsHelpful(voteType === 'helpful' && !isCancel); + setIsUnhelpful(voteType === 'unhelpful' && !isCancel); + }); + }; + + useEffect(() => { + if ((!canType || !isLast) && content) { + // 如果不是最后一个消息,直接返回,不进行打字效果 + if (typewriterRef.current.timer) { + clearInterval(typewriterRef.current.timer); + typewriterRef.current.timer = null; + } + setDisplayContent(content); + setCanShowAction(true); + typewriterRef.current.timer = null; + typewriterRef.current.isTyping = false; + return; + } + // 当内容变化时,清理之前的计时器 + if (typewriterRef.current.timer) { + clearInterval(typewriterRef.current.timer); + typewriterRef.current.timer = null; + } + + // 如果内容为空,则直接返回 + if (!content) { + setDisplayContent(''); + return; + } + + // 如果内容比当前显示的短,则重置 + if (content.length < displayContent.length) { + setDisplayContent(''); + typewriterRef.current.index = 0; + } + + // 如果内容与显示内容相同,不需要做任何事 + if (content === displayContent) { + return; + } + + typewriterRef.current.isTyping = true; + + // start typing animation + typewriterRef.current.timer = setInterval(() => { + const currentIndex = typewriterRef.current.index; + if (currentIndex < content.length) { + const remainingLength = content.length - currentIndex; + const baseRandomNum = Math.floor(Math.random() * 3) + 2; + let randomNum = Math.min(baseRandomNum, remainingLength); + + // 简单的单词边界检查(可选) + const nextChar = content[currentIndex + randomNum]; + const prevChar = content[currentIndex + randomNum - 1]; + + // 如果下一个字符是字母,当前字符也是字母,尝试调整到空格处 + if ( + nextChar && + /[a-zA-Z]/.test(nextChar) && + /[a-zA-Z]/.test(prevChar) + ) { + // 向前找1-2个字符,看看有没有空格 + for ( + let i = 1; + i <= 2 && currentIndex + randomNum - i > currentIndex; + i += 1 + ) { + if (content[currentIndex + randomNum - i] === ' ') { + randomNum = randomNum - i + 1; + break; + } + } + // 向后找1-2个字符,看看有没有空格 + for ( + let i = 1; + i <= 2 && currentIndex + randomNum + i < content.length; + i += 1 + ) { + if (content[currentIndex + randomNum + i] === ' ') { + randomNum = randomNum + i + 1; + break; + } + } + } + + const nextIndex = currentIndex + randomNum; + const newContent = content.substring(0, nextIndex); + setDisplayContent(newContent); + typewriterRef.current.index = nextIndex; + setCanShowAction(false); + } else { + clearInterval(typewriterRef.current.timer as NodeJS.Timeout); + typewriterRef.current.timer = null; + typewriterRef.current.isTyping = false; + setCanShowAction(false); + } + }, 30); + + // eslint-disable-next-line consistent-return + return () => { + if (typewriterRef.current.timer) { + clearInterval(typewriterRef.current.timer); + typewriterRef.current.timer = null; + } + }; + }, [content, isCompleted]); + + useEffect(() => { + setIsHelpful(actionData.helpful > 0); + setIsUnhelpful(actionData.unhelpful > 0); + }, [actionData]); + + useEffect(() => { + if (fmtContainer.current && isCompleted) { + htmlRender(fmtContainer.current, { + copySuccessText: t('copied', { keyPrefix: 'messages' }), + copyText: t('copy', { keyPrefix: 'messages' }), + }); + const links = fmtContainer.current.querySelectorAll('a'); + links.forEach((link) => { + link.setAttribute('target', '_blank'); + }); + setCanShowAction(true); + } + }, [isCompleted, fmtContainer.current]); + + return ( +
    +
    +
    + + {canShowAction && ( +
    + + + +
    + )} +
    +
    + ); +}; + +export default BubbleAi; diff --git a/ui/src/components/BubbleUser/index.scss b/ui/src/components/BubbleUser/index.scss new file mode 100644 index 000000000..6606ac5e4 --- /dev/null +++ b/ui/src/components/BubbleUser/index.scss @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +.bubble-user-wrap { + scroll-margin-top: 88px; +} +.bubble-user { + background-color: var(--bs-gray-200); +} diff --git a/ui/src/components/BubbleUser/index.tsx b/ui/src/components/BubbleUser/index.tsx new file mode 100644 index 000000000..b6c52a743 --- /dev/null +++ b/ui/src/components/BubbleUser/index.tsx @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { FC } from 'react'; +import './index.scss'; + +interface BubbleUserProps { + content?: string; +} + +const BubbleUser: FC = ({ content }) => { + return ( +
    +
    + {content} +
    +
    + ); +}; + +export default BubbleUser; diff --git a/ui/src/components/Modal/Modal.tsx b/ui/src/components/Modal/Modal.tsx index cbf98c249..580d51daa 100644 --- a/ui/src/components/Modal/Modal.tsx +++ b/ui/src/components/Modal/Modal.tsx @@ -21,6 +21,8 @@ import React, { FC } from 'react'; import { Button, Modal } from 'react-bootstrap'; import { useTranslation } from 'react-i18next'; +import classNames from 'classnames'; + export interface Props { id?: string; /** header title */ @@ -77,7 +79,9 @@ const Index: FC = ({ {title || t('title', { keyPrefix: 'modal_confirm' })} - {children} + + {children} + {(showCancel || showConfirm) && ( {showCancel && ( diff --git a/ui/src/components/Sender/index.scss b/ui/src/components/Sender/index.scss new file mode 100644 index 000000000..32c12faa9 --- /dev/null +++ b/ui/src/components/Sender/index.scss @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +.sender-wrap { + z-index: 10; + margin-top: auto; + background-color: var(--bs-body-bg); + .input { + resize: none; + overflow-y: auto; + scrollbar-width: thin; + } + .input:focus { + box-shadow: none !important; + border-width: 0 !important; + } + + .form-control-focus { + box-shadow: 0 0 0 0.25rem rgba(0, 51, 255, 0.25) !important; + border-color: rgb(128, 153, 255) !important; + } +} diff --git a/ui/src/components/Sender/index.tsx b/ui/src/components/Sender/index.tsx new file mode 100644 index 000000000..e79cf9b2e --- /dev/null +++ b/ui/src/components/Sender/index.tsx @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { useEffect, useState, useRef, FC } from 'react'; +import { Form, Button } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; + +import classnames from 'classnames'; + +import { Icon } from '@/components'; + +import './index.scss'; + +interface IProps { + onSubmit?: (value: string) => void; + onCancel?: () => void; + isGenerate: boolean; + hasConversation: boolean; +} + +const Sender: FC = ({ + onSubmit, + onCancel, + isGenerate, + hasConversation, +}) => { + const { t } = useTranslation('translation', { keyPrefix: 'ai_assistant' }); + const containerRef = useRef(null); + const textareaRef = useRef(null); + const [initialized, setInitialized] = useState(false); + const [inputValue, setInputValue] = useState(''); + const [isFocus, setIsFocus] = useState(false); + + const handleFocus = () => { + setIsFocus(true); + textareaRef?.current?.focus(); + }; + + const handleBlur = () => { + setIsFocus(false); + }; + + const autoResize = () => { + const textarea = textareaRef.current; + if (!textarea) return; + + textarea.style.height = '32px'; + + const minHeight = 32; // minimum height + const maxHeight = 96; // maximum height + + // calculate the height needed + const { scrollHeight } = textarea; + const newHeight = Math.min(Math.max(scrollHeight, minHeight), maxHeight); + + // set the new height + textarea.style.height = `${newHeight}px`; + + // control the scrollbar display + if (scrollHeight > maxHeight) { + textarea.style.overflowY = 'auto'; + } else { + textarea.style.overflowY = 'hidden'; + } + }; + + const handleInputChange = (e: React.ChangeEvent) => { + setInputValue(e.target.value); + setTimeout(autoResize, 0); + }; + + const handleSubmit = () => { + if (isGenerate || !inputValue.trim()) { + return; + } + onSubmit?.(inputValue); + setInputValue(''); + }; + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter' && !e.shiftKey) { + e.preventDefault(); // Prevent default behavior of Enter key + handleSubmit(); + } else if (e.key === 'Escape') { + setInputValue((prev) => `${prev}\n`); // Add a new line on Escape key + } + }; + + useEffect(() => { + setInitialized(true); + }, []); + + useEffect(() => { + const handleOutsideClick = (event) => { + if ( + initialized && + containerRef.current && + !containerRef.current?.contains(event.target) + ) { + handleBlur(); + } + }; + document.addEventListener('click', handleOutsideClick); + return () => { + document.removeEventListener('click', handleOutsideClick); + }; + }, [initialized]); + return ( +
    +
    + +
    + {isGenerate ? ( + + ) : ( + + )} +
    +
    + + {t('ai_generate')} +
    + ); +}; + +export default Sender; diff --git a/ui/src/components/SideNav/index.tsx b/ui/src/components/SideNav/index.tsx index 294389a0b..54d2f6a47 100644 --- a/ui/src/components/SideNav/index.tsx +++ b/ui/src/components/SideNav/index.tsx @@ -22,7 +22,7 @@ import { Nav } from 'react-bootstrap'; import { NavLink, useLocation, useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; -import { loggedUserInfoStore, sideNavStore } from '@/stores'; +import { loggedUserInfoStore, sideNavStore, aiControlStore } from '@/stores'; import { Icon, PluginRender } from '@/components'; import { PluginType } from '@/utils/pluginKit'; import request from '@/utils/request'; @@ -34,6 +34,7 @@ const Index: FC = () => { const { pathname } = useLocation(); const { user: userInfo } = loggedUserInfoStore(); const { can_revision, revision } = sideNavStore(); + const { ai_enabled } = aiControlStore(); const navigate = useNavigate(); return ( @@ -47,6 +48,17 @@ const Index: FC = () => { {t('header.nav.question')} + {ai_enabled && ( + + pathname === '/ai-assistant' ? 'nav-link active' : 'nav-link' + }> + + {t('ai_assistant', { keyPrefix: 'page_title' })} + + )} + diff --git a/ui/src/components/index.ts b/ui/src/components/index.ts index 416db241c..5c81739bb 100644 --- a/ui/src/components/index.ts +++ b/ui/src/components/index.ts @@ -64,6 +64,9 @@ import CardBadge from './CardBadge'; import PinList from './PinList'; import MobileSideNav from './MobileSideNav'; import AdminSideNav from './AdminSideNav'; +import BubbleAi from './BubbleAi'; +import BubbleUser from './BubbleUser'; +import Sender from './Sender'; import TabNav from './TabNav'; export { @@ -116,6 +119,9 @@ export { PinList, MobileSideNav, AdminSideNav, + BubbleAi, + BubbleUser, + Sender, TabNav, }; export type { EditorRef, JSONSchema, UISchema }; diff --git a/ui/src/pages/Admin/AiAssistant/components/Action/index.tsx b/ui/src/pages/Admin/AiAssistant/components/Action/index.tsx new file mode 100644 index 000000000..c9702ea68 --- /dev/null +++ b/ui/src/pages/Admin/AiAssistant/components/Action/index.tsx @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { Dropdown } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; + +import { Modal, Icon } from '@/components'; +import { deleteAdminConversation } from '@/services'; +import { useToast } from '@/hooks'; + +interface Props { + id: string; + refreshList?: () => void; +} +const ConversationsOperation = ({ id, refreshList }: Props) => { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.conversations', + }); + const toast = useToast(); + + const handleAction = (eventKey: string | null) => { + if (eventKey === 'delete') { + Modal.confirm({ + title: t('delete_modal.title'), + content: t('delete_modal.content'), + cancelBtnVariant: 'link', + confirmBtnVariant: 'danger', + confirmText: t('delete', { keyPrefix: 'btns' }), + onConfirm: () => { + deleteAdminConversation(id).then(() => { + refreshList?.(); + toast.onShow({ + variant: 'success', + msg: t('delete_modal.delete_success'), + }); + }); + }, + }); + } + }; + + return ( + + + + + + + {t('delete', { keyPrefix: 'btns' })} + + + + ); +}; + +export default ConversationsOperation; diff --git a/ui/src/pages/Admin/AiAssistant/components/DetailModal/index.tsx b/ui/src/pages/Admin/AiAssistant/components/DetailModal/index.tsx new file mode 100644 index 000000000..ec4bd7d79 --- /dev/null +++ b/ui/src/pages/Admin/AiAssistant/components/DetailModal/index.tsx @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { FC, memo } from 'react'; +import { Button, Modal } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; + +import { BubbleAi, BubbleUser } from '@/components'; +import { useQueryAdminConversationDetail } from '@/services'; + +interface IProps { + visible: boolean; + id: string; + onClose?: () => void; +} + +const Index: FC = ({ visible, id, onClose }) => { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.conversations', + }); + + const { data: conversationDetail } = useQueryAdminConversationDetail(id); + + const handleClose = () => { + onClose?.(); + }; + return ( + + +
    + {conversationDetail?.topic} +
    +
    + + {conversationDetail?.records.map((item, index) => { + const isLastMessage = + index === Number(conversationDetail?.records.length) - 1; + return ( +
    + {item.role === 'user' ? ( + + ) : ( + + )} +
    + ); + })} +
    + + + +
    + ); +}; + +export default memo(Index); diff --git a/ui/src/pages/Admin/AiAssistant/index.tsx b/ui/src/pages/Admin/AiAssistant/index.tsx new file mode 100644 index 000000000..7fc3e9d9b --- /dev/null +++ b/ui/src/pages/Admin/AiAssistant/index.tsx @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { useState } from 'react'; +import { Table, Button } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; +import { useSearchParams } from 'react-router-dom'; + +import { BaseUserCard, FormatTime, Pagination, Empty } from '@/components'; +import { useQueryAdminConversationList } from '@/services'; + +import DetailModal from './components/DetailModal'; +import Action from './components/Action'; + +const Index = () => { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.conversations', + }); + const [urlSearchParams] = useSearchParams(); + const curPage = Number(urlSearchParams.get('page') || '1'); + const PAGE_SIZE = 20; + const [detailModal, setDetailModal] = useState({ + visible: false, + id: '', + }); + const { + data: conversations, + isLoading, + mutate: refreshList, + } = useQueryAdminConversationList({ + page: curPage, + page_size: PAGE_SIZE, + }); + + const handleShowDetailModal = (data) => { + setDetailModal({ + visible: true, + id: data.id, + }); + }; + + const handleHideDetailModal = () => { + setDetailModal({ + visible: false, + id: '', + }); + }; + + return ( +
    +

    {t('ai_assistant', { keyPrefix: 'nav_menus' })}

    +
    + + + + + + + + + + + {conversations?.list.map((item) => { + return ( + + + + + + + + ); + })} + +
    {t('topic')}{t('helpful')}{t('unhelpful')}{t('created')} + {t('action')} +
    + + {item.helpful_count}{item.unhelpful_count} +
    + + +
    +
    + +
    + {!isLoading && Number(conversations?.count) <= 0 && ( + {t('empty')} + )} + +
    + +
    + +
    + ); +}; +export default Index; diff --git a/ui/src/pages/Admin/AiSettings/index.tsx b/ui/src/pages/Admin/AiSettings/index.tsx new file mode 100644 index 000000000..2270aa5c5 --- /dev/null +++ b/ui/src/pages/Admin/AiSettings/index.tsx @@ -0,0 +1,486 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { useEffect, useState, useRef } from 'react'; +import { Form, InputGroup, Button } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; + +import { + getAiConfig, + useQueryAiProvider, + checkAiConfig, + saveAiConfig, +} from '@/services'; +import { aiControlStore } from '@/stores'; +import { handleFormError } from '@/utils'; +import { useToast } from '@/hooks'; +import * as Type from '@/common/interface'; + +const Index = () => { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.ai_settings', + }); + const toast = useToast(); + const historyConfigRef = useRef(); + // const [historyConfig, setHistoryConfig] = useState(); + const { data: aiProviders } = useQueryAiProvider(); + + const [formData, setFormData] = useState({ + enabled: { + value: false, + isInvalid: false, + errorMsg: '', + }, + provider: { + value: '', + isInvalid: false, + errorMsg: '', + }, + api_host: { + value: '', + isInvalid: false, + errorMsg: '', + }, + api_key: { + value: '', + isInvalid: false, + isValid: false, + errorMsg: '', + }, + model: { + value: '', + isInvalid: false, + errorMsg: '', + }, + }); + const [apiHostPlaceholder, setApiHostPlaceholder] = useState(''); + const [modelsData, setModels] = useState<{ id: string }[]>([]); + const [isChecking, setIsChecking] = useState(false); + + const getCurrentProviderData = (provider) => { + const findHistoryProvider = + historyConfigRef.current?.ai_providers.find( + (v) => v.provider === provider, + ) || historyConfigRef.current?.ai_providers[0]; + + return findHistoryProvider; + }; + + const checkAiConfigData = (data) => { + const params = data || { + api_host: formData.api_host.value || apiHostPlaceholder, + api_key: formData.api_key.value, + }; + setIsChecking(true); + + checkAiConfig(params) + .then((res) => { + setModels(res); + const findHistoryProvider = getCurrentProviderData( + formData.provider.value, + ); + + setIsChecking(false); + + if (!data) { + setFormData({ + ...formData, + api_key: { + ...formData.api_key, + errorMsg: t('api_key.check_success'), + isInvalid: false, + isValid: true, + }, + model: { + value: findHistoryProvider?.model || res[0].id, + errorMsg: '', + isInvalid: false, + }, + }); + } + }) + .catch((err) => { + console.error('Checking AI config:', err); + setIsChecking(false); + }); + }; + + const handleProviderChange = (value) => { + const findHistoryProvider = getCurrentProviderData(value); + setFormData({ + ...formData, + provider: { + value, + isInvalid: false, + errorMsg: '', + }, + api_host: { + value: findHistoryProvider?.api_host || '', + isInvalid: false, + errorMsg: '', + }, + api_key: { + value: findHistoryProvider?.api_key || '', + isInvalid: false, + isValid: false, + errorMsg: '', + }, + model: { + value: findHistoryProvider?.model || '', + isInvalid: false, + errorMsg: '', + }, + }); + const provider = aiProviders?.find((item) => item.name === value); + const host = findHistoryProvider?.api_host || provider?.default_api_host; + if (findHistoryProvider?.model) { + checkAiConfigData({ + api_host: host, + api_key: findHistoryProvider.api_key, + }); + } else { + setModels([]); + } + }; + + const handleValueChange = (value) => { + setFormData((prev) => ({ + ...prev, + ...value, + })); + }; + + const checkValidate = () => { + let bol = true; + + const { api_host, api_key, model } = formData; + + if (!api_host.value) { + bol = false; + formData.api_host = { + value: '', + isInvalid: true, + errorMsg: t('api_host.msg'), + }; + } + + if (!api_key.value) { + bol = false; + formData.api_key = { + value: '', + isInvalid: true, + isValid: false, + errorMsg: t('api_key.msg'), + }; + } + + if (!model.value) { + bol = false; + formData.model = { + value: '', + isInvalid: true, + errorMsg: t('model.msg'), + }; + } + + setFormData({ + ...formData, + }); + + return bol; + }; + + const handleSubmit = (e) => { + e.preventDefault(); + if (!checkValidate()) { + return; + } + const newProviders = historyConfigRef.current?.ai_providers.map((v) => { + if (v.provider === formData.provider.value) { + return { + provider: formData.provider.value, + api_host: formData.api_host.value, + api_key: formData.api_key.value, + model: formData.model.value, + }; + } + return v; + }); + + const params = { + enabled: formData.enabled.value, + chosen_provider: formData.provider.value, + ai_providers: newProviders, + }; + saveAiConfig(params) + .then(() => { + aiControlStore.getState().update({ + ai_enabled: formData.enabled.value, + }); + + historyConfigRef.current = { + ...params, + ai_providers: params.ai_providers || [], + }; + + toast.onShow({ + msg: t('add_success'), + variant: 'success', + }); + }) + .catch((err) => { + const data = handleFormError(err, formData); + setFormData({ ...data }); + const ele = document.getElementById(err.list[0].error_field); + ele?.scrollIntoView({ behavior: 'smooth', block: 'center' }); + }); + }; + + const getAiConfigData = async () => { + const aiConfig = await getAiConfig(); + historyConfigRef.current = aiConfig; + + const currentAiConfig = getCurrentProviderData(aiConfig.chosen_provider); + if (currentAiConfig?.model) { + const provider = aiProviders?.find( + (item) => item.name === formData.provider.value, + ); + const host = currentAiConfig.api_host || provider?.default_api_host; + checkAiConfigData({ + api_host: host, + api_key: currentAiConfig.api_key, + }); + } + + setFormData({ + enabled: { + value: aiConfig.enabled || false, + isInvalid: false, + errorMsg: '', + }, + provider: { + value: currentAiConfig?.provider || '', + isInvalid: false, + errorMsg: '', + }, + api_host: { + value: currentAiConfig?.api_host || '', + isInvalid: false, + errorMsg: '', + }, + api_key: { + value: currentAiConfig?.api_key || '', + isInvalid: false, + isValid: false, + errorMsg: '', + }, + model: { + value: currentAiConfig?.model || '', + isInvalid: false, + errorMsg: '', + }, + }); + }; + + useEffect(() => { + getAiConfigData(); + }, []); + + useEffect(() => { + if (formData.provider.value) { + const provider = aiProviders?.find( + (item) => item.name === formData.provider.value, + ); + if (provider) { + setApiHostPlaceholder(provider.default_api_host || ''); + } + } + if (!formData.provider.value && aiProviders) { + setFormData((prev) => ({ + ...prev, + provider: { + ...prev.provider, + value: aiProviders[0].name, + }, + })); + } + }, [aiProviders, formData]); + + return ( +
    +

    {t('ai_settings', { keyPrefix: 'nav_menus' })}

    +
    +
    + + {t('enabled.label')} + + handleValueChange({ + enabled: { + value: e.target.checked, + errorMsg: '', + isInvalid: false, + }, + }) + } + /> + {t('enabled.text')} + + {formData.enabled.errorMsg} + + + + + {t('provider.label')} + handleProviderChange(e.target.value)}> + {aiProviders?.map((provider) => ( + + ))} + + + {formData.provider.errorMsg} + + + + + {t('api_host.label')} + + handleValueChange({ + api_host: { + value: e.target.value, + errorMsg: '', + isInvalid: false, + }, + }) + } + /> + + {formData.api_host.errorMsg} + + + + + {t('api_key.label')} + + + handleValueChange({ + api_key: { + value: e.target.value, + errorMsg: '', + isInvalid: false, + isValid: false, + }, + }) + } + /> + + + {formData.api_key.errorMsg} + + + + +
    + + {/* + handleValueChange({ + model: { + value: e.target.value, + errorMsg: '', + isInvalid: false, + }, + }) + }> + {modelsData?.map((model) => { + return ( + + ); + })} + */} + + handleValueChange({ + model: { + value: e.target.value, + errorMsg: '', + isInvalid: false, + }, + }) + } + /> + + {modelsData?.map((model) => { + return ( + + ); + })} + + +
    {formData.model.errorMsg}
    +
    + + +
    +
    +
    + ); +}; +export default Index; diff --git a/ui/src/pages/Admin/Apikeys/components/Action/index.tsx b/ui/src/pages/Admin/Apikeys/components/Action/index.tsx new file mode 100644 index 000000000..f3a7cbcc6 --- /dev/null +++ b/ui/src/pages/Admin/Apikeys/components/Action/index.tsx @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Dropdown } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; + +import { Icon, Modal } from '@/components'; +import { deleteApiKey } from '@/services'; +import { toastStore } from '@/stores'; + +const ApiActions = ({ itemData, refreshList, showModal }) => { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.apikeys.delete_modal', + }); + + const handleAction = (type) => { + if (type === 'delete') { + Modal.confirm({ + title: t('title'), + content: t('content'), + cancelBtnVariant: 'link', + confirmBtnVariant: 'danger', + confirmText: t('delete', { keyPrefix: 'btns' }), + onConfirm: () => { + deleteApiKey(itemData.id).then(() => { + toastStore.getState().show({ + msg: t('api_key_deleted', { keyPrefix: 'messages' }), + variant: 'success', + }); + refreshList(); + }); + }, + }); + } + + if (type === 'edit') { + showModal(true); + } + }; + + return ( + + + + + + handleAction('edit')}> + {t('edit', { keyPrefix: 'btns' })} + + handleAction('delete')}> + {t('delete', { keyPrefix: 'btns' })} + + + + ); +}; + +export default ApiActions; diff --git a/ui/src/pages/Admin/Apikeys/components/AddOrEditModal/index.tsx b/ui/src/pages/Admin/Apikeys/components/AddOrEditModal/index.tsx new file mode 100644 index 000000000..044a30173 --- /dev/null +++ b/ui/src/pages/Admin/Apikeys/components/AddOrEditModal/index.tsx @@ -0,0 +1,184 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { useState } from 'react'; +import { Modal, Form, Button } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; + +import { handleFormError } from '@/utils'; +import { addApiKey, updateApiKey } from '@/services'; + +const initFormData = { + description: { + value: '', + isInvalid: false, + errorMsg: '', + }, + scope: { + value: 'read-only', + isInvalid: false, + errorMsg: '', + }, +}; + +const Index = ({ data, visible = false, onClose, callback }) => { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.apikeys.add_or_edit_modal', + }); + const [formData, setFormData] = useState(initFormData); + + const handleValueChange = (value) => { + setFormData({ + ...formData, + ...value, + }); + }; + + const handleAdd = () => { + const { description, scope } = formData; + if (!description.value) { + setFormData({ + ...formData, + description: { + ...description, + isInvalid: true, + errorMsg: t('description_required'), + }, + }); + return; + } + addApiKey({ + description: description.value, + scope: scope.value, + }) + .then((res) => { + callback('add', res.access_key); + setFormData(initFormData); + }) + .catch((error) => { + const obj = handleFormError(error, formData); + setFormData({ ...obj }); + }); + }; + + const handleEdit = () => { + const { description } = formData; + if (!description.value) { + setFormData({ + ...formData, + description: { + ...description, + isInvalid: true, + errorMsg: t('description_required'), + }, + }); + return; + } + updateApiKey({ + description: description.value, + id: data?.id, + }) + .then(() => { + callback('edit', null); + setFormData(initFormData); + }) + .catch((error) => { + const obj = handleFormError(error, formData); + setFormData({ ...obj }); + }); + }; + + const handleSubmit = () => { + if (data?.id) { + handleEdit(); + return; + } + handleAdd(); + }; + + const closeModal = () => { + setFormData(initFormData); + onClose(false, null); + }; + return ( + + + {data?.id ? t('edit_title') : t('add_title')} + + +
    + + {t('description')} + { + handleValueChange({ + description: { + value: e.target.value, + errorMsg: '', + isInvalid: false, + }, + }); + }} + /> + + {formData.description.errorMsg} + + + + {!data?.id && visible && ( + + {t('scope')} + { + handleValueChange({ + scope: { + value: e.target.value, + errorMsg: '', + isInvalid: false, + }, + }); + }}> + + + + + {formData.scope.errorMsg} + + + )} +
    +
    + + + + +
    + ); +}; + +export default Index; diff --git a/ui/src/pages/Admin/Apikeys/components/CreatedModal/index.tsx b/ui/src/pages/Admin/Apikeys/components/CreatedModal/index.tsx new file mode 100644 index 000000000..83f782a10 --- /dev/null +++ b/ui/src/pages/Admin/Apikeys/components/CreatedModal/index.tsx @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Modal, Form, Button } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; + +const Index = ({ visible, api_key = '', onClose }) => { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.apikeys.created_modal', + }); + + return ( + + {t('title')} + +
    + + {t('api_key')} + + + +
    {t('description')}
    +
    +
    + + + +
    + ); +}; + +export default Index; diff --git a/ui/src/pages/Admin/Apikeys/components/index.ts b/ui/src/pages/Admin/Apikeys/components/index.ts new file mode 100644 index 000000000..46bda3f5d --- /dev/null +++ b/ui/src/pages/Admin/Apikeys/components/index.ts @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Action from './Action'; +import AddOrEditModal from './AddOrEditModal'; +import CreatedModal from './CreatedModal'; + +export { Action, AddOrEditModal, CreatedModal }; diff --git a/ui/src/pages/Admin/Apikeys/index.tsx b/ui/src/pages/Admin/Apikeys/index.tsx new file mode 100644 index 000000000..a143cfa8f --- /dev/null +++ b/ui/src/pages/Admin/Apikeys/index.tsx @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Button, Table } from 'react-bootstrap'; + +import dayjs from 'dayjs'; + +import { useQueryApiKeys } from '@/services'; + +import { Action, AddOrEditModal, CreatedModal } from './components'; + +const Index = () => { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.apikeys', + }); + const [showModal, setShowModal] = useState({ + visible: false, + item: null, + }); + const [showCreatedModal, setShowCreatedModal] = useState({ + visible: false, + api_key: '', + }); + const { data: apiKeysList, mutate: refreshList } = useQueryApiKeys(); + + const handleAddModalState = (bol, item) => { + setShowModal({ + visible: bol, + item, + }); + }; + + const handleCreatedModalState = (visible, api_key) => { + setShowCreatedModal({ + visible, + api_key, + }); + }; + + const addOrEditCallback = (type, key) => { + handleAddModalState(false, null); + refreshList(); + if (type === 'add') { + handleCreatedModalState(true, key); + } + }; + + return ( +
    +

    {t('title')}

    + + + + + + + + + + + + {apiKeysList?.map((item) => { + return ( + + + + + + + + + ); + })} + +
    {t('desc')}{t('scope')}{t('key')}{t('created')}{t('last_used')} + {t('action', { keyPrefix: 'admin.questions' })} +
    {item.description} + {t(item.scope, { + keyPrefix: 'admin.apikeys.add_or_edit_modal', + })} + {item.access_key} + {dayjs + .unix(item?.created_at) + .tz() + .format(t('long_date_with_time', { keyPrefix: 'dates' }))} + + {item?.last_used_at && + dayjs + .unix(item?.last_used_at) + .tz() + .format(t('long_date_with_time', { keyPrefix: 'dates' }))} + + handleAddModalState(true, item)} + refreshList={refreshList} + /> +
    + + + handleCreatedModalState(false, '')} + /> +
    + ); +}; + +export default Index; diff --git a/ui/src/pages/Admin/Mcp/index.tsx b/ui/src/pages/Admin/Mcp/index.tsx new file mode 100644 index 000000000..39d5375d1 --- /dev/null +++ b/ui/src/pages/Admin/Mcp/index.tsx @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { FormEvent, useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Form, Button } from 'react-bootstrap'; + +import { useToast } from '@/hooks'; +import { getMcpConfig, saveMcpConfig } from '@/services'; + +const Mcp = () => { + const toast = useToast(); + const { t } = useTranslation('translation', { + keyPrefix: 'admin.mcp', + }); + const [formData, setFormData] = useState({ + enabled: true, + type: '', + url: '', + http_header: '', + }); + const [isLoading, setIsLoading] = useState(false); + + const handleOnChange = (form) => { + setFormData({ ...formData, ...form }); + }; + const onSubmit = (evt: FormEvent) => { + evt.preventDefault(); + evt.stopPropagation(); + saveMcpConfig({ enabled: formData.enabled }).then(() => { + toast.onShow({ + msg: t('update', { keyPrefix: 'toast' }), + variant: 'success', + }); + }); + }; + + useEffect(() => { + getMcpConfig() + .then((resp) => { + setIsLoading(false); + setFormData(resp); + }) + .catch(() => { + setIsLoading(false); + }); + }, []); + if (isLoading) { + return null; + } + return ( + <> +

    {t('mcp', { keyPrefix: 'nav_menus' })}

    +
    +
    + + {t('mcp_server.label')} + handleOnChange({ enabled: e.target.checked })} + /> + + {formData.enabled && ( + <> + + {t('type.label')} + + + + {t('url.label')} + + + + {t('http_header.label')} + + + {t('http_header.text')} + + + + )} + +
    +
    + + ); +}; + +export default Mcp; diff --git a/ui/src/pages/Admin/QaSettings/index.tsx b/ui/src/pages/Admin/QaSettings/index.tsx index 0c2636eae..17834ab04 100644 --- a/ui/src/pages/Admin/QaSettings/index.tsx +++ b/ui/src/pages/Admin/QaSettings/index.tsx @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + import { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/ui/src/pages/Admin/Security/index.tsx b/ui/src/pages/Admin/Security/index.tsx index 07eaeb5b4..35d7f2f65 100644 --- a/ui/src/pages/Admin/Security/index.tsx +++ b/ui/src/pages/Admin/Security/index.tsx @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + import { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/ui/src/pages/Admin/TagsSettings/index.tsx b/ui/src/pages/Admin/TagsSettings/index.tsx index f2ab2f5b1..b857d9899 100644 --- a/ui/src/pages/Admin/TagsSettings/index.tsx +++ b/ui/src/pages/Admin/TagsSettings/index.tsx @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + import { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/ui/src/pages/Admin/UsersSettings/index.tsx b/ui/src/pages/Admin/UsersSettings/index.tsx index 769c9f0a1..55a3e7842 100644 --- a/ui/src/pages/Admin/UsersSettings/index.tsx +++ b/ui/src/pages/Admin/UsersSettings/index.tsx @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + import { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; diff --git a/ui/src/pages/AiAssistant/components/ConversationList/index.tsx b/ui/src/pages/AiAssistant/components/ConversationList/index.tsx new file mode 100644 index 000000000..4dbc61297 --- /dev/null +++ b/ui/src/pages/AiAssistant/components/ConversationList/index.tsx @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { FC, memo } from 'react'; +import { Card, ListGroup } from 'react-bootstrap'; +import { Link } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; + +interface ConversationListItem { + conversation_id: string; + topic: string; +} + +interface IProps { + data: { + count: number; + list: ConversationListItem[]; + }; + loadMore: (e: React.MouseEvent) => void; +} + +const Index: FC = ({ data, loadMore }) => { + const { t } = useTranslation('translation', { keyPrefix: 'ai_assistant' }); + + if (Number(data?.list.length) <= 0) return null; + return ( + + + {t('recent_conversations')} + + + {data?.list.map((item) => { + return ( + + {item.topic} + + ); + })} + {Number(data?.count) > data?.list.length && ( + + {t('show_more')} + + )} + + + ); +}; + +export default memo(Index); diff --git a/ui/src/pages/AiAssistant/index.tsx b/ui/src/pages/AiAssistant/index.tsx new file mode 100644 index 000000000..e2329f85c --- /dev/null +++ b/ui/src/pages/AiAssistant/index.tsx @@ -0,0 +1,380 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { useEffect, useState } from 'react'; +import { Row, Col, Spinner, Button } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; +import { useParams, useNavigate } from 'react-router-dom'; + +import classNames from 'classnames'; +import { v4 as uuidv4 } from 'uuid'; + +import * as Type from '@/common/interface'; +import requestAi, { cancelCurrentRequest } from '@/utils/requestAi'; +import { Sender, BubbleUser, BubbleAi, Icon } from '@/components'; +import { getConversationDetail, getConversationList } from '@/services'; +import { usePageTags } from '@/hooks'; +import { Storage } from '@/utils'; + +import ConversationsList from './components/ConversationList'; + +interface ConversationListItem { + conversation_id: string; + topic: string; +} + +const Index = () => { + const { t } = useTranslation('translation', { keyPrefix: 'ai_assistant' }); + const [isShowConversationList, setIsShowConversationList] = useState(false); + const [isGenerate, setIsGenerate] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const [recentNewItem, setRecentNewItem] = useState(null); + const [conversions, setConversions] = useState({ + records: [], + conversation_id: '', + created_at: 0, + topic: '', + updated_at: 0, + }); + const navigate = useNavigate(); + const { id = '' } = useParams<{ id: string }>(); + const [temporaryBottomSpace, setTemporaryBottomSpace] = useState(0); + const [conversationsPage, setConversationsPage] = useState(1); + + const [conversationsList, setConversationsList] = useState<{ + count: number; + list: ConversationListItem[]; + }>({ + count: 0, + list: [], + }); + + const calculateTemporarySpace = () => { + const viewportHeight = window.innerHeight; + const navHeight = 64; + const senderHeight = (document.querySelector('.sender-wrap') as HTMLElement) + ?.offsetHeight; + const neededSpace = viewportHeight - senderHeight - navHeight - 120; + const height = neededSpace; + console.log('lasMsgHeight', height); + + setTemporaryBottomSpace(height); + }; + + const resetPageState = () => { + setConversions({ + records: [], + conversation_id: '', + created_at: 0, + topic: '', + updated_at: 0, + }); + setIsGenerate(false); + setRecentNewItem(null); + }; + + const handleNewConversation = (e) => { + e.preventDefault(); + navigate('/ai-assistant', { replace: true }); + }; + + const fetchDetail = () => { + getConversationDetail(id).then((res) => { + setConversions(res); + }); + }; + + const handleSubmit = async (userMsg) => { + setIsLoading(true); + if (conversions?.records.length === 0) { + setRecentNewItem({ + conversation_id: id, + topic: userMsg, + }); + } + const chatId = Date.now(); + setConversions((prev) => ({ + ...prev, + topic: userMsg, + conversation_id: id, + records: [ + ...prev.records, + { + id: chatId, + role: 'user', + content: userMsg, + chat_completion_id: String(chatId), // Add required properties + helpful: 0, + unhelpful: 0, + created_at: chatId, + }, + ], + })); + + // scroll to user message after the page height is stable + requestAnimationFrame(() => { + const userBubbles = document.querySelectorAll('.bubble-user-wrap'); + const lastUserBubble = userBubbles[userBubbles.length - 1]; + if (lastUserBubble) { + lastUserBubble.scrollIntoView({ + behavior: 'smooth', + block: 'start', + }); + } + }); + + calculateTemporarySpace(); + + const params = { + conversation_id: id, + messages: [ + { + role: 'user', + content: userMsg, + }, + ], + }; + + await requestAi('/answer/api/v1/chat/completions', { + body: JSON.stringify(params), + onMessage: (res) => { + if (!res.choices[0].delta?.content) { + return; + } + setIsLoading(false); + setIsGenerate(true); + setConversions((prev) => { + const updatedRecords = [...prev.records]; + const lastConversion = updatedRecords[updatedRecords.length - 1]; + if (lastConversion?.chat_completion_id === res?.chat_completion_id) { + updatedRecords[updatedRecords.length - 1] = { + ...lastConversion, + content: lastConversion.content + res.choices[0].delta.content, + }; + } else { + updatedRecords.push({ + chat_completion_id: res.chat_completion_id, + role: res.choices[0].delta.role || 'assistant', + content: res.choices[0].delta.content, + helpful: 0, + unhelpful: 0, + created_at: Date.now(), + }); + } + return { + ...prev, + conversation_id: params.conversation_id, + records: updatedRecords, + }; + }); + }, + onError: (error) => { + setIsLoading(false); + setIsGenerate(false); + console.error('Error:', error); + }, + onComplete: () => { + setIsGenerate(false); + setIsLoading(false); + }, + }); + }; + + const handleSender = (userMsg) => { + if (conversions?.records.length <= 0) { + const newConversationId = uuidv4(); + navigate(`/ai-assistant/${newConversationId}`); + Storage.set('_a_once_msg', userMsg); + } else { + handleSubmit(userMsg); + } + }; + + const handleCancel = () => { + if (cancelCurrentRequest()) { + setIsGenerate(false); + } + }; + + usePageTags({ + title: conversions?.topic || t('ai_assistant', { keyPrefix: 'page_title' }), + }); + + useEffect(() => { + if (id) { + const msg = Storage.get('_a_once_msg'); + Storage.remove('_a_once_msg'); + if (msg) { + if (msg) { + handleSubmit(msg); + } + return; + } + fetchDetail(); + } else { + resetPageState(); + } + }, [id]); + + const getList = (p) => { + getConversationList({ + page: p, + page_size: 10, + }).then((res) => { + setConversationsList({ + count: res.count, + list: [...conversationsList.list, ...res.list], + }); + }); + }; + + const getMore = (e) => { + e.preventDefault(); + setConversationsPage((prev) => prev + 1); + getList(conversationsPage + 1); + }; + + useEffect(() => { + getList(1); + + return () => { + setConversationsList({ + count: 0, + list: [], + }); + setConversationsPage(1); + }; + }, []); + + useEffect(() => { + if (recentNewItem && recentNewItem.conversation_id) { + setConversationsList((prev) => ({ + ...prev, + list: [ + recentNewItem, + ...prev.list.filter( + (item) => item.conversation_id !== recentNewItem.conversation_id, + ), + ], + })); + } + }, [recentNewItem]); + + return ( +
    +
    +

    + {t('ai_assistant', { keyPrefix: 'page_title' })} +

    +
    + + +
    +
    + + + {conversions?.records.length > 0 && ( +
    + {conversions?.records.map((item, index) => { + const isLastMessage = + index === Number(conversions?.records.length) - 1; + return ( +
    + {item.role === 'user' ? ( + + ) : ( + + )} +
    + ); + })} + + {temporaryBottomSpace > 0 && isLoading && ( +
    + {isLoading && ( + + )} +
    + )} +
    + )} + {conversions?.conversation_id ? null : ( +
    {t('description')}
    + )} + + + {isShowConversationList && ( + + + + )} +
    +
    + ); +}; + +export default Index; diff --git a/ui/src/pages/Questions/Ask/index.tsx b/ui/src/pages/Questions/Ask/index.tsx index 5fb4d57f2..ab680c495 100644 --- a/ui/src/pages/Questions/Ask/index.tsx +++ b/ui/src/pages/Questions/Ask/index.tsx @@ -279,10 +279,10 @@ const Ask = () => { }); const handleAnswerChange = (value: string) => - setFormData({ - ...formData, + setFormData((prev) => ({ + ...prev, answer_content: { value, errorMsg: '', isInvalid: false }, - }); + })); const handleSummaryChange = (evt: React.ChangeEvent) => setFormData({ diff --git a/ui/src/pages/Questions/EditAnswer/index.tsx b/ui/src/pages/Questions/EditAnswer/index.tsx index 3be7befcf..11b0411a5 100644 --- a/ui/src/pages/Questions/EditAnswer/index.tsx +++ b/ui/src/pages/Questions/EditAnswer/index.tsx @@ -116,10 +116,10 @@ const Index = () => { }, [formData.content.value, formData.description.value]); const handleAnswerChange = (value: string) => - setFormData({ - ...formData, - content: { ...formData.content, value }, - }); + setFormData((prev) => ({ + ...prev, + content: { ...prev.content, value }, + })); const handleSummaryChange = (evt) => { const v = evt.currentTarget.value; setFormData({ diff --git a/ui/src/pages/Search/components/AiCard/index.tsx b/ui/src/pages/Search/components/AiCard/index.tsx new file mode 100644 index 000000000..9e7d8f944 --- /dev/null +++ b/ui/src/pages/Search/components/AiCard/index.tsx @@ -0,0 +1,170 @@ +import { useState, useEffect } from 'react'; +import { Card, Spinner } from 'react-bootstrap'; +import { useSearchParams, Link } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; + +import { v4 as uuidv4 } from 'uuid'; + +import { BubbleAi, BubbleUser } from '@/components'; +import { aiControlStore } from '@/stores'; +import * as Type from '@/common/interface'; +import requestAi from '@/utils/requestAi'; + +const Index = () => { + const { t } = useTranslation('translation', { keyPrefix: 'ai_assistant' }); + const { ai_enabled } = aiControlStore((state) => state); + const [searchParams] = useSearchParams(); + const [isLoading, setIsLoading] = useState(false); + const [isGenerate, setIsGenerate] = useState(false); + const [isCompleted, setIsCompleted] = useState(false); + const [conversions, setConversions] = useState({ + records: [], + conversation_id: '', + created_at: 0, + topic: '', + updated_at: 0, + }); + + const handleSubmit = async (userMsg) => { + setIsLoading(true); + setIsCompleted(false); + const newConversationId = uuidv4(); + setConversions({ + conversation_id: newConversationId, + created_at: 0, + topic: '', + updated_at: 0, + records: [ + { + chat_completion_id: Date.now().toString(), + role: 'user', + content: userMsg, + helpful: 0, + unhelpful: 0, + created_at: Date.now(), + }, + ], + }); + + const params = { + conversation_id: newConversationId, + messages: [ + { + role: 'user', + content: userMsg, + }, + ], + }; + + await requestAi('/answer/api/v1/chat/completions', { + body: JSON.stringify(params), + onMessage: (res) => { + if (!res.choices[0].delta?.content) { + return; + } + setIsLoading(false); + setIsGenerate(true); + + setConversions((prev) => { + const updatedRecords = [...prev.records]; + const lastConversion = updatedRecords[updatedRecords.length - 1]; + if (lastConversion?.chat_completion_id === res?.chat_completion_id) { + updatedRecords[updatedRecords.length - 1] = { + ...lastConversion, + content: lastConversion.content + res.choices[0].delta.content, + }; + } else { + updatedRecords.push({ + chat_completion_id: res.chat_completion_id, + role: res.choices[0].delta.role || 'assistant', + content: res.choices[0].delta.content, + helpful: 0, + unhelpful: 0, + created_at: Date.now(), + }); + } + return { + ...prev, + conversation_id: params.conversation_id, + records: updatedRecords, + }; + }); + }, + onError: (error) => { + setIsGenerate(false); + setIsLoading(false); + setIsCompleted(true); + console.error('Error:', error); + }, + onComplete: () => { + setIsCompleted(true); + setIsGenerate(false); + }, + }); + }; + + useEffect(() => { + const q = searchParams.get('q') || ''; + if (ai_enabled && q) { + handleSubmit(q); + } + }, [searchParams]); + + if (!ai_enabled) { + return null; + } + return ( + + + {t('ai_assistant', { keyPrefix: 'page_title' })} + + + {conversions?.records.map((item, index) => { + const isLastMessage = + index === Number(conversions?.records.length) - 1; + return ( +
    + {item.role === 'user' ? ( + + ) : ( + + )} +
    + ); + })} + {isLoading && ( + + )} +
    + {isCompleted && !isLoading && ( + + + {t('ask_a_follow_up')} + + {t('ai_generate')} + + )} +
    + ); +}; + +export default Index; diff --git a/ui/src/pages/Search/components/index.ts b/ui/src/pages/Search/components/index.ts index 1ea0e9910..c04ecba02 100644 --- a/ui/src/pages/Search/components/index.ts +++ b/ui/src/pages/Search/components/index.ts @@ -23,5 +23,6 @@ import Tips from './Tips'; import Empty from './Empty'; import SearchHead from './SearchHead'; import ListLoader from './ListLoader'; +import AiCard from './AiCard'; -export { Head, SearchItem, Tips, Empty, SearchHead, ListLoader }; +export { Head, SearchItem, Tips, Empty, SearchHead, ListLoader, AiCard }; diff --git a/ui/src/pages/Search/index.tsx b/ui/src/pages/Search/index.tsx index 8b6cc1e20..bcc734b21 100644 --- a/ui/src/pages/Search/index.tsx +++ b/ui/src/pages/Search/index.tsx @@ -27,6 +27,7 @@ import { useCaptchaPlugin } from '@/utils/pluginKit'; import { Pagination } from '@/components'; import { getSearchResult } from '@/services'; import type { SearchParams, SearchRes } from '@/common/interface'; +import { logged } from '@/utils/guard'; import { Head, @@ -35,10 +36,12 @@ import { Tips, Empty, ListLoader, + AiCard, } from './components'; const Index = () => { const { t } = useTranslation('translation'); + const isLogged = logged().ok; const [searchParams] = useSearchParams(); const page = searchParams.get('page') || 1; const q = searchParams.get('q') || ''; @@ -106,6 +109,7 @@ const Index = () => { + {isLogged && } {isSkeletonShow ? ( diff --git a/ui/src/pages/SideNavLayoutWithoutFooter/index.tsx b/ui/src/pages/SideNavLayoutWithoutFooter/index.tsx new file mode 100644 index 000000000..5f931f78a --- /dev/null +++ b/ui/src/pages/SideNavLayoutWithoutFooter/index.tsx @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { FC, memo } from 'react'; +import { Outlet } from 'react-router-dom'; + +import { SideNav } from '@/components'; + +import '@/common/sideNavLayout.scss'; + +const Index: FC = () => { + return ( +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + ); +}; + +export default memo(Index); diff --git a/ui/src/pages/Tags/Create/index.tsx b/ui/src/pages/Tags/Create/index.tsx index b0564f193..428ba9414 100644 --- a/ui/src/pages/Tags/Create/index.tsx +++ b/ui/src/pages/Tags/Create/index.tsx @@ -100,10 +100,10 @@ const Index = () => { ]); const handleDescriptionChange = (value: string) => - setFormData({ - ...formData, - description: { ...formData.description, value, isInvalid: false }, - }); + setFormData((prev) => ({ + ...prev, + description: { value, isInvalid: false, errorMsg: '' }, + })); const checkValidated = (): boolean => { let bol = true; diff --git a/ui/src/pages/Tags/Edit/index.tsx b/ui/src/pages/Tags/Edit/index.tsx index 0670b9467..021ce1ce3 100644 --- a/ui/src/pages/Tags/Edit/index.tsx +++ b/ui/src/pages/Tags/Edit/index.tsx @@ -117,10 +117,10 @@ const Index = () => { ]); const handleDescriptionChange = (value: string) => - setFormData({ - ...formData, - description: { ...formData.description, value }, - }); + setFormData((prev) => ({ + ...prev, + description: { value, isInvalid: false, errorMsg: '' }, + })); const checkValidated = (): boolean => { let bol = true; diff --git a/ui/src/router/routes.ts b/ui/src/router/routes.ts index 7d7003a12..8423fb7a3 100644 --- a/ui/src/router/routes.ts +++ b/ui/src/router/routes.ts @@ -445,6 +445,22 @@ const routes: RouteNode[] = [ path: 'badges', page: 'pages/Admin/Badges', }, + { + path: 'ai-assistant', + page: 'pages/Admin/AiAssistant', + }, + { + path: 'ai-settings', + page: 'pages/Admin/AiSettings', + }, + { + path: 'apikeys', + page: 'pages/Admin/Apikeys', + }, + { + path: 'mcp', + page: 'pages/Admin/Mcp', + }, ], }, { @@ -467,6 +483,26 @@ const routes: RouteNode[] = [ path: '50x', page: 'pages/50X', }, + // ai + { + page: 'pages/SideNavLayoutWithoutFooter', + children: [ + { + path: '/ai-assistant', + page: 'pages/AiAssistant', + guard: () => { + return guard.logged(); + }, + }, + { + path: '/ai-assistant/:id', + page: 'pages/AiAssistant', + guard: () => { + return guard.logged(); + }, + }, + ], + }, ], }, { diff --git a/ui/src/services/admin/ai.ts b/ui/src/services/admin/ai.ts new file mode 100644 index 000000000..e20da7ac6 --- /dev/null +++ b/ui/src/services/admin/ai.ts @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import useSWR from 'swr'; +import qs from 'qs'; + +import request from '@/utils/request'; +import type * as Type from '@/common/interface'; + +export const getAiConfig = () => { + return request.get('/answer/admin/api/ai-config'); +}; + +export const useQueryAiProvider = () => { + const apiUrl = `/answer/admin/api/ai-provider`; + const { data, error, mutate } = useSWR( + apiUrl, + request.instance.get, + ); + return { + data, + isLoading: !data && !error, + error, + mutate, + }; +}; + +export const checkAiConfig = (params) => { + return request.post('/answer/admin/api/ai-models', params); +}; + +export const saveAiConfig = (params) => { + return request.put('/answer/admin/api/ai-config', params); +}; + +export const useQueryAdminConversationDetail = (id: string) => { + const apiUrl = !id + ? null + : `/answer/admin/api/ai/conversation?conversation_id=${id}`; + + const { data, error, mutate } = useSWR( + apiUrl, + request.instance.get, + ); + return { + data, + isLoading: !data && !error, + error, + mutate, + }; +}; + +export const useQueryAdminConversationList = (params: Type.Paging) => { + const apiUrl = `/answer/admin/api/ai/conversation/page?${qs.stringify(params)}`; + const { data, error, mutate } = useSWR< + { count: number; list: Type.AdminConversationListItem[] }, + Error + >(apiUrl, request.instance.get); + return { + data, + isLoading: !data && !error, + error, + mutate, + }; +}; + +export const deleteAdminConversation = (id: string) => { + return request.delete('/answer/admin/api/ai/conversation', { + conversation_id: id, + }); +}; diff --git a/ui/src/services/admin/apikeys.ts b/ui/src/services/admin/apikeys.ts new file mode 100644 index 000000000..8271e024e --- /dev/null +++ b/ui/src/services/admin/apikeys.ts @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import useSWR from 'swr'; + +import request from '@/utils/request'; +import type * as Type from '@/common/interface'; + +export const useQueryApiKeys = () => { + const apiUrl = `/answer/admin/api/api-key/all`; + const { data, error, mutate } = useSWR( + apiUrl, + request.instance.get, + ); + return { + data, + isLoading: !data && !error, + error, + mutate, + }; +}; + +export const addApiKey = (params: Type.AddOrEditApiKeyParams) => { + return request.post('/answer/admin/api/api-key', params); +}; + +export const updateApiKey = (params: Type.AddOrEditApiKeyParams) => { + return request.put('/answer/admin/api/api-key', params); +}; + +export const deleteApiKey = (id: string) => { + return request.delete('/answer/admin/api/api-key', { + id, + }); +}; diff --git a/ui/src/services/admin/index.ts b/ui/src/services/admin/index.ts index 3fa211ee3..76d6ef90a 100644 --- a/ui/src/services/admin/index.ts +++ b/ui/src/services/admin/index.ts @@ -25,4 +25,7 @@ export * from './users'; export * from './dashboard'; export * from './plugins'; export * from './badges'; +export * from './ai'; export * from './tags'; +export * from './apikeys'; +export * from './mcp'; diff --git a/ui/src/services/admin/mcp.ts b/ui/src/services/admin/mcp.ts new file mode 100644 index 000000000..6fbbd735d --- /dev/null +++ b/ui/src/services/admin/mcp.ts @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import request from '@/utils/request'; + +type McpConfig = { + enabled: boolean; + type: string; + url: string; + http_header: string; +}; + +export const getMcpConfig = () => { + return request.get(`/answer/admin/api/mcp-config`); +}; + +export const saveMcpConfig = (params: { enabled: boolean }) => { + return request.put(`/answer/admin/api/mcp-config`, params); +}; diff --git a/ui/src/services/client/ai.ts b/ui/src/services/client/ai.ts new file mode 100644 index 000000000..28cc6398f --- /dev/null +++ b/ui/src/services/client/ai.ts @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import qs from 'qs'; + +import request from '@/utils/request'; +import type * as Type from '@/common/interface'; + +export const getConversationList = (params: Type.Paging) => { + return request.get<{ count: number; list: Type.ConversationListItem[] }>( + `/answer/api/v1/ai/conversation/page?${qs.stringify(params)}`, + ); +}; + +export const getConversationDetail = (id: string) => { + return request.get( + `/answer/api/v1/ai/conversation?conversation_id=${id}`, + ); +}; + +// /answer/api/v1/ai/conversation/vote +export const voteConversation = (params: Type.VoteConversationParams) => { + return request.post('/answer/api/v1/ai/conversation/vote', params); +}; diff --git a/ui/src/services/client/index.ts b/ui/src/services/client/index.ts index 005bc26d7..4d5c85c10 100644 --- a/ui/src/services/client/index.ts +++ b/ui/src/services/client/index.ts @@ -31,3 +31,4 @@ export * from './user'; export * from './Oauth'; export * from './review'; export * from './badges'; +export * from './ai'; diff --git a/ui/src/stores/aiControl.ts b/ui/src/stores/aiControl.ts new file mode 100644 index 000000000..c9f0afbc7 --- /dev/null +++ b/ui/src/stores/aiControl.ts @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { create } from 'zustand'; + +interface AiControlStore { + ai_enabled: boolean; + update: (params: { ai_enabled: boolean }) => void; + reset: () => void; +} + +const aiControlStore = create((set) => ({ + ai_enabled: false, + update: (params: { ai_enabled: boolean }) => + set((state) => { + return { + ...state, + ...params, + }; + }), + reset: () => set({ ai_enabled: false }), +})); + +export default aiControlStore; diff --git a/ui/src/stores/index.ts b/ui/src/stores/index.ts index 1bd2fece0..41af8d55e 100644 --- a/ui/src/stores/index.ts +++ b/ui/src/stores/index.ts @@ -34,6 +34,7 @@ import errorCodeStore from './errorCode'; import sideNavStore from './sideNav'; import commentReplyStore from './commentReply'; import siteSecurityStore from './siteSecurity'; +import aiControlStore from './aiControl'; export { toastStore, @@ -53,4 +54,5 @@ export { commentReplyStore, writeSettingStore, siteSecurityStore, + aiControlStore, }; diff --git a/ui/src/utils/guard.ts b/ui/src/utils/guard.ts index 6e6a6d801..fc78fa122 100644 --- a/ui/src/utils/guard.ts +++ b/ui/src/utils/guard.ts @@ -31,6 +31,7 @@ import { pageTagStore, writeSettingStore, siteSecurityStore, + aiControlStore, } from '@/stores'; import { RouteAlias } from '@/router/alias'; import { @@ -386,6 +387,9 @@ export const initAppSettingsStore = async () => { ...appSettings.site_questions, ...appSettings.site_tags, }); + aiControlStore.getState().update({ + ai_enabled: appSettings.ai_enabled, + }); siteSecurityStore.getState().update(appSettings.site_security); } }; diff --git a/ui/src/utils/requestAi.ts b/ui/src/utils/requestAi.ts new file mode 100644 index 000000000..444bbe6dc --- /dev/null +++ b/ui/src/utils/requestAi.ts @@ -0,0 +1,300 @@ +import { Modal } from '@/components'; +import { loggedUserInfoStore, toastStore, errorCodeStore } from '@/stores'; +import { LOGGED_TOKEN_STORAGE_KEY } from '@/common/constants'; +import { RouteAlias } from '@/router/alias'; +import { getCurrentLang } from '@/utils/localize'; +import Storage from '@/utils/storage'; +import { floppyNavigation } from '@/utils/floppyNavigation'; +import { isIgnoredPath, IGNORE_PATH_LIST } from '@/utils/guard'; + +interface RequestAiOptions extends RequestInit { + onMessage?: (text: any) => void; + onError?: (error: Error) => void; + onComplete?: () => void; + signal?: AbortSignal; + // 添加项目配置选项 + allow404?: boolean; + ignoreError?: '403' | '50X'; + passingError?: boolean; +} + +// create a object to track the current request state +const requestState = { + currentReader: null as ReadableStreamDefaultReader | null, + abortController: null as AbortController | null, + isProcessing: false, +}; + +// HTTP error handling function (based on request.ts logic) +const handleHttpError = async ( + response: Response, + options: RequestAiOptions, +): Promise => { + const { status } = response; + let errBody: any = {}; + + try { + const text = await response.text(); + errBody = text ? JSON.parse(text) : {}; + } catch { + errBody = { msg: response.statusText }; + } + + const { data = {}, msg = '', config } = errBody || {}; + + const errorObject = { + code: status, + msg, + data, + }; + + if (status === 400) { + if (data?.err_type && options?.passingError) { + return Promise.reject(errorObject); + } + + if (data?.err_type) { + if (data.err_type === 'toast') { + toastStore.getState().show({ + msg, + variant: 'danger', + }); + } + + if (data.err_type === 'alert') { + return Promise.reject({ msg, ...data }); + } + + if (data.err_type === 'modal') { + Modal.confirm({ + content: msg, + }); + } + return Promise.reject(false); + } + + if (Array.isArray(data) && data.length > 0) { + return Promise.reject({ + ...errorObject, + isError: true, + list: data, + }); + } + + if (!data || Object.keys(data).length <= 0) { + Modal.confirm({ + content: msg, + showConfirm: false, + cancelText: 'close', + }); + return Promise.reject(false); + } + } + + // 401: 重新登录 + if (status === 401) { + errorCodeStore.getState().reset(); + loggedUserInfoStore.getState().clear(); + floppyNavigation.navigateToLogin(); + return Promise.reject(false); + } + + if (status === 403) { + // Permission interception + if (data?.type === 'url_expired') { + // url expired + floppyNavigation.navigate(RouteAlias.activationFailed, { + handler: 'replace', + }); + return Promise.reject(false); + } + if (data?.type === 'inactive') { + // inactivated + floppyNavigation.navigate(RouteAlias.inactive); + return Promise.reject(false); + } + + if (data?.type === 'suspended') { + loggedUserInfoStore.getState().clear(); + floppyNavigation.navigate(RouteAlias.suspended, { + handler: 'replace', + }); + return Promise.reject(false); + } + + if (isIgnoredPath(IGNORE_PATH_LIST)) { + return Promise.reject(false); + } + if (config?.url.includes('/admin/api')) { + errorCodeStore.getState().update('403'); + return Promise.reject(false); + } + + if (msg) { + toastStore.getState().show({ + msg, + variant: 'danger', + }); + } + return Promise.reject(false); + } + + if (status === 404 && config?.allow404) { + if (isIgnoredPath(IGNORE_PATH_LIST)) { + return Promise.reject(false); + } + errorCodeStore.getState().update('404'); + return Promise.reject(false); + } + + if (status >= 500) { + if (isIgnoredPath(IGNORE_PATH_LIST)) { + return Promise.reject(false); + } + + if (config?.ignoreError !== '50X') { + errorCodeStore.getState().update('50X'); + } + + console.error(`Request failed with status code ${status}, ${msg || ''}`); + } + return Promise.reject(errorObject); +}; +const requestAi = async (url: string, options: RequestAiOptions) => { + try { + // if there is a previous request being processed, cancel it + if (requestState.isProcessing && requestState.abortController) { + requestState.abortController.abort(); + } + + // create a new AbortController + const abortController = new AbortController(); + requestState.abortController = abortController; + + // merge the incoming signal with the new created signal + const combinedSignal = options.signal || abortController.signal; + + // mark as being processed + requestState.isProcessing = true; + + // get the authentication information and language settings (consistent with request.ts) + const token = Storage.get(LOGGED_TOKEN_STORAGE_KEY) || ''; + console.log(token); + const lang = getCurrentLang(); + + const response = await fetch(url, { + ...options, + method: 'POST', + signal: combinedSignal, + headers: { + Authorization: token, + 'Accept-Language': lang, + 'Content-Type': 'application/json', + ...options.headers, + }, + }); + + // unified error handling (based on request.ts logic) + if (!response.ok) { + await handleHttpError(response, options); + return; + } + + const reader = response.body?.getReader(); + if (!reader) { + throw new Error('ReadableStream not supported'); + } + + // store the current reader so it can be cancelled later + requestState.currentReader = reader; + + const decoder = new TextDecoder(); + let buffer = ''; + + const processStream = async (): Promise => { + try { + const { value, done } = await reader.read(); + + if (done) { + options.onComplete?.(); + requestState.isProcessing = false; + requestState.currentReader = null; + return; + } + + const chunk = decoder.decode(value, { stream: true }); + buffer += chunk; + + const lines = buffer.split('\n'); + buffer = lines.pop() || ''; + + lines.forEach((line) => { + if (line.trim()) { + try { + // handle the special [DONE] signal + const cleanedLine = line.replace(/^data: /, '').trim(); + if (cleanedLine === '[DONE]') { + return; // skip the [DONE] signal processing + } + + if (cleanedLine) { + const parsedLine = JSON.parse(cleanedLine); + options.onMessage?.(parsedLine); + } + } catch (error) { + console.debug('Error parsing line:', line); + } + } + }); + + // check if it has been cancelled + if (combinedSignal.aborted) { + requestState.isProcessing = false; + requestState.currentReader = null; + throw new Error('Request was aborted'); + } + + await processStream(); + } catch (error) { + if ((error as Error).message === 'Request was aborted') { + options.onComplete?.(); + } else { + throw error; // rethrow other errors + } + } + }; + + await processStream(); + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : 'Unknown error'; + + // if the error is caused by cancellation, do not treat it as an error + if ( + errorMessage !== 'The user aborted a request' && + errorMessage !== 'Request was aborted' + ) { + console.error('Request AI Error:', errorMessage); + options.onError?.(new Error(errorMessage)); + } else { + console.log('Request was cancelled by user'); + options.onComplete?.(); // cancellation is also considered complete + } + } finally { + requestState.isProcessing = false; + requestState.currentReader = null; + } +}; + +// add a function to cancel the current request +const cancelCurrentRequest = () => { + if (requestState.abortController) { + requestState.abortController.abort(); + console.log('AI request cancelled by user'); + return true; + } + return false; +}; + +export { cancelCurrentRequest }; +export default requestAi; From 9fbf9e4ff44aca7d6aa3ca112215d54652f7ef2b Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Fri, 23 Jan 2026 17:22:13 +0800 Subject: [PATCH 81/92] fix: correct loop iteration in AI conversation rounds --- internal/controller/ai_controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/controller/ai_controller.go b/internal/controller/ai_controller.go index aa7d2819b..85db78a93 100644 --- a/internal/controller/ai_controller.go +++ b/internal/controller/ai_controller.go @@ -433,7 +433,7 @@ func (c *AIController) handleAIConversation(ctx *gin.Context, w http.ResponseWri maxRounds := 10 messages := conversationCtx.GetOpenAIMessages() - for round := 0; round < maxRounds; round++ { + for round := range maxRounds { log.Debugf("AI conversation round: %d", round+1) aiReq := openai.ChatCompletionRequest{ From ce5aadf30dba2d7a9d01362a4e39af07c51030a2 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Fri, 23 Jan 2026 17:09:05 +0800 Subject: [PATCH 82/92] feat: add AI configuration support with related controllers and services --- cmd/wire_gen.go | 17 +- go.sum | 22 +- internal/base/constant/ai_config.go | 49 ++ internal/base/constant/site_type.go | 3 + internal/base/middleware/mcp_auth.go | 47 ++ internal/base/reason/reason.go | 1 + internal/base/translator/provider.go | 6 +- internal/controller/ai_controller.go | 756 ++++++++++++++++++ .../controller/ai_conversation_controller.go | 130 +++ internal/controller/controller.go | 3 + internal/controller/mcp_controller.go | 351 ++++++++ internal/controller/siteinfo_controller.go | 7 + .../ai_conversation_admin_controller.go | 123 +++ internal/controller_admin/controller.go | 2 + .../controller_admin/e_api_key_controller.go | 116 +++ .../controller_admin/siteinfo_controller.go | 102 +++ internal/entity/ai_conversation.go | 37 + internal/entity/ai_conversation_record.go | 40 + internal/entity/api_key_entity.go | 42 + internal/migrations/migrations.go | 1 + internal/migrations/v32.go | 116 +++ .../ai_conversation/ai_conversation_repo.go | 205 +++++ internal/repo/api_key/api_key_repo.go | 83 ++ internal/repo/provider.go | 4 + internal/repo/site_info/siteinfo_repo.go | 10 +- internal/router/answer_api_router.go | 161 ++-- internal/schema/ai_config_schema.go | 51 ++ internal/schema/ai_conversation_schema.go | 123 +++ internal/schema/api_key_schema.go | 60 ++ internal/schema/mcp_schema.go | 194 +++++ internal/schema/mcp_tools/mcp_tools.go | 105 +++ internal/schema/siteinfo_schema.go | 52 ++ .../ai_conversation_service.go | 372 +++++++++ internal/service/apikey/apikey_service.go | 116 +++ .../feature_toggle/feature_toggle_service.go | 130 +++ internal/service/mock/siteinfo_repo_mock.go | 30 +- internal/service/provider.go | 6 + internal/service/siteinfo/siteinfo_service.go | 223 ++++++ .../siteinfo_common/siteinfo_service.go | 22 +- 39 files changed, 3843 insertions(+), 75 deletions(-) create mode 100644 internal/base/constant/ai_config.go create mode 100644 internal/base/middleware/mcp_auth.go create mode 100644 internal/controller/ai_controller.go create mode 100644 internal/controller/ai_conversation_controller.go create mode 100644 internal/controller/mcp_controller.go create mode 100644 internal/controller_admin/ai_conversation_admin_controller.go create mode 100644 internal/controller_admin/e_api_key_controller.go create mode 100644 internal/entity/ai_conversation.go create mode 100644 internal/entity/ai_conversation_record.go create mode 100644 internal/entity/api_key_entity.go create mode 100644 internal/migrations/v32.go create mode 100644 internal/repo/ai_conversation/ai_conversation_repo.go create mode 100644 internal/repo/api_key/api_key_repo.go create mode 100644 internal/schema/ai_config_schema.go create mode 100644 internal/schema/ai_conversation_schema.go create mode 100644 internal/schema/api_key_schema.go create mode 100644 internal/schema/mcp_schema.go create mode 100644 internal/schema/mcp_tools/mcp_tools.go create mode 100644 internal/service/ai_conversation/ai_conversation_service.go create mode 100644 internal/service/apikey/apikey_service.go create mode 100644 internal/service/feature_toggle/feature_toggle_service.go diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index 5b9990213..24d32f7eb 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -38,7 +38,9 @@ import ( "github.com/apache/answer/internal/controller_admin" "github.com/apache/answer/internal/repo/activity" "github.com/apache/answer/internal/repo/activity_common" + "github.com/apache/answer/internal/repo/ai_conversation" "github.com/apache/answer/internal/repo/answer" + "github.com/apache/answer/internal/repo/api_key" "github.com/apache/answer/internal/repo/auth" "github.com/apache/answer/internal/repo/badge" "github.com/apache/answer/internal/repo/badge_award" @@ -73,7 +75,9 @@ import ( activity2 "github.com/apache/answer/internal/service/activity" activity_common2 "github.com/apache/answer/internal/service/activity_common" "github.com/apache/answer/internal/service/activityqueue" + ai_conversation2 "github.com/apache/answer/internal/service/ai_conversation" "github.com/apache/answer/internal/service/answer_common" + "github.com/apache/answer/internal/service/apikey" auth2 "github.com/apache/answer/internal/service/auth" badge2 "github.com/apache/answer/internal/service/badge" collection2 "github.com/apache/answer/internal/service/collection" @@ -85,6 +89,7 @@ import ( "github.com/apache/answer/internal/service/dashboard" "github.com/apache/answer/internal/service/eventqueue" export2 "github.com/apache/answer/internal/service/export" + "github.com/apache/answer/internal/service/feature_toggle" file_record2 "github.com/apache/answer/internal/service/file_record" "github.com/apache/answer/internal/service/follow" "github.com/apache/answer/internal/service/importer" @@ -274,7 +279,17 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, badgeService := badge2.NewBadgeService(badgeRepo, badgeGroupRepo, badgeAwardRepo, badgeEventService, siteInfoCommonService) badgeController := controller.NewBadgeController(badgeService, badgeAwardService) controller_adminBadgeController := controller_admin.NewBadgeController(badgeService) - answerAPIRouter := router.NewAnswerAPIRouter(langController, userController, commentController, reportController, voteController, tagController, followController, collectionController, questionController, answerController, searchController, revisionController, rankController, userAdminController, reasonController, themeController, siteInfoController, controllerSiteInfoController, notificationController, dashboardController, uploadController, activityController, roleController, pluginController, permissionController, userPluginController, reviewController, metaController, badgeController, controller_adminBadgeController) + apiKeyRepo := api_key.NewAPIKeyRepo(dataData) + apiKeyService := apikey.NewAPIKeyService(apiKeyRepo) + adminAPIKeyController := controller_admin.NewAdminAPIKeyController(apiKeyService) + featureToggleService := feature_toggle.NewFeatureToggleService(siteInfoRepo) + mcpController := controller.NewMCPController(searchService, siteInfoCommonService, tagCommonService, questionCommon, commentRepo, userCommon, answerRepo, featureToggleService) + aiConversationRepo := ai_conversation.NewAIConversationRepo(dataData) + aiConversationService := ai_conversation2.NewAIConversationService(aiConversationRepo, userCommon) + aiController := controller.NewAIController(searchService, siteInfoCommonService, tagCommonService, questionCommon, commentRepo, userCommon, answerRepo, mcpController, aiConversationService, featureToggleService) + aiConversationController := controller.NewAIConversationController(aiConversationService, featureToggleService) + aiConversationAdminController := controller_admin.NewAIConversationAdminController(aiConversationService, featureToggleService) + answerAPIRouter := router.NewAnswerAPIRouter(langController, userController, commentController, reportController, voteController, tagController, followController, collectionController, questionController, answerController, searchController, revisionController, rankController, userAdminController, reasonController, themeController, siteInfoController, controllerSiteInfoController, notificationController, dashboardController, uploadController, activityController, roleController, pluginController, permissionController, userPluginController, reviewController, metaController, badgeController, controller_adminBadgeController, adminAPIKeyController, aiController, aiConversationController, aiConversationAdminController) swaggerRouter := router.NewSwaggerRouter(swaggerConf) uiRouter := router.NewUIRouter(controllerSiteInfoController, siteInfoCommonService) authUserMiddleware := middleware.NewAuthUserMiddleware(authService, siteInfoCommonService) diff --git a/go.sum b/go.sum index 69d97751e..bf30d85b3 100644 --- a/go.sum +++ b/go.sum @@ -54,10 +54,14 @@ github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg= @@ -197,6 +201,8 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4= +github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= @@ -301,6 +307,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= +github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= @@ -410,6 +418,8 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mark3labs/mcp-go v0.43.2 h1:21PUSlWWiSbUPQwXIJ5WKlETixpFpq+WBpbMGDSVy/I= +github.com/mark3labs/mcp-go v0.43.2/go.mod h1:YnJfOL382MIWDx1kMY+2zsRHU/q78dBg9aFb8W6Thdw= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -543,6 +553,8 @@ github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sashabaranov/go-openai v1.41.2 h1:vfPRBZNMpnqu8ELsclWcAvF19lDNgh1t6TVfFFOPiSM= +github.com/sashabaranov/go-openai v1.41.2/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405 h1:2ieGkj4z/YPXVyQ2ayZUg3GwE1pYWd5f1RB6DzAOXKM= github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405/go.mod h1:rIxVzVLKlBwLxO+lC+k/I4HJfRQcemg/f/76Xmmzsec= @@ -576,8 +588,8 @@ github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9yS github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= -github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= @@ -630,6 +642,8 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -638,6 +652,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= +github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -801,6 +817,8 @@ golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/internal/base/constant/ai_config.go b/internal/base/constant/ai_config.go new file mode 100644 index 000000000..aa733bbaf --- /dev/null +++ b/internal/base/constant/ai_config.go @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package constant + +const ( + AIConfigProvider = "ai_config.provider" +) + +const ( + DefaultAIPromptConfigZhCN = `你是一个智能助手,可以帮助用户查询系统中的信息。用户问题:%s + +你可以使用以下工具来查询系统信息: +- get_questions: 搜索系统中已存在的问题,使用这个工具可以获取问题列表后注意需要使用 get_answers_by_question_id 获取问题的答案 +- get_answers_by_question_id: 根据问题ID获取该问题的所有答案 +- get_comments: 搜索评论信息 +- get_tags: 搜索标签信息 +- get_tag_detail: 获取特定标签的详细信息 +- get_user: 搜索用户信息 + +请根据用户的问题智能地使用这些工具来提供准确的答案。如果需要查询系统信息,请先使用相应的工具获取数据。` + DefaultAIPromptConfigEnUS = `You are an intelligent assistant that can help users query information in the system. User question: %s + +You can use the following tools to query system information: +- get_questions: Search for existing questions in the system. After using this tool to get the question list, you need to use get_answers_by_question_id to get the answers to the questions +- get_answers_by_question_id: Get all answers for a question based on question ID +- get_comments: Search for comment information +- get_tags: Search for tag information +- get_tag_detail: Get detailed information about a specific tag +- get_user: Search for user information + +Please intelligently use these tools based on the user's question to provide accurate answers. If you need to query system information, please use the appropriate tools to get the data first.` +) diff --git a/internal/base/constant/site_type.go b/internal/base/constant/site_type.go index 44cd0abd7..64ea9c4ae 100644 --- a/internal/base/constant/site_type.go +++ b/internal/base/constant/site_type.go @@ -44,4 +44,7 @@ const ( SiteTypePolicies = "policies" SiteTypeSecurity = "security" + SiteTypeAI = "ai" + SiteTypeFeatureToggle = "feature-toggle" + SiteTypeMCP = "mcp" ) diff --git a/internal/base/middleware/mcp_auth.go b/internal/base/middleware/mcp_auth.go new file mode 100644 index 000000000..6da056bae --- /dev/null +++ b/internal/base/middleware/mcp_auth.go @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package middleware + +import ( + "github.com/apache/answer/internal/base/handler" + "github.com/apache/answer/internal/base/reason" + "github.com/gin-gonic/gin" + "github.com/segmentfault/pacman/errors" + "github.com/segmentfault/pacman/log" +) + +// AuthMcpEnable check mcp is enabled +func (am *AuthUserMiddleware) AuthMcpEnable() gin.HandlerFunc { + return func(ctx *gin.Context) { + mcpConfig, err := am.siteInfoCommonService.GetSiteMCP(ctx) + if err != nil { + handler.HandleResponse(ctx, errors.InternalServer(reason.UnknownError), nil) + ctx.Abort() + return + } + if mcpConfig != nil && mcpConfig.Enabled { + ctx.Next() + return + } + handler.HandleResponse(ctx, errors.Forbidden(reason.ForbiddenError), nil) + ctx.Abort() + log.Error("abort mcp auth middleware, get mcp config error: ", err) + } +} diff --git a/internal/base/reason/reason.go b/internal/base/reason/reason.go index 97aaa75a9..b4c569a03 100644 --- a/internal/base/reason/reason.go +++ b/internal/base/reason/reason.go @@ -117,6 +117,7 @@ const ( UserStatusSuspendedForever = "error.user.status_suspended_forever" UserStatusSuspendedUntil = "error.user.status_suspended_until" UserStatusDeleted = "error.user.status_deleted" + ErrFeatureDisabled = "error.feature.disabled" ) // user external login reasons diff --git a/internal/base/translator/provider.go b/internal/base/translator/provider.go index 1a465b1e8..4f0059e36 100644 --- a/internal/base/translator/provider.go +++ b/internal/base/translator/provider.go @@ -242,16 +242,14 @@ func inspectTranslatorNode(node any, path []string, isRoot bool) error { return nil case []any: for idx, child := range data { - nextPath := append(path, fmt.Sprintf("[%d]", idx)) - if err := inspectTranslatorNode(child, nextPath, false); err != nil { + if err := inspectTranslatorNode(child, append(path, fmt.Sprintf("[%d]", idx)), false); err != nil { return err } } return nil case []map[string]any: for idx, child := range data { - nextPath := append(path, fmt.Sprintf("[%d]", idx)) - if err := inspectTranslatorNode(child, nextPath, false); err != nil { + if err := inspectTranslatorNode(child, append(path, fmt.Sprintf("[%d]", idx)), false); err != nil { return err } } diff --git a/internal/controller/ai_controller.go b/internal/controller/ai_controller.go new file mode 100644 index 000000000..aa7d2819b --- /dev/null +++ b/internal/controller/ai_controller.go @@ -0,0 +1,756 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package controller + +import ( + "context" + "encoding/json" + "fmt" + "maps" + "net/http" + "strings" + "time" + + "github.com/apache/answer/internal/base/constant" + "github.com/apache/answer/internal/base/handler" + "github.com/apache/answer/internal/base/middleware" + "github.com/apache/answer/internal/schema" + "github.com/apache/answer/internal/schema/mcp_tools" + "github.com/apache/answer/internal/service/ai_conversation" + answercommon "github.com/apache/answer/internal/service/answer_common" + "github.com/apache/answer/internal/service/comment" + "github.com/apache/answer/internal/service/content" + "github.com/apache/answer/internal/service/feature_toggle" + questioncommon "github.com/apache/answer/internal/service/question_common" + "github.com/apache/answer/internal/service/siteinfo_common" + tagcommonser "github.com/apache/answer/internal/service/tag_common" + usercommon "github.com/apache/answer/internal/service/user_common" + "github.com/apache/answer/pkg/token" + "github.com/gin-gonic/gin" + "github.com/mark3labs/mcp-go/mcp" + "github.com/sashabaranov/go-openai" + "github.com/segmentfault/pacman/errors" + "github.com/segmentfault/pacman/i18n" + "github.com/segmentfault/pacman/log" +) + +type AIController struct { + searchService *content.SearchService + siteInfoService siteinfo_common.SiteInfoCommonService + tagCommonService *tagcommonser.TagCommonService + questioncommon *questioncommon.QuestionCommon + commentRepo comment.CommentRepo + userCommon *usercommon.UserCommon + answerRepo answercommon.AnswerRepo + mcpController *MCPController + aiConversationService ai_conversation.AIConversationService + featureToggleSvc *feature_toggle.FeatureToggleService +} + +// NewAIController new site info controller. +func NewAIController( + searchService *content.SearchService, + siteInfoService siteinfo_common.SiteInfoCommonService, + tagCommonService *tagcommonser.TagCommonService, + questioncommon *questioncommon.QuestionCommon, + commentRepo comment.CommentRepo, + userCommon *usercommon.UserCommon, + answerRepo answercommon.AnswerRepo, + mcpController *MCPController, + aiConversationService ai_conversation.AIConversationService, + featureToggleSvc *feature_toggle.FeatureToggleService, +) *AIController { + return &AIController{ + searchService: searchService, + siteInfoService: siteInfoService, + tagCommonService: tagCommonService, + questioncommon: questioncommon, + commentRepo: commentRepo, + userCommon: userCommon, + answerRepo: answerRepo, + mcpController: mcpController, + aiConversationService: aiConversationService, + featureToggleSvc: featureToggleSvc, + } +} + +func (c *AIController) ensureAIChatEnabled(ctx *gin.Context) bool { + if c.featureToggleSvc == nil { + return true + } + if err := c.featureToggleSvc.EnsureEnabled(ctx, feature_toggle.FeatureAIChatbot); err != nil { + handler.HandleResponse(ctx, err, nil) + return false + } + return true +} + +type ChatCompletionsRequest struct { + Messages []Message `validate:"required,gte=1" json:"messages"` + ConversationID string `json:"conversation_id"` + UserID string `json:"-"` +} + +type Message struct { + Role string `json:"role" binding:"required"` + Content string `json:"content" binding:"required"` +} + +type ChatCompletionsResponse struct { + ID string `json:"id"` + Object string `json:"object"` + Created int64 `json:"created"` + Model string `json:"model"` + Choices []Choice `json:"choices"` + Usage Usage `json:"usage"` +} + +type StreamResponse struct { + ChatCompletionID string `json:"chat_completion_id"` + Object string `json:"object"` + Created int64 `json:"created"` + Model string `json:"model"` + Choices []StreamChoice `json:"choices"` +} + +type Choice struct { + Index int `json:"index"` + Message Message `json:"message"` + FinishReason string `json:"finish_reason"` +} + +type StreamChoice struct { + Index int `json:"index"` + Delta Delta `json:"delta"` + FinishReason *string `json:"finish_reason"` +} + +type Delta struct { + Role string `json:"role,omitempty"` + Content string `json:"content,omitempty"` +} + +type Usage struct { + PromptTokens int `json:"prompt_tokens"` + CompletionTokens int `json:"completion_tokens"` + TotalTokens int `json:"total_tokens"` +} + +type ConversationContext struct { + ConversationID string + UserID string + UserQuestion string + Messages []*ai_conversation.ConversationMessage + IsNewConversation bool + Model string +} + +func (c *ConversationContext) GetOpenAIMessages() []openai.ChatCompletionMessage { + messages := make([]openai.ChatCompletionMessage, len(c.Messages)) + for i, msg := range c.Messages { + messages[i] = openai.ChatCompletionMessage{ + Role: msg.Role, + Content: msg.Content, + } + } + return messages +} + +// sendStreamData +func sendStreamData(w http.ResponseWriter, data StreamResponse) { + jsonData, err := json.Marshal(data) + if err != nil { + return + } + + _, _ = fmt.Fprintf(w, "data: %s\n\n", string(jsonData)) + if f, ok := w.(http.Flusher); ok { + f.Flush() + } +} + +func (c *AIController) ChatCompletions(ctx *gin.Context) { + if !c.ensureAIChatEnabled(ctx) { + return + } + aiConfig, err := c.siteInfoService.GetSiteAI(context.Background()) + if err != nil { + log.Errorf("Failed to get AI config: %v", err) + handler.HandleResponse(ctx, errors.BadRequest("AI service configuration error"), nil) + return + } + + if !aiConfig.Enabled { + handler.HandleResponse(ctx, errors.ServiceUnavailable("AI service is not enabled"), nil) + return + } + + aiProvider := aiConfig.GetProvider() + + req := &ChatCompletionsRequest{} + if handler.BindAndCheck(ctx, req) { + return + } + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + data, _ := json.Marshal(req) + log.Infof("ai chat request data: %s", string(data)) + + ctx.Header("Content-Type", "text/event-stream") + ctx.Header("Cache-Control", "no-cache") + ctx.Header("Connection", "keep-alive") + ctx.Header("Access-Control-Allow-Origin", "*") + ctx.Header("Access-Control-Allow-Headers", "Cache-Control") + + ctx.Status(http.StatusOK) + + w := ctx.Writer + + if f, ok := w.(http.Flusher); ok { + f.Flush() + } + + chatcmplID := "chatcmpl-" + token.GenerateToken() + created := time.Now().Unix() + + firstResponse := StreamResponse{ + ChatCompletionID: chatcmplID, + Object: "chat.completion.chunk", + Created: time.Now().Unix(), + Model: aiProvider.Model, + Choices: []StreamChoice{{Index: 0, Delta: Delta{Role: "assistant"}, FinishReason: nil}}, + } + + sendStreamData(w, firstResponse) + + conversationCtx := c.initializeConversationContext(ctx, aiProvider.Model, req) + if conversationCtx == nil { + log.Error("Failed to initialize conversation context") + c.sendErrorResponse(w, chatcmplID, aiProvider.Model, "Failed to initialize conversation context") + return + } + + c.redirectRequestToAI(ctx, w, chatcmplID, conversationCtx) + + finishReason := "stop" + endResponse := StreamResponse{ + ChatCompletionID: chatcmplID, + Object: "chat.completion.chunk", + Created: created, + Model: aiProvider.Model, + Choices: []StreamChoice{{Index: 0, Delta: Delta{}, FinishReason: &finishReason}}, + } + + sendStreamData(w, endResponse) + + _, _ = fmt.Fprintf(w, "data: [DONE]\n\n") + if f, ok := w.(http.Flusher); ok { + f.Flush() + } + + c.saveConversationRecord(ctx, chatcmplID, conversationCtx) +} + +func (c *AIController) redirectRequestToAI(ctx *gin.Context, w http.ResponseWriter, id string, conversationCtx *ConversationContext) { + client := c.createOpenAIClient() + + c.handleAIConversation(ctx, w, id, client, conversationCtx) +} + +// createOpenAIClient +func (c *AIController) createOpenAIClient() *openai.Client { + config := openai.DefaultConfig("") + config.BaseURL = "" + + aiConfig, err := c.siteInfoService.GetSiteAI(context.Background()) + if err != nil { + log.Errorf("Failed to get AI config: %v", err) + return openai.NewClientWithConfig(config) + } + + if !aiConfig.Enabled { + log.Warn("AI feature is disabled") + return openai.NewClientWithConfig(config) + } + + aiProvider := aiConfig.GetProvider() + + config = openai.DefaultConfig(aiProvider.APIKey) + config.BaseURL = aiProvider.APIHost + if !strings.HasSuffix(config.BaseURL, "/v1") { + config.BaseURL += "/v1" + } + return openai.NewClientWithConfig(config) +} + +// getPromptByLanguage +func (c *AIController) getPromptByLanguage(language i18n.Language, question string) string { + aiConfig, err := c.siteInfoService.GetSiteAI(context.Background()) + if err != nil { + log.Errorf("Failed to get AI config: %v", err) + return c.getDefaultPrompt(language, question) + } + + var promptTemplate string + + switch language { + case i18n.LanguageChinese: + promptTemplate = aiConfig.PromptConfig.ZhCN + case i18n.LanguageEnglish: + promptTemplate = aiConfig.PromptConfig.EnUS + default: + promptTemplate = aiConfig.PromptConfig.EnUS + } + + if promptTemplate == "" { + return c.getDefaultPrompt(language, question) + } + + return fmt.Sprintf(promptTemplate, question) +} + +// getDefaultPrompt prompt +func (c *AIController) getDefaultPrompt(language i18n.Language, question string) string { + switch language { + case i18n.LanguageChinese: + return fmt.Sprintf(constant.DefaultAIPromptConfigZhCN, question) + case i18n.LanguageEnglish: + return fmt.Sprintf(constant.DefaultAIPromptConfigEnUS, question) + default: + return fmt.Sprintf(constant.DefaultAIPromptConfigEnUS, question) + } +} + +// initializeConversationContext +func (c *AIController) initializeConversationContext(ctx *gin.Context, model string, req *ChatCompletionsRequest) *ConversationContext { + if len(req.ConversationID) == 0 { + req.ConversationID = token.GenerateToken() + } + conversationCtx := &ConversationContext{ + UserID: req.UserID, + Messages: make([]*ai_conversation.ConversationMessage, 0), + ConversationID: req.ConversationID, + Model: model, + } + + conversationDetail, exist, err := c.aiConversationService.GetConversationDetail(ctx, &schema.AIConversationDetailReq{ + ConversationID: req.ConversationID, + UserID: req.UserID, + }) + if err != nil { + log.Errorf("Failed to get conversation detail: %v", err) + return nil + } + if !exist { + conversationCtx.UserQuestion = req.Messages[0].Content + conversationCtx.Messages = c.buildInitialMessages(ctx, req) + conversationCtx.IsNewConversation = true + return conversationCtx + } + conversationCtx.IsNewConversation = false + + for _, record := range conversationDetail.Records { + conversationCtx.Messages = append(conversationCtx.Messages, &ai_conversation.ConversationMessage{ + ChatCompletionID: record.ChatCompletionID, + Role: record.Role, + Content: record.Content, + }) + } + conversationCtx.Messages = append(conversationCtx.Messages, &ai_conversation.ConversationMessage{ + Role: req.Messages[0].Role, + Content: req.Messages[0].Content, + }) + return conversationCtx +} + +// buildInitialMessages +func (c *AIController) buildInitialMessages(ctx *gin.Context, req *ChatCompletionsRequest) []*ai_conversation.ConversationMessage { + question := "" + if len(req.Messages) == 1 { + question = req.Messages[0].Content + } else { + messages := make([]*ai_conversation.ConversationMessage, len(req.Messages)) + for i, msg := range req.Messages { + messages[i] = &ai_conversation.ConversationMessage{ + Role: msg.Role, + Content: msg.Content, + } + } + return messages + } + + currentLang := handler.GetLangByCtx(ctx) + + prompt := c.getPromptByLanguage(currentLang, question) + + return []*ai_conversation.ConversationMessage{{Role: openai.ChatMessageRoleUser, Content: prompt}} +} + +// saveConversationRecord +func (c *AIController) saveConversationRecord(ctx context.Context, chatcmplID string, conversationCtx *ConversationContext) { + if conversationCtx == nil || len(conversationCtx.Messages) == 0 { + return + } + + if conversationCtx.IsNewConversation { + topic := conversationCtx.UserQuestion + if topic == "" { + log.Warn("No user message found for new conversation") + return + } + + err := c.aiConversationService.CreateConversation(ctx, conversationCtx.UserID, conversationCtx.ConversationID, topic) + if err != nil { + log.Errorf("Failed to create conversation: %v", err) + return + } + } + + err := c.aiConversationService.SaveConversationRecords(ctx, conversationCtx.ConversationID, chatcmplID, conversationCtx.Messages) + if err != nil { + log.Errorf("Failed to save conversation records: %v", err) + } +} + +func (c *AIController) handleAIConversation(ctx *gin.Context, w http.ResponseWriter, id string, client *openai.Client, conversationCtx *ConversationContext) { + maxRounds := 10 + messages := conversationCtx.GetOpenAIMessages() + + for round := 0; round < maxRounds; round++ { + log.Debugf("AI conversation round: %d", round+1) + + aiReq := openai.ChatCompletionRequest{ + Model: conversationCtx.Model, + Messages: messages, + Tools: c.getMCPTools(), + Stream: true, + } + + toolCalls, newMessages, finished, aiResponse := c.processAIStream(ctx, w, id, conversationCtx.Model, client, aiReq, messages) + messages = newMessages + + if aiResponse != "" { + conversationCtx.Messages = append(conversationCtx.Messages, &ai_conversation.ConversationMessage{ + Role: "assistant", + Content: aiResponse, + }) + } + + if finished { + return + } + + if len(toolCalls) > 0 { + messages = c.executeToolCalls(ctx, w, id, conversationCtx.Model, toolCalls, messages) + } else { + return + } + } + + log.Warnf("AI conversation reached maximum rounds limit: %d", maxRounds) +} + +// processAIStream +func (c *AIController) processAIStream( + _ *gin.Context, w http.ResponseWriter, id, model string, client *openai.Client, aiReq openai.ChatCompletionRequest, messages []openai.ChatCompletionMessage) ( + []openai.ToolCall, []openai.ChatCompletionMessage, bool, string) { + stream, err := client.CreateChatCompletionStream(context.Background(), aiReq) + if err != nil { + log.Errorf("Failed to create stream: %v", err) + c.sendErrorResponse(w, id, model, "Failed to create AI stream") + return nil, messages, true, "" + } + defer func() { + _ = stream.Close() + }() + + var currentToolCalls []openai.ToolCall + var accumulatedContent strings.Builder + var accumulatedMessage openai.ChatCompletionMessage + toolCallsMap := make(map[int]*openai.ToolCall) + + for { + response, err := stream.Recv() + if err != nil { + if err.Error() == "EOF" { + log.Info("Stream finished") + break + } + log.Errorf("Stream error: %v", err) + break + } + + choice := response.Choices[0] + + if len(choice.Delta.ToolCalls) > 0 { + for _, deltaToolCall := range choice.Delta.ToolCalls { + index := *deltaToolCall.Index + + if _, exists := toolCallsMap[index]; !exists { + toolCallsMap[index] = &openai.ToolCall{ + ID: deltaToolCall.ID, + Type: deltaToolCall.Type, + Function: openai.FunctionCall{ + Name: deltaToolCall.Function.Name, + Arguments: deltaToolCall.Function.Arguments, + }, + } + } else { + if deltaToolCall.Function.Arguments != "" { + toolCallsMap[index].Function.Arguments += deltaToolCall.Function.Arguments + } + if deltaToolCall.Function.Name != "" { + toolCallsMap[index].Function.Name = deltaToolCall.Function.Name + } + } + } + } + + if choice.Delta.Content != "" { + accumulatedContent.WriteString(choice.Delta.Content) + + contentResponse := StreamResponse{ + ChatCompletionID: id, + Object: "chat.completion.chunk", + Created: time.Now().Unix(), + Model: model, + Choices: []StreamChoice{ + { + Index: 0, + Delta: Delta{ + Content: choice.Delta.Content, + }, + FinishReason: nil, + }, + }, + } + sendStreamData(w, contentResponse) + } + + if len(choice.FinishReason) > 0 { + if choice.FinishReason == "tool_calls" { + for _, toolCall := range toolCallsMap { + currentToolCalls = append(currentToolCalls, *toolCall) + } + return currentToolCalls, messages, false, accumulatedContent.String() + } else { + aiResponseContent := accumulatedContent.String() + if aiResponseContent != "" { + accumulatedMessage = openai.ChatCompletionMessage{ + Role: openai.ChatMessageRoleAssistant, + Content: aiResponseContent, + } + messages = append(messages, accumulatedMessage) + } + return nil, messages, true, aiResponseContent + } + } + } + + aiResponseContent := accumulatedContent.String() + if aiResponseContent != "" { + accumulatedMessage = openai.ChatCompletionMessage{ + Role: openai.ChatMessageRoleAssistant, + Content: aiResponseContent, + } + messages = append(messages, accumulatedMessage) + } + + if len(toolCallsMap) > 0 { + for _, toolCall := range toolCallsMap { + currentToolCalls = append(currentToolCalls, *toolCall) + } + return currentToolCalls, messages, false, aiResponseContent + } + + return currentToolCalls, messages, len(currentToolCalls) == 0, aiResponseContent +} + +// executeToolCalls +func (c *AIController) executeToolCalls(ctx *gin.Context, _ http.ResponseWriter, _, _ string, toolCalls []openai.ToolCall, messages []openai.ChatCompletionMessage) []openai.ChatCompletionMessage { + validToolCalls := make([]openai.ToolCall, 0) + for _, toolCall := range toolCalls { + if toolCall.ID == "" || toolCall.Function.Name == "" { + log.Errorf("Invalid tool call: missing required fields. ID: %s, Function: %v", toolCall.ID, toolCall.Function) + continue + } + + if toolCall.Function.Arguments == "" { + toolCall.Function.Arguments = "{}" + } + + validToolCalls = append(validToolCalls, toolCall) + log.Debugf("Valid tool call: ID=%s, Name=%s, Arguments=%s", toolCall.ID, toolCall.Function.Name, toolCall.Function.Arguments) + } + + if len(validToolCalls) == 0 { + log.Warn("No valid tool calls found") + return messages + } + + assistantMsg := openai.ChatCompletionMessage{ + Role: openai.ChatMessageRoleAssistant, + ToolCalls: validToolCalls, + } + messages = append(messages, assistantMsg) + + for _, toolCall := range validToolCalls { + if toolCall.Function.Name != "" { + var args map[string]interface{} + if err := json.Unmarshal([]byte(toolCall.Function.Arguments), &args); err != nil { + log.Errorf("Failed to parse tool arguments for %s: %v, arguments: %s", toolCall.Function.Name, err, toolCall.Function.Arguments) + errorResult := fmt.Sprintf("Error parsing tool arguments: %v", err) + toolMessage := openai.ChatCompletionMessage{ + Role: openai.ChatMessageRoleTool, + Content: errorResult, + ToolCallID: toolCall.ID, + } + messages = append(messages, toolMessage) + continue + } + + result, err := c.callMCPTool(ctx, toolCall.Function.Name, args) + if err != nil { + log.Errorf("Failed to call MCP tool %s: %v", toolCall.Function.Name, err) + result = fmt.Sprintf("Error calling tool %s: %v", toolCall.Function.Name, err) + } + + toolMessage := openai.ChatCompletionMessage{ + Role: openai.ChatMessageRoleTool, + Content: result, + ToolCallID: toolCall.ID, + } + messages = append(messages, toolMessage) + } + } + + return messages +} + +// sendErrorResponse send error response in stream +func (c *AIController) sendErrorResponse(w http.ResponseWriter, id, model, errorMsg string) { + errorResponse := StreamResponse{ + ChatCompletionID: id, + Object: "chat.completion.chunk", + Created: time.Now().Unix(), + Model: model, + Choices: []StreamChoice{ + { + Index: 0, + Delta: Delta{ + Content: fmt.Sprintf("Error: %s", errorMsg), + }, + FinishReason: nil, + }, + }, + } + sendStreamData(w, errorResponse) +} + +// getMCPTools +func (c *AIController) getMCPTools() []openai.Tool { + openaiTools := make([]openai.Tool, 0) + for _, mcpTool := range mcp_tools.MCPToolsList { + openaiTool := c.convertMCPToolToOpenAI(mcpTool) + openaiTools = append(openaiTools, openaiTool) + } + + return openaiTools +} + +// convertMCPToolToOpenAI +func (c *AIController) convertMCPToolToOpenAI(mcpTool mcp.Tool) openai.Tool { + properties := make(map[string]interface{}) + required := make([]string, 0) + + maps.Copy(properties, mcpTool.InputSchema.Properties) + + required = append(required, mcpTool.InputSchema.Required...) + + parameters := map[string]interface{}{ + "type": "object", + "properties": properties, + } + + if len(required) > 0 { + parameters["required"] = required + } + + return openai.Tool{ + Type: openai.ToolTypeFunction, + Function: &openai.FunctionDefinition{ + Name: mcpTool.Name, + Description: mcpTool.Description, + Parameters: parameters, + }, + } +} + +// callMCPTool +func (c *AIController) callMCPTool(ctx context.Context, toolName string, arguments map[string]interface{}) (string, error) { + request := mcp.CallToolRequest{ + Request: mcp.Request{}, + Params: struct { + Name string `json:"name"` + Arguments any `json:"arguments,omitempty"` + Meta *mcp.Meta `json:"_meta,omitempty"` + }{ + Name: toolName, + Arguments: arguments, + }, + } + + var result *mcp.CallToolResult + var err error + + log.Debugf("Calling MCP tool: %s with arguments: %v", toolName, arguments) + + switch toolName { + case "get_questions": + result, err = c.mcpController.MCPQuestionsHandler()(ctx, request) + case "get_answers_by_question_id": + result, err = c.mcpController.MCPAnswersHandler()(ctx, request) + case "get_comments": + result, err = c.mcpController.MCPCommentsHandler()(ctx, request) + case "get_tags": + result, err = c.mcpController.MCPTagsHandler()(ctx, request) + case "get_tag_detail": + result, err = c.mcpController.MCPTagDetailsHandler()(ctx, request) + case "get_user": + result, err = c.mcpController.MCPUserDetailsHandler()(ctx, request) + default: + return "", fmt.Errorf("unknown tool: %s", toolName) + } + + if err != nil { + return "", err + } + + data, _ := json.Marshal(result) + log.Debugf("MCP tool %s called successfully, result: %v", toolName, string(data)) + + if result != nil && len(result.Content) > 0 { + if textContent, ok := result.Content[0].(mcp.TextContent); ok { + return textContent.Text, nil + } + } + + return "No result found", nil +} diff --git a/internal/controller/ai_conversation_controller.go b/internal/controller/ai_conversation_controller.go new file mode 100644 index 000000000..1b8debd78 --- /dev/null +++ b/internal/controller/ai_conversation_controller.go @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package controller + +import ( + "github.com/apache/answer/internal/base/handler" + "github.com/apache/answer/internal/base/middleware" + "github.com/apache/answer/internal/schema" + "github.com/apache/answer/internal/service/ai_conversation" + "github.com/apache/answer/internal/service/feature_toggle" + "github.com/gin-gonic/gin" +) + +// AIConversationController ai conversation controller +type AIConversationController struct { + aiConversationService ai_conversation.AIConversationService + featureToggleSvc *feature_toggle.FeatureToggleService +} + +// NewAIConversationController creates a new AI conversation controller +func NewAIConversationController( + aiConversationService ai_conversation.AIConversationService, + featureToggleSvc *feature_toggle.FeatureToggleService, +) *AIConversationController { + return &AIConversationController{ + aiConversationService: aiConversationService, + featureToggleSvc: featureToggleSvc, + } +} + +func (ctrl *AIConversationController) ensureEnabled(ctx *gin.Context) bool { + if ctrl.featureToggleSvc == nil { + return true + } + if err := ctrl.featureToggleSvc.EnsureEnabled(ctx, feature_toggle.FeatureAIChatbot); err != nil { + handler.HandleResponse(ctx, err, nil) + return false + } + return true +} + +// GetConversationList gets conversation list +// @Summary get conversation list +// @Description get conversation list +// @Tags ai-conversation +// @Accept json +// @Produce json +// @Param page query int false "page" +// @Param page_size query int false "page size" +// @Success 200 {object} handler.RespBody{data=pager.PageModel{list=[]schema.AIConversationListItem}} +// @Router /answer/api/v1/ai/conversation/page [get] +func (ctrl *AIConversationController) GetConversationList(ctx *gin.Context) { + if !ctrl.ensureEnabled(ctx) { + return + } + req := &schema.AIConversationListReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + resp, err := ctrl.aiConversationService.GetConversationList(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// GetConversationDetail gets conversation detail +// @Summary get conversation detail +// @Description get conversation detail +// @Tags ai-conversation +// @Accept json +// @Produce json +// @Param conversation_id query string true "conversation id" +// @Success 200 {object} handler.RespBody{data=schema.AIConversationDetailResp} +// @Router /answer/api/v1/ai/conversation [get] +func (ctrl *AIConversationController) GetConversationDetail(ctx *gin.Context) { + if !ctrl.ensureEnabled(ctx) { + return + } + req := &schema.AIConversationDetailReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + resp, _, err := ctrl.aiConversationService.GetConversationDetail(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// VoteRecord vote record +// @Summary vote record +// @Description vote record +// @Tags ai-conversation +// @Accept json +// @Produce json +// @Param data body schema.AIConversationVoteReq true "vote request" +// @Success 200 {object} handler.RespBody +// @Router /answer/api/v1/ai/conversation/vote [post] +func (ctrl *AIConversationController) VoteRecord(ctx *gin.Context) { + if !ctrl.ensureEnabled(ctx) { + return + } + req := &schema.AIConversationVoteReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + err := ctrl.aiConversationService.VoteRecord(ctx, req) + handler.HandleResponse(ctx, err, nil) +} diff --git a/internal/controller/controller.go b/internal/controller/controller.go index b5c3f91c4..c31763bea 100644 --- a/internal/controller/controller.go +++ b/internal/controller/controller.go @@ -54,4 +54,7 @@ var ProviderSetController = wire.NewSet( NewBadgeController, NewRenderController, NewSidebarController, + NewMCPController, + NewAIController, + NewAIConversationController, ) diff --git a/internal/controller/mcp_controller.go b/internal/controller/mcp_controller.go new file mode 100644 index 000000000..d52f57979 --- /dev/null +++ b/internal/controller/mcp_controller.go @@ -0,0 +1,351 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package controller + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + "github.com/apache/answer/internal/base/pager" + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/schema" + answercommon "github.com/apache/answer/internal/service/answer_common" + "github.com/apache/answer/internal/service/comment" + "github.com/apache/answer/internal/service/content" + "github.com/apache/answer/internal/service/feature_toggle" + questioncommon "github.com/apache/answer/internal/service/question_common" + "github.com/apache/answer/internal/service/siteinfo_common" + tagcommonser "github.com/apache/answer/internal/service/tag_common" + usercommon "github.com/apache/answer/internal/service/user_common" + "github.com/mark3labs/mcp-go/mcp" + "github.com/segmentfault/pacman/log" +) + +type MCPController struct { + searchService *content.SearchService + siteInfoService siteinfo_common.SiteInfoCommonService + tagCommonService *tagcommonser.TagCommonService + questioncommon *questioncommon.QuestionCommon + commentRepo comment.CommentRepo + userCommon *usercommon.UserCommon + answerRepo answercommon.AnswerRepo + featureToggleSvc *feature_toggle.FeatureToggleService +} + +// NewMCPController new site info controller. +func NewMCPController( + searchService *content.SearchService, + siteInfoService siteinfo_common.SiteInfoCommonService, + tagCommonService *tagcommonser.TagCommonService, + questioncommon *questioncommon.QuestionCommon, + commentRepo comment.CommentRepo, + userCommon *usercommon.UserCommon, + answerRepo answercommon.AnswerRepo, + featureToggleSvc *feature_toggle.FeatureToggleService, +) *MCPController { + return &MCPController{ + searchService: searchService, + siteInfoService: siteInfoService, + tagCommonService: tagCommonService, + questioncommon: questioncommon, + commentRepo: commentRepo, + userCommon: userCommon, + answerRepo: answerRepo, + featureToggleSvc: featureToggleSvc, + } +} + +func (c *MCPController) ensureMCPEnabled(ctx context.Context) error { + if c.featureToggleSvc == nil { + return nil + } + return c.featureToggleSvc.EnsureEnabled(ctx, feature_toggle.FeatureMCP) +} + +func (c *MCPController) MCPQuestionsHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchCond(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + searchResp, err := c.searchService.Search(ctx, &schema.SearchDTO{ + Query: cond.ToQueryString() + " is:question", + Page: 1, + Size: 5, + Order: "newest", + }) + if err != nil { + return nil, err + } + + resp := make([]*schema.MCPSearchQuestionInfoResp, 0) + for _, question := range searchResp.SearchResults { + t := &schema.MCPSearchQuestionInfoResp{ + QuestionID: question.Object.QuestionID, + Title: question.Object.Title, + Content: question.Object.Excerpt, + Link: fmt.Sprintf("%s/questions/%s", siteGeneral.SiteUrl, question.Object.QuestionID), + } + resp = append(resp, t) + } + + data, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(data)), nil + } +} + +func (c *MCPController) MCPQuestionDetailHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchQuestionDetail(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + question, err := c.questioncommon.Info(ctx, cond.QuestionID, "") + if err != nil { + log.Errorf("get question failed: %v", err) + return mcp.NewToolResultText("No question found."), nil + } + + resp := &schema.MCPSearchQuestionInfoResp{ + QuestionID: question.ID, + Title: question.Title, + Content: question.Content, + Link: fmt.Sprintf("%s/questions/%s", siteGeneral.SiteUrl, question.ID), + } + res, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(res)), nil + } +} + +func (c *MCPController) MCPAnswersHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchAnswerCond(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + if len(cond.QuestionID) > 0 { + answerList, err := c.answerRepo.GetAnswerList(ctx, &entity.Answer{QuestionID: cond.QuestionID}) + if err != nil { + log.Errorf("get answers failed: %v", err) + return nil, err + } + resp := make([]*schema.MCPSearchAnswerInfoResp, 0) + for _, answer := range answerList { + t := &schema.MCPSearchAnswerInfoResp{ + QuestionID: answer.QuestionID, + AnswerID: answer.ID, + AnswerContent: answer.OriginalText, + Link: fmt.Sprintf("%s/questions/%s/answers/%s", siteGeneral.SiteUrl, answer.QuestionID, answer.ID), + } + resp = append(resp, t) + } + data, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(data)), nil + } + + answerList, err := c.answerRepo.GetAnswerList(ctx, &entity.Answer{QuestionID: cond.QuestionID}) + if err != nil { + log.Errorf("get answers failed: %v", err) + return nil, err + } + resp := make([]*schema.MCPSearchAnswerInfoResp, 0) + for _, answer := range answerList { + t := &schema.MCPSearchAnswerInfoResp{ + QuestionID: answer.QuestionID, + AnswerID: answer.ID, + AnswerContent: answer.OriginalText, + Link: fmt.Sprintf("%s/questions/%s/answers/%s", siteGeneral.SiteUrl, answer.QuestionID, answer.ID), + } + resp = append(resp, t) + } + data, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(data)), nil + } +} + +func (c *MCPController) MCPCommentsHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchCommentCond(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + dto := &comment.CommentQuery{ + PageCond: pager.PageCond{Page: 1, PageSize: 5}, + QueryCond: "newest", + ObjectID: cond.ObjectID, + } + commentList, total, err := c.commentRepo.GetCommentPage(ctx, dto) + if err != nil { + return nil, err + } + if total == 0 { + return mcp.NewToolResultText("No comments found."), nil + } + + resp := make([]*schema.MCPSearchCommentInfoResp, 0) + for _, comment := range commentList { + t := &schema.MCPSearchCommentInfoResp{ + CommentID: comment.ID, + Content: comment.OriginalText, + ObjectID: comment.ObjectID, + Link: fmt.Sprintf("%s/comments/%s", siteGeneral.SiteUrl, comment.ID), + } + resp = append(resp, t) + } + data, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(data)), nil + } +} + +func (c *MCPController) MCPTagsHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchTagCond(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + tags, total, err := c.tagCommonService.GetTagPage(ctx, 1, 10, &entity.Tag{DisplayName: cond.TagName}, "newest") + if err != nil { + log.Errorf("get tags failed: %v", err) + return nil, err + } + + if total == 0 { + res := strings.Builder{} + res.WriteString("No tags found.\n") + return mcp.NewToolResultText(res.String()), nil + } + + resp := make([]*schema.MCPSearchTagResp, 0) + for _, tag := range tags { + t := &schema.MCPSearchTagResp{ + TagName: tag.SlugName, + DisplayName: tag.DisplayName, + Description: tag.OriginalText, + Link: fmt.Sprintf("%s/tags/%s", siteGeneral.SiteUrl, tag.SlugName), + } + resp = append(resp, t) + } + data, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(data)), nil + } +} + +func (c *MCPController) MCPTagDetailsHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchTagCond(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + tag, exist, err := c.tagCommonService.GetTagBySlugName(ctx, cond.TagName) + if err != nil { + log.Errorf("get tag failed: %v", err) + return nil, err + } + if !exist { + return mcp.NewToolResultText("Tag not found."), nil + } + + resp := &schema.MCPSearchTagResp{ + TagName: tag.SlugName, + DisplayName: tag.DisplayName, + Description: tag.OriginalText, + Link: fmt.Sprintf("%s/tags/%s", siteGeneral.SiteUrl, tag.SlugName), + } + res, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(res)), nil + } +} + +func (c *MCPController) MCPUserDetailsHandler() func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + return func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + if err := c.ensureMCPEnabled(ctx); err != nil { + return nil, err + } + cond := schema.NewMCPSearchUserCond(request) + + siteGeneral, err := c.siteInfoService.GetSiteGeneral(ctx) + if err != nil { + log.Errorf("get site general info failed: %v", err) + return nil, err + } + + user, exist, err := c.userCommon.GetUserBasicInfoByUserName(ctx, cond.Username) + if err != nil { + log.Errorf("get user failed: %v", err) + return nil, err + } + if !exist { + return mcp.NewToolResultText("User not found."), nil + } + + resp := &schema.MCPSearchUserInfoResp{ + Username: user.Username, + DisplayName: user.DisplayName, + Avatar: user.Avatar, + Link: fmt.Sprintf("%s/users/%s", siteGeneral.SiteUrl, user.Username), + } + res, _ := json.Marshal(resp) + return mcp.NewToolResultText(string(res)), nil + } +} diff --git a/internal/controller/siteinfo_controller.go b/internal/controller/siteinfo_controller.go index 320c1b475..a5dde0234 100644 --- a/internal/controller/siteinfo_controller.go +++ b/internal/controller/siteinfo_controller.go @@ -110,6 +110,13 @@ func (sc *SiteInfoController) GetSiteInfo(ctx *gin.Context) { if security, err := sc.siteInfoService.GetSiteSecurity(ctx); err == nil { resp.Security = security } + if aiConf, err := sc.siteInfoService.GetSiteAI(ctx); err == nil { + resp.AIEnabled = aiConf.Enabled + } + + if mcpConf, err := sc.siteInfoService.GetSiteMCP(ctx); err == nil { + resp.MCPEnabled = mcpConf.Enabled + } handler.HandleResponse(ctx, nil, resp) } diff --git a/internal/controller_admin/ai_conversation_admin_controller.go b/internal/controller_admin/ai_conversation_admin_controller.go new file mode 100644 index 000000000..5802a7a8d --- /dev/null +++ b/internal/controller_admin/ai_conversation_admin_controller.go @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package controller_admin + +import ( + "github.com/apache/answer/internal/base/handler" + "github.com/apache/answer/internal/schema" + "github.com/apache/answer/internal/service/ai_conversation" + "github.com/apache/answer/internal/service/feature_toggle" + "github.com/gin-gonic/gin" +) + +// AIConversationAdminController ai conversation admin controller +type AIConversationAdminController struct { + aiConversationService ai_conversation.AIConversationService + featureToggleSvc *feature_toggle.FeatureToggleService +} + +// NewAIConversationAdminController new AI conversation admin controller +func NewAIConversationAdminController( + aiConversationService ai_conversation.AIConversationService, + featureToggleSvc *feature_toggle.FeatureToggleService, +) *AIConversationAdminController { + return &AIConversationAdminController{ + aiConversationService: aiConversationService, + featureToggleSvc: featureToggleSvc, + } +} + +func (ctrl *AIConversationAdminController) ensureEnabled(ctx *gin.Context) bool { + if ctrl.featureToggleSvc == nil { + return true + } + if err := ctrl.featureToggleSvc.EnsureEnabled(ctx, feature_toggle.FeatureAIChatbot); err != nil { + handler.HandleResponse(ctx, err, nil) + return false + } + return true +} + +// GetConversationList gets conversation list +// @Summary get conversation list for admin +// @Description get conversation list for admin +// @Tags ai-conversation-admin +// @Accept json +// @Produce json +// @Param page query int false "page" +// @Param page_size query int false "page size" +// @Success 200 {object} handler.RespBody{data=pager.PageModel{list=[]schema.AIConversationAdminListItem}} +// @Router /answer/admin/api/ai/conversation/page [get] +func (ctrl *AIConversationAdminController) GetConversationList(ctx *gin.Context) { + if !ctrl.ensureEnabled(ctx) { + return + } + req := &schema.AIConversationAdminListReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + resp, err := ctrl.aiConversationService.GetConversationListForAdmin(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// GetConversationDetail get conversation detail +// @Summary get conversation detail for admin +// @Description get conversation detail for admin +// @Tags ai-conversation-admin +// @Accept json +// @Produce json +// @Param conversation_id query string true "conversation id" +// @Success 200 {object} handler.RespBody{data=schema.AIConversationAdminDetailResp} +// @Router /answer/admin/api/ai/conversation [get] +func (ctrl *AIConversationAdminController) GetConversationDetail(ctx *gin.Context) { + if !ctrl.ensureEnabled(ctx) { + return + } + req := &schema.AIConversationAdminDetailReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + resp, err := ctrl.aiConversationService.GetConversationDetailForAdmin(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// DeleteConversation delete conversation +// @Summary delete conversation for admin +// @Description delete conversation and its related records for admin +// @Tags ai-conversation-admin +// @Accept json +// @Produce json +// @Param data body schema.AIConversationAdminDeleteReq true "apikey" +// @Success 200 {object} handler.RespBody +// @Router /answer/admin/api/ai/conversation [delete] +func (ctrl *AIConversationAdminController) DeleteConversation(ctx *gin.Context) { + if !ctrl.ensureEnabled(ctx) { + return + } + req := &schema.AIConversationAdminDeleteReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + err := ctrl.aiConversationService.DeleteConversationForAdmin(ctx, req) + handler.HandleResponse(ctx, err, nil) +} diff --git a/internal/controller_admin/controller.go b/internal/controller_admin/controller.go index ebf32cbfc..de0c7ec88 100644 --- a/internal/controller_admin/controller.go +++ b/internal/controller_admin/controller.go @@ -29,4 +29,6 @@ var ProviderSetController = wire.NewSet( NewRoleController, NewPluginController, NewBadgeController, + NewAdminAPIKeyController, + NewAIConversationAdminController, ) diff --git a/internal/controller_admin/e_api_key_controller.go b/internal/controller_admin/e_api_key_controller.go new file mode 100644 index 000000000..1b32b5350 --- /dev/null +++ b/internal/controller_admin/e_api_key_controller.go @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package controller_admin + +import ( + "github.com/apache/answer/internal/base/handler" + "github.com/apache/answer/internal/base/middleware" + "github.com/apache/answer/internal/schema" + "github.com/apache/answer/internal/service/apikey" + "github.com/gin-gonic/gin" +) + +// AdminAPIKeyController site info controller +type AdminAPIKeyController struct { + apiKeyService *apikey.APIKeyService +} + +// NewAdminAPIKeyController new site info controller +func NewAdminAPIKeyController(apiKeyService *apikey.APIKeyService) *AdminAPIKeyController { + return &AdminAPIKeyController{ + apiKeyService: apiKeyService, + } +} + +// GetAllAPIKeys get all api keys +// @Summary get all api keys +// @Description get all api keys +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=[]schema.GetAPIKeyResp} +// @Router /answer/admin/api/api-key/all [get] +func (sc *AdminAPIKeyController) GetAllAPIKeys(ctx *gin.Context) { + resp, err := sc.apiKeyService.GetAPIKeyList(ctx, &schema.GetAPIKeyReq{}) + handler.HandleResponse(ctx, err, resp) +} + +// AddAPIKey add apikey +// @Summary add apikey +// @Description add apikey +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Param data body schema.AddAPIKeyReq true "apikey" +// @Success 200 {object} handler.RespBody{data=schema.AddAPIKeyResp} +// @Router /answer/admin/api/api-key [post] +func (sc *AdminAPIKeyController) AddAPIKey(ctx *gin.Context) { + req := &schema.AddAPIKeyReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + resp, err := sc.apiKeyService.AddAPIKey(ctx, req) + handler.HandleResponse(ctx, err, resp) +} + +// UpdateAPIKey update apikey +// @Summary update apikey +// @Description update apikey +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Param data body schema.UpdateAPIKeyReq true "apikey" +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/api-key [put] +func (sc *AdminAPIKeyController) UpdateAPIKey(ctx *gin.Context) { + req := &schema.UpdateAPIKeyReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + err := sc.apiKeyService.UpdateAPIKey(ctx, req) + handler.HandleResponse(ctx, err, nil) +} + +// DeleteAPIKey delete apikey +// @Summary delete apikey +// @Description delete apikey +// @Security ApiKeyAuth +// @Tags admin +// @Param data body schema.DeleteAPIKeyReq true "apikey" +// @Produce json +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/api-key [delete] +func (sc *AdminAPIKeyController) DeleteAPIKey(ctx *gin.Context) { + req := &schema.DeleteAPIKeyReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + + err := sc.apiKeyService.DeleteAPIKey(ctx, req) + handler.HandleResponse(ctx, err, nil) +} diff --git a/internal/controller_admin/siteinfo_controller.go b/internal/controller_admin/siteinfo_controller.go index 339d2caa2..4575a5d19 100644 --- a/internal/controller_admin/siteinfo_controller.go +++ b/internal/controller_admin/siteinfo_controller.go @@ -585,3 +585,105 @@ func (sc *SiteInfoController) UpdatePrivilegesConfig(ctx *gin.Context) { err := sc.siteInfoService.UpdatePrivilegesConfig(ctx, req) handler.HandleResponse(ctx, err, nil) } + +// GetAIConfig get AI configuration +// @Summary get AI configuration +// @Description get AI configuration +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=schema.SiteAIResp} +// @Router /answer/admin/api/ai-config [get] +func (sc *SiteInfoController) GetAIConfig(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteAI(ctx) + handler.HandleResponse(ctx, err, resp) +} + +// UpdateAIConfig update AI configuration +// @Summary update AI configuration +// @Description update AI configuration +// @Security ApiKeyAuth +// @Tags admin +// @Param data body schema.SiteAIReq true "AI config" +// @Produce json +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/ai-config [put] +func (sc *SiteInfoController) UpdateAIConfig(ctx *gin.Context) { + req := &schema.SiteAIReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + err := sc.siteInfoService.SaveSiteAI(ctx, req) + handler.HandleResponse(ctx, err, nil) +} + +// GetAIProvider get AI provider configuration +// @Summary get AI provider configuration +// @Description get AI provider configuration +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=[]schema.GetAIProviderResp} +// @Router /answer/admin/api/ai-provider [get] +func (sc *SiteInfoController) GetAIProvider(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetAIProvider(ctx) + if err != nil { + handler.HandleResponse(ctx, err, nil) + return + } + handler.HandleResponse(ctx, nil, resp) +} + +// RequestAIModels get AI models +// @Summary get AI models +// @Description get AI models +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=[]schema.GetAIModelResp} +// @Router /answer/admin/api/ai-models [post] +func (sc *SiteInfoController) RequestAIModels(ctx *gin.Context) { + req := &schema.GetAIModelsReq{} + if handler.BindAndCheck(ctx, req) { + return + } + resp, err := sc.siteInfoService.GetAIModels(ctx, req) + if err != nil { + handler.HandleResponse(ctx, err, nil) + return + } + handler.HandleResponse(ctx, nil, resp) +} + +// GetMCPConfig get MCP configuration +// @Summary get MCP configuration +// @Description get MCP configuration +// @Security ApiKeyAuth +// @Tags admin +// @Produce json +// @Success 200 {object} handler.RespBody{data=schema.SiteMCPResp} +// @Router /answer/admin/api/mcp-config [get] +func (sc *SiteInfoController) GetMCPConfig(ctx *gin.Context) { + resp, err := sc.siteInfoService.GetSiteMCP(ctx) + handler.HandleResponse(ctx, err, resp) +} + +// UpdateMCPConfig update MCP configuration +// @Summary update MCP configuration +// @Description update MCP configuration +// @Security ApiKeyAuth +// @Tags admin +// @Param data body schema.SiteMCPReq true "MCP config" +// @Produce json +// @Success 200 {object} handler.RespBody{} +// @Router /answer/admin/api/mcp-config [put] +func (sc *SiteInfoController) UpdateMCPConfig(ctx *gin.Context) { + req := &schema.SiteMCPReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + err := sc.siteInfoService.SaveSiteMCP(ctx, req) + handler.HandleResponse(ctx, err, nil) +} diff --git a/internal/entity/ai_conversation.go b/internal/entity/ai_conversation.go new file mode 100644 index 000000000..7a610f7ba --- /dev/null +++ b/internal/entity/ai_conversation.go @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package entity + +import "time" + +// AIConversation AI +type AIConversation struct { + ID int `xorm:"not null pk autoincr INT(11) id"` + CreatedAt time.Time `xorm:"created not null default CURRENT_TIMESTAMP TIMESTAMP created_at"` + UpdatedAt time.Time `xorm:"updated not null default CURRENT_TIMESTAMP TIMESTAMP updated_at"` + ConversationID string `xorm:"not null unique VARCHAR(255) conversation_id"` + Topic string `xorm:"not null MEDIUMTEXT topic"` + UserID string `xorm:"not null default 0 BIGINT(20) user_id"` +} + +// TableName returns the table name +func (AIConversation) TableName() string { + return "ai_conversation" +} diff --git a/internal/entity/ai_conversation_record.go b/internal/entity/ai_conversation_record.go new file mode 100644 index 000000000..14dea3470 --- /dev/null +++ b/internal/entity/ai_conversation_record.go @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package entity + +import "time" + +// AIConversationRecord AI Conversation Record +type AIConversationRecord struct { + ID int `xorm:"not null pk autoincr INT(11) id"` + CreatedAt time.Time `xorm:"created not null default CURRENT_TIMESTAMP TIMESTAMP created_at"` + UpdatedAt time.Time `xorm:"updated not null default CURRENT_TIMESTAMP TIMESTAMP updated_at"` + ConversationID string `xorm:"not null VARCHAR(255) conversation_id"` + ChatCompletionID string `xorm:"not null VARCHAR(255) chat_completion_id"` + Role string `xorm:"not null default '' VARCHAR(128) role"` + Content string `xorm:"not null MEDIUMTEXT content"` + Helpful int `xorm:"not null default 0 INT(11) helpful"` + Unhelpful int `xorm:"not null default 0 INT(11) unhelpful"` +} + +// TableName returns the table name +func (AIConversationRecord) TableName() string { + return "ai_conversation_record" +} diff --git a/internal/entity/api_key_entity.go b/internal/entity/api_key_entity.go new file mode 100644 index 000000000..6d7713fec --- /dev/null +++ b/internal/entity/api_key_entity.go @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package entity + +import ( + "time" +) + +// APIKey entity +type APIKey struct { + ID int `xorm:"not null pk autoincr INT(11) id"` + CreatedAt time.Time `xorm:"created not null default CURRENT_TIMESTAMP TIMESTAMP created_at"` + UpdatedAt time.Time `xorm:"updated not null default CURRENT_TIMESTAMP TIMESTAMP updated_at"` + LastUsedAt time.Time `xorm:"not null default CURRENT_TIMESTAMP TIMESTAMP last_used_at"` + Description string `xorm:"not null MEDIUMTEXT description"` + AccessKey string `xorm:"not null unique VARCHAR(255) access_key"` + Scope string `xorm:"not null VARCHAR(255) scope"` + UserID string `xorm:"not null default 0 BIGINT(20) user_id"` + Hidden int `xorm:"not null default 0 INT(11) hidden"` +} + +// TableName category table name +func (c *APIKey) TableName() string { + return "api_key" +} diff --git a/internal/migrations/migrations.go b/internal/migrations/migrations.go index 783332df9..33453ef19 100644 --- a/internal/migrations/migrations.go +++ b/internal/migrations/migrations.go @@ -106,6 +106,7 @@ var migrations = []Migration{ NewMigration("v1.7.0", "add optional tags", addOptionalTags, true), NewMigration("v1.7.2", "expand avatar column length", expandAvatarColumnLength, false), NewMigration("v1.8.0", "change admin menu", updateAdminMenuSettings, true), + NewMigration("v1.8.1", "ai feat", aiFeat, true), } func GetMigrations() []Migration { diff --git a/internal/migrations/v32.go b/internal/migrations/v32.go new file mode 100644 index 000000000..89b970475 --- /dev/null +++ b/internal/migrations/v32.go @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package migrations + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/apache/answer/internal/base/constant" + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/schema" + "github.com/segmentfault/pacman/log" + "xorm.io/xorm" +) + +func aiFeat(ctx context.Context, x *xorm.Engine) error { + if err := addAIConversationTables(ctx, x); err != nil { + return fmt.Errorf("add ai conversation tables failed: %w", err) + } + if err := addAPIKey(ctx, x); err != nil { + return fmt.Errorf("add api key failed: %w", err) + } + log.Info("AI feature migration completed successfully") + return nil +} + +func addAIConversationTables(ctx context.Context, x *xorm.Engine) error { + if err := x.Context(ctx).Sync(new(entity.AIConversation)); err != nil { + return fmt.Errorf("sync ai_conversation table failed: %w", err) + } + + if err := x.Context(ctx).Sync(new(entity.AIConversationRecord)); err != nil { + return fmt.Errorf("sync ai_conversation_record table failed: %w", err) + } + + return nil +} + +func addAPIKey(ctx context.Context, x *xorm.Engine) error { + err := x.Context(ctx).Sync(new(entity.APIKey)) + if err != nil { + return err + } + + defaultConfigTable := []*entity.Config{ + {ID: 10000, Key: "ai_config.provider", Value: `[{"default_api_host":"https://api.openai.com","display_name":"OpenAI","name":"openai"},{"default_api_host":"https://generativelanguage.googleapis.com","display_name":"Gemini","name":"gemini"},{"default_api_host":"https://api.anthropic.com","display_name":"Anthropic","name":"anthropic"}]`}, + } + for _, c := range defaultConfigTable { + exist, err := x.Context(ctx).Get(&entity.Config{Key: c.Key}) + if err != nil { + return fmt.Errorf("get config failed: %w", err) + } + if exist { + continue + } + if _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { + log.Errorf("insert %+v config failed: %s", c, err) + return fmt.Errorf("add config failed: %w", err) + } + } + + aiSiteInfo := &entity.SiteInfo{ + Type: constant.SiteTypeAI, + } + exist, err := x.Context(ctx).Get(aiSiteInfo) + if err != nil { + return fmt.Errorf("get config failed: %w", err) + } + if exist { + content := &schema.SiteAIReq{} + _ = json.Unmarshal([]byte(aiSiteInfo.Content), content) + content.PromptConfig = &schema.AIPromptConfig{ + ZhCN: constant.DefaultAIPromptConfigZhCN, + EnUS: constant.DefaultAIPromptConfigEnUS, + } + data, _ := json.Marshal(content) + aiSiteInfo.Content = string(data) + _, err = x.Context(ctx).ID(aiSiteInfo.ID).Cols("content").Update(aiSiteInfo) + if err != nil { + return fmt.Errorf("update site info failed: %w", err) + } + } else { + content := &schema.SiteAIReq{ + PromptConfig: &schema.AIPromptConfig{ + ZhCN: constant.DefaultAIPromptConfigZhCN, + EnUS: constant.DefaultAIPromptConfigEnUS, + }, + } + data, _ := json.Marshal(content) + aiSiteInfo.Content = string(data) + aiSiteInfo.Type = constant.SiteTypeAI + if _, err = x.Context(ctx).Insert(aiSiteInfo); err != nil { + return fmt.Errorf("insert site info failed: %w", err) + } + log.Infof("insert site info %+v", aiSiteInfo) + } + return nil +} diff --git a/internal/repo/ai_conversation/ai_conversation_repo.go b/internal/repo/ai_conversation/ai_conversation_repo.go new file mode 100644 index 000000000..9947eb6cc --- /dev/null +++ b/internal/repo/ai_conversation/ai_conversation_repo.go @@ -0,0 +1,205 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package ai_conversation + +import ( + "context" + + "github.com/apache/answer/internal/base/data" + "github.com/apache/answer/internal/base/pager" + "github.com/apache/answer/internal/base/reason" + "github.com/apache/answer/internal/entity" + "github.com/segmentfault/pacman/errors" + "github.com/segmentfault/pacman/log" + "xorm.io/builder" + "xorm.io/xorm" +) + +// AIConversationRepo +type AIConversationRepo interface { + CreateConversation(ctx context.Context, conversation *entity.AIConversation) error + GetConversation(ctx context.Context, conversationID string) (*entity.AIConversation, bool, error) + UpdateConversation(ctx context.Context, conversation *entity.AIConversation) error + GetConversationsPage(ctx context.Context, page, pageSize int, cond *entity.AIConversation) (list []*entity.AIConversation, total int64, err error) + CreateRecord(ctx context.Context, record *entity.AIConversationRecord) error + GetRecordsByConversationID(ctx context.Context, conversationID string) ([]*entity.AIConversationRecord, error) + UpdateRecordVote(ctx context.Context, cond *entity.AIConversationRecord) error + GetRecord(ctx context.Context, recordID int) (*entity.AIConversationRecord, bool, error) + GetRecordByChatCompletionID(ctx context.Context, role, chatCompletionID string) (*entity.AIConversationRecord, bool, error) + GetConversationsForAdmin(ctx context.Context, page, pageSize int, cond *entity.AIConversation) (list []*entity.AIConversation, total int64, err error) + GetConversationWithVoteStats(ctx context.Context, conversationID string) (helpful, unhelpful int64, err error) + DeleteConversation(ctx context.Context, conversationID string) error +} + +type aiConversationRepo struct { + data *data.Data +} + +// NewAIConversationRepo new AIConversationRepo +func NewAIConversationRepo(data *data.Data) AIConversationRepo { + return &aiConversationRepo{ + data: data, + } +} + +// CreateConversation creates a conversation +func (r *aiConversationRepo) CreateConversation(ctx context.Context, conversation *entity.AIConversation) error { + _, err := r.data.DB.Context(ctx).Insert(conversation) + if err != nil { + log.Errorf("create ai conversation failed: %v", err) + return err + } + return nil +} + +// GetConversation gets a conversation +func (r *aiConversationRepo) GetConversation(ctx context.Context, conversationID string) (*entity.AIConversation, bool, error) { + conversation := &entity.AIConversation{} + exist, err := r.data.DB.Context(ctx).Where(builder.Eq{"conversation_id": conversationID}).Get(conversation) + if err != nil { + log.Errorf("get ai conversation failed: %v", err) + return nil, false, err + } + return conversation, exist, nil +} + +// UpdateConversation updates a conversation +func (r *aiConversationRepo) UpdateConversation(ctx context.Context, conversation *entity.AIConversation) error { + _, err := r.data.DB.Context(ctx).ID(conversation.ID).Update(conversation) + if err != nil { + log.Errorf("update ai conversation failed: %v", err) + return err + } + return nil +} + +// GetConversationsPage get conversations by user ID +func (r *aiConversationRepo) GetConversationsPage(ctx context.Context, page, pageSize int, cond *entity.AIConversation) (list []*entity.AIConversation, total int64, err error) { + list = make([]*entity.AIConversation, 0) + total, err = pager.Help(page, pageSize, &list, cond, r.data.DB.Context(ctx).Desc("id")) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return list, total, err +} + +// CreateRecord creates a conversation record +func (r *aiConversationRepo) CreateRecord(ctx context.Context, record *entity.AIConversationRecord) error { + _, err := r.data.DB.Context(ctx).Insert(record) + if err != nil { + log.Errorf("create ai conversation record failed: %v", err) + return err + } + return nil +} + +// GetRecordsByConversationID get records by conversation ID +func (r *aiConversationRepo) GetRecordsByConversationID(ctx context.Context, conversationID string) ([]*entity.AIConversationRecord, error) { + records := make([]*entity.AIConversationRecord, 0) + err := r.data.DB.Context(ctx). + Where(builder.Eq{"conversation_id": conversationID}). + OrderBy("created_at ASC"). + Find(&records) + if err != nil { + log.Errorf("get ai conversation records failed: %v", err) + return nil, err + } + return records, nil +} + +// UpdateRecordVote update record vote +func (r *aiConversationRepo) UpdateRecordVote(ctx context.Context, cond *entity.AIConversationRecord) (err error) { + _, err = r.data.DB.Context(ctx).ID(cond.ID).MustCols("helpful", "unhelpful").Update(cond) + if err != nil { + log.Errorf("update ai conversation record vote failed: %v", err) + return err + } + return nil +} + +// GetRecord get record +func (r *aiConversationRepo) GetRecord(ctx context.Context, recordID int) (*entity.AIConversationRecord, bool, error) { + record := &entity.AIConversationRecord{} + exist, err := r.data.DB.Context(ctx).ID(recordID).Get(record) + if err != nil { + log.Errorf("get ai conversation record failed: %v", err) + return nil, false, err + } + return record, exist, nil +} + +// GetRecordByChatCompletionID gets record by chat completion ID +func (r *aiConversationRepo) GetRecordByChatCompletionID(ctx context.Context, role, chatCompletionID string) (*entity.AIConversationRecord, bool, error) { + record := &entity.AIConversationRecord{} + exist, err := r.data.DB.Context(ctx).Where(builder.Eq{"role": role}). + Where(builder.Eq{"chat_completion_id": chatCompletionID}).Get(record) + if err != nil { + log.Errorf("get ai conversation record by chat completion id failed: %v", err) + return nil, false, err + } + return record, exist, nil +} + +// GetConversationsForAdmin gets conversation list for admin +func (r *aiConversationRepo) GetConversationsForAdmin(ctx context.Context, page, pageSize int, cond *entity.AIConversation) (list []*entity.AIConversation, total int64, err error) { + list = make([]*entity.AIConversation, 0) + total, err = pager.Help(page, pageSize, &list, cond, r.data.DB.Context(ctx).Desc("id")) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return list, total, err +} + +// GetConversationWithVoteStats gets conversation vote statistics +func (r *aiConversationRepo) GetConversationWithVoteStats(ctx context.Context, conversationID string) (helpful, unhelpful int64, err error) { + res, err := r.data.DB.Context(ctx).SumsInt(&entity.AIConversationRecord{ConversationID: conversationID}, "helpful", "unhelpful") + if err != nil { + log.Errorf("get ai conversation vote stats failed: %v", err) + return 0, 0, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + if len(res) < 2 { + log.Errorf("get ai conversation vote stats failed: invalid result length %d", len(res)) + return 0, 0, nil + } + return res[0], res[1], nil +} + +// DeleteConversation deletes a conversation and its related records +func (r *aiConversationRepo) DeleteConversation(ctx context.Context, conversationID string) error { + _, err := r.data.DB.Transaction(func(session *xorm.Session) (result any, err error) { + if _, err := session.Context(ctx).Where("conversation_id = ?", conversationID).Delete(&entity.AIConversationRecord{}); err != nil { + log.Errorf("delete ai conversation records failed: %v", err) + return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + + if _, err := session.Context(ctx).Where("conversation_id = ?", conversationID).Delete(&entity.AIConversation{}); err != nil { + log.Errorf("delete ai conversation failed: %v", err) + return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + + return nil, nil + }) + + if err != nil { + return err + } + + return nil +} diff --git a/internal/repo/api_key/api_key_repo.go b/internal/repo/api_key/api_key_repo.go new file mode 100644 index 000000000..2309384a9 --- /dev/null +++ b/internal/repo/api_key/api_key_repo.go @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package api_key + +import ( + "context" + + "github.com/apache/answer/internal/base/data" + "github.com/apache/answer/internal/base/reason" + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/service/apikey" + "github.com/segmentfault/pacman/errors" +) + +type apiKeyRepo struct { + data *data.Data +} + +// NewAPIKeyRepo creates a new apiKey repository +func NewAPIKeyRepo(data *data.Data) apikey.APIKeyRepo { + return &apiKeyRepo{ + data: data, + } +} + +func (ar *apiKeyRepo) GetAPIKeyList(ctx context.Context) (keys []*entity.APIKey, err error) { + keys = make([]*entity.APIKey, 0) + err = ar.data.DB.Context(ctx).Where("hidden = ?", 0).Find(&keys) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return +} + +func (ar *apiKeyRepo) GetAPIKey(ctx context.Context, apiKey string) (key *entity.APIKey, exist bool, err error) { + key = &entity.APIKey{} + exist, err = ar.data.DB.Context(ctx).Where("access_key = ?", apiKey).Get(key) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return +} + +func (ar *apiKeyRepo) UpdateAPIKey(ctx context.Context, apiKey entity.APIKey) (err error) { + _, err = ar.data.DB.Context(ctx).ID(apiKey.ID).Update(&apiKey) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return +} + +func (ar *apiKeyRepo) AddAPIKey(ctx context.Context, apiKey entity.APIKey) (err error) { + _, err = ar.data.DB.Context(ctx).Insert(&apiKey) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return +} + +func (ar *apiKeyRepo) DeleteAPIKey(ctx context.Context, id int) (err error) { + _, err = ar.data.DB.Context(ctx).ID(id).Delete(&entity.APIKey{}) + if err != nil { + err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() + } + return +} diff --git a/internal/repo/provider.go b/internal/repo/provider.go index 02f27f62f..510a94aaa 100644 --- a/internal/repo/provider.go +++ b/internal/repo/provider.go @@ -23,7 +23,9 @@ import ( "github.com/apache/answer/internal/base/data" "github.com/apache/answer/internal/repo/activity" "github.com/apache/answer/internal/repo/activity_common" + "github.com/apache/answer/internal/repo/ai_conversation" "github.com/apache/answer/internal/repo/answer" + "github.com/apache/answer/internal/repo/api_key" "github.com/apache/answer/internal/repo/auth" "github.com/apache/answer/internal/repo/badge" "github.com/apache/answer/internal/repo/badge_award" @@ -109,4 +111,6 @@ var ProviderSetRepo = wire.NewSet( badge_group.NewBadgeGroupRepo, badge_award.NewBadgeAwardRepo, file_record.NewFileRecordRepo, + api_key.NewAPIKeyRepo, + ai_conversation.NewAIConversationRepo, ) diff --git a/internal/repo/site_info/siteinfo_repo.go b/internal/repo/site_info/siteinfo_repo.go index 5f95b7486..379a59c91 100644 --- a/internal/repo/site_info/siteinfo_repo.go +++ b/internal/repo/site_info/siteinfo_repo.go @@ -63,10 +63,12 @@ func (sr *siteInfoRepo) SaveByType(ctx context.Context, siteType string, data *e } // GetByType get site info by type -func (sr *siteInfoRepo) GetByType(ctx context.Context, siteType string) (siteInfo *entity.SiteInfo, exist bool, err error) { - siteInfo = sr.getCache(ctx, siteType) - if siteInfo != nil { - return siteInfo, true, nil +func (sr *siteInfoRepo) GetByType(ctx context.Context, siteType string, withoutCache ...bool) (siteInfo *entity.SiteInfo, exist bool, err error) { + if len(withoutCache) == 0 { + siteInfo = sr.getCache(ctx, siteType) + if siteInfo != nil { + return siteInfo, true, nil + } } siteInfo = &entity.SiteInfo{} exist, err = sr.data.DB.Context(ctx).Where(builder.Eq{"type": siteType}).Get(siteInfo) diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go index 1fe8bdb14..fc53ec455 100644 --- a/internal/router/answer_api_router.go +++ b/internal/router/answer_api_router.go @@ -27,36 +27,40 @@ import ( ) type AnswerAPIRouter struct { - langController *controller.LangController - userController *controller.UserController - commentController *controller.CommentController - reportController *controller.ReportController - voteController *controller.VoteController - tagController *controller.TagController - followController *controller.FollowController - collectionController *controller.CollectionController - questionController *controller.QuestionController - answerController *controller.AnswerController - searchController *controller.SearchController - revisionController *controller.RevisionController - rankController *controller.RankController - adminUserController *controller_admin.UserAdminController - reasonController *controller.ReasonController - themeController *controller_admin.ThemeController - adminSiteInfoController *controller_admin.SiteInfoController - siteInfoController *controller.SiteInfoController - notificationController *controller.NotificationController - dashboardController *controller.DashboardController - uploadController *controller.UploadController - activityController *controller.ActivityController - roleController *controller_admin.RoleController - pluginController *controller_admin.PluginController - permissionController *controller.PermissionController - userPluginController *controller.UserPluginController - reviewController *controller.ReviewController - metaController *controller.MetaController - badgeController *controller.BadgeController - adminBadgeController *controller_admin.BadgeController + langController *controller.LangController + userController *controller.UserController + commentController *controller.CommentController + reportController *controller.ReportController + voteController *controller.VoteController + tagController *controller.TagController + followController *controller.FollowController + collectionController *controller.CollectionController + questionController *controller.QuestionController + answerController *controller.AnswerController + searchController *controller.SearchController + revisionController *controller.RevisionController + rankController *controller.RankController + adminUserController *controller_admin.UserAdminController + reasonController *controller.ReasonController + themeController *controller_admin.ThemeController + adminSiteInfoController *controller_admin.SiteInfoController + siteInfoController *controller.SiteInfoController + notificationController *controller.NotificationController + dashboardController *controller.DashboardController + uploadController *controller.UploadController + activityController *controller.ActivityController + roleController *controller_admin.RoleController + pluginController *controller_admin.PluginController + permissionController *controller.PermissionController + userPluginController *controller.UserPluginController + reviewController *controller.ReviewController + metaController *controller.MetaController + badgeController *controller.BadgeController + adminBadgeController *controller_admin.BadgeController + apiKeyController *controller_admin.AdminAPIKeyController + aiController *controller.AIController + aiConversationController *controller.AIConversationController + aiConversationAdminController *controller_admin.AIConversationAdminController } func NewAnswerAPIRouter( @@ -90,38 +94,46 @@ func NewAnswerAPIRouter( metaController *controller.MetaController, badgeController *controller.BadgeController, adminBadgeController *controller_admin.BadgeController, + apiKeyController *controller_admin.AdminAPIKeyController, + aiController *controller.AIController, + aiConversationController *controller.AIConversationController, + aiConversationAdminController *controller_admin.AIConversationAdminController, ) *AnswerAPIRouter { return &AnswerAPIRouter{ - langController: langController, - userController: userController, - commentController: commentController, - reportController: reportController, - voteController: voteController, - tagController: tagController, - followController: followController, - collectionController: collectionController, - questionController: questionController, - answerController: answerController, - searchController: searchController, - revisionController: revisionController, - rankController: rankController, - adminUserController: adminUserController, - reasonController: reasonController, - themeController: themeController, - adminSiteInfoController: adminSiteInfoController, - notificationController: notificationController, - siteInfoController: siteInfoController, - dashboardController: dashboardController, - uploadController: uploadController, - activityController: activityController, - roleController: roleController, - pluginController: pluginController, - permissionController: permissionController, - userPluginController: userPluginController, - reviewController: reviewController, - metaController: metaController, - badgeController: badgeController, - adminBadgeController: adminBadgeController, + langController: langController, + userController: userController, + commentController: commentController, + reportController: reportController, + voteController: voteController, + tagController: tagController, + followController: followController, + collectionController: collectionController, + questionController: questionController, + answerController: answerController, + searchController: searchController, + revisionController: revisionController, + rankController: rankController, + adminUserController: adminUserController, + reasonController: reasonController, + themeController: themeController, + adminSiteInfoController: adminSiteInfoController, + notificationController: notificationController, + siteInfoController: siteInfoController, + dashboardController: dashboardController, + uploadController: uploadController, + activityController: activityController, + roleController: roleController, + pluginController: pluginController, + permissionController: permissionController, + userPluginController: userPluginController, + reviewController: reviewController, + metaController: metaController, + badgeController: badgeController, + adminBadgeController: adminBadgeController, + apiKeyController: apiKeyController, + aiController: aiController, + aiConversationController: aiConversationController, + aiConversationAdminController: aiConversationAdminController, } } @@ -310,6 +322,14 @@ func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) { // meta r.PUT("/meta/reaction", a.metaController.AddOrUpdateReaction) + + // AI chat + r.POST("/chat/completions", a.aiController.ChatCompletions) + + // AI conversation + r.GET("/ai/conversation/page", a.aiConversationController.GetConversationList) + r.GET("/ai/conversation", a.aiConversationController.GetConversationDetail) + r.POST("/ai/conversation/vote", a.aiConversationController.VoteRecord) } func (a *AnswerAPIRouter) RegisterAnswerAdminAPIRouter(r *gin.RouterGroup) { @@ -394,4 +414,25 @@ func (a *AnswerAPIRouter) RegisterAnswerAdminAPIRouter(r *gin.RouterGroup) { // badge r.GET("/badges", a.adminBadgeController.GetBadgeList) r.PUT("/badge/status", a.adminBadgeController.UpdateBadgeStatus) + + // api key + r.GET("/api-key/all", a.apiKeyController.GetAllAPIKeys) + r.POST("/api-key", a.apiKeyController.AddAPIKey) + r.PUT("/api-key", a.apiKeyController.UpdateAPIKey) + r.DELETE("/api-key", a.apiKeyController.DeleteAPIKey) + + // ai config + r.GET("/ai-config", a.adminSiteInfoController.GetAIConfig) + r.PUT("/ai-config", a.adminSiteInfoController.UpdateAIConfig) + r.GET("/ai-provider", a.adminSiteInfoController.GetAIProvider) + r.POST("/ai-models", a.adminSiteInfoController.RequestAIModels) + + // mcp config + r.GET("/mcp-config", a.adminSiteInfoController.GetMCPConfig) + r.PUT("/mcp-config", a.adminSiteInfoController.UpdateMCPConfig) + + // AI conversation management + r.GET("/ai/conversation/page", a.aiConversationAdminController.GetConversationList) + r.GET("/ai/conversation", a.aiConversationAdminController.GetConversationDetail) + r.DELETE("/ai/conversation", a.aiConversationAdminController.DeleteConversation) } diff --git a/internal/schema/ai_config_schema.go b/internal/schema/ai_config_schema.go new file mode 100644 index 000000000..6ac686343 --- /dev/null +++ b/internal/schema/ai_config_schema.go @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package schema + +// GetAIProviderResp get AI providers response +type GetAIProviderResp struct { + Name string `json:"name"` + DisplayName string `json:"display_name"` + DefaultAPIHost string `json:"default_api_host"` +} + +// GetAIModelsResp get AI model response +type GetAIModelsResp struct { + Object string `json:"object"` + Data []struct { + Id string `json:"id"` + Object string `json:"object"` + Created int `json:"created"` + OwnedBy string `json:"owned_by"` + } `json:"data"` +} + +type GetAIModelsReq struct { + APIHost string `json:"api_host"` + APIKey string `json:"api_key"` +} + +// GetAIModelResp get AI model response +type GetAIModelResp struct { + Id string `json:"id"` + Object string `json:"object"` + Created int `json:"created"` + OwnedBy string `json:"owned_by"` +} diff --git a/internal/schema/ai_conversation_schema.go b/internal/schema/ai_conversation_schema.go new file mode 100644 index 000000000..fd34278a1 --- /dev/null +++ b/internal/schema/ai_conversation_schema.go @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package schema + +import ( + "github.com/apache/answer/internal/base/validator" +) + +// AIConversationListReq ai conversation list req +type AIConversationListReq struct { + Page int `validate:"omitempty,min=1" form:"page"` + PageSize int `validate:"omitempty,min=1" form:"page_size"` + UserID string `validate:"omitempty" json:"-"` +} + +// AIConversationListItem ai conversation list item +type AIConversationListItem struct { + ConversationID string `json:"conversation_id"` + Topic string `json:"topic"` + CreatedAt int64 `json:"created_at"` +} + +// AIConversationDetailReq ai conversation detail req +type AIConversationDetailReq struct { + ConversationID string `validate:"required" form:"conversation_id" json:"conversation_id"` + UserID string `validate:"omitempty" json:"-"` +} + +// AIConversationRecord ai conversation record +type AIConversationRecord struct { + ChatCompletionID string `json:"chat_completion_id"` + Role string `json:"role"` + Content string `json:"content"` + Helpful int `json:"helpful"` + Unhelpful int `json:"unhelpful"` + CreatedAt int64 `json:"created_at"` +} + +// AIConversationDetailResp ai conversation detail resp +type AIConversationDetailResp struct { + ConversationID string `json:"conversation_id"` + Topic string `json:"topic"` + Records []*AIConversationRecord `json:"records"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` +} + +// AIConversationVoteReq ai conversation vote req +type AIConversationVoteReq struct { + ChatCompletionID string `validate:"required" json:"chat_completion_id"` + VoteType string `validate:"required,oneof=helpful unhelpful" json:"vote_type"` + Cancel bool `validate:"omitempty" json:"cancel"` + UserID string `validate:"omitempty" json:"-"` +} + +// AIConversationAdminListReq ai conversation admin list req +type AIConversationAdminListReq struct { + Page int `validate:"omitempty,min=1" form:"page"` + PageSize int `validate:"omitempty,min=1" form:"page_size"` +} + +// AIConversationAdminListItem ai conversation admin list item +type AIConversationAdminListItem struct { + ID string `json:"id"` + Topic string `json:"topic"` + UserInfo AIConversationUserInfo `json:"user_info"` + HelpfulCount int64 `json:"helpful_count"` + UnhelpfulCount int64 `json:"unhelpful_count"` + CreatedAt int64 `json:"created_at"` +} + +// AIConversationUserInfo ai conversation user info +type AIConversationUserInfo struct { + ID string `json:"id"` + Username string `json:"username"` + DisplayName string `json:"display_name"` + Avatar string `json:"avatar"` + Rank int `json:"rank"` +} + +// AIConversationAdminDetailReq ai conversation admin detail req +type AIConversationAdminDetailReq struct { + ConversationID string `validate:"required" form:"conversation_id" json:"conversation_id"` +} + +// AIConversationAdminDetailResp ai conversation admin detail resp +type AIConversationAdminDetailResp struct { + ConversationID string `json:"conversation_id"` + Topic string `json:"topic"` + UserInfo AIConversationUserInfo `json:"user_info"` + Records []AIConversationRecord `json:"records"` + CreatedAt int64 `json:"created_at"` +} + +// AIConversationAdminDeleteReq admin delete ai +type AIConversationAdminDeleteReq struct { + ConversationID string `validate:"required" json:"conversation_id"` +} + +func (req *AIConversationDetailReq) Check() (errFields []*validator.FormErrorField, err error) { + return nil, nil +} + +func (req *AIConversationVoteReq) Check() (errFields []*validator.FormErrorField, err error) { + return nil, nil +} diff --git a/internal/schema/api_key_schema.go b/internal/schema/api_key_schema.go new file mode 100644 index 000000000..e9dde7847 --- /dev/null +++ b/internal/schema/api_key_schema.go @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package schema + +// GetAPIKeyReq get api key request +type GetAPIKeyReq struct { + UserID string `json:"-"` +} + +// GetAPIKeyResp get api keys response +type GetAPIKeyResp struct { + ID int `json:"id"` + AccessKey string `json:"access_key"` + Description string `json:"description"` + Scope string `json:"scope"` + CreatedAt int64 `json:"created_at"` + LastUsedAt int64 `json:"last_used_at"` +} + +// AddAPIKeyReq add api key request +type AddAPIKeyReq struct { + Description string `validate:"required,notblank,lte=150" json:"description"` + Scope string `validate:"required,oneof=read-only global" json:"scope"` + UserID string `json:"-"` +} + +// AddAPIKeyResp add api key response +type AddAPIKeyResp struct { + AccessKey string `json:"access_key"` +} + +// UpdateAPIKeyReq update api key request +type UpdateAPIKeyReq struct { + ID int `validate:"required" json:"id"` + Description string `validate:"required,notblank,lte=150" json:"description"` + UserID string `json:"-"` +} + +// DeleteAPIKeyReq delete api key request +type DeleteAPIKeyReq struct { + ID int `json:"id"` + UserID string `json:"-"` +} diff --git a/internal/schema/mcp_schema.go b/internal/schema/mcp_schema.go new file mode 100644 index 000000000..bead21c9d --- /dev/null +++ b/internal/schema/mcp_schema.go @@ -0,0 +1,194 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package schema + +import ( + "strings" + + "github.com/apache/answer/pkg/converter" + "github.com/mark3labs/mcp-go/mcp" +) + +const ( + MCPSearchCondKeyword = "keyword" + MCPSearchCondUsername = "username" + MCPSearchCondScore = "score" + MCPSearchCondTag = "tag" + MCPSearchCondPage = "page" + MCPSearchCondPageSize = "page_size" + MCPSearchCondTagName = "tag_name" + MCPSearchCondQuestionID = "question_id" + MCPSearchCondObjectID = "object_id" +) + +type MCPSearchCond struct { + Keyword string `json:"keyword"` + Username string `json:"username"` + Score int `json:"score"` + Tags []string `json:"tags"` + QuestionID string `json:"question_id"` +} + +type MCPSearchQuestionDetail struct { + QuestionID string `json:"question_id"` +} + +type MCPSearchCommentCond struct { + ObjectID string `json:"object_id"` +} + +type MCPSearchTagCond struct { + TagName string `json:"tag_name"` +} + +type MCPSearchUserCond struct { + Username string `json:"username"` +} + +type MCPSearchQuestionInfoResp struct { + QuestionID string `json:"question_id"` + Title string `json:"title"` + Content string `json:"content"` + Link string `json:"link"` +} + +type MCPSearchAnswerInfoResp struct { + QuestionID string `json:"question_id"` + QuestionTitle string `json:"question_title,omitempty"` + AnswerID string `json:"answer_id"` + AnswerContent string `json:"answer_content"` + Link string `json:"link"` +} + +type MCPSearchTagResp struct { + TagName string `json:"tag_name"` + DisplayName string `json:"display_name"` + Description string `json:"description"` + Link string `json:"link"` +} + +type MCPSearchUserInfoResp struct { + Username string `json:"username"` + DisplayName string `json:"display_name"` + Avatar string `json:"avatar"` + Link string `json:"link"` +} + +type MCPSearchCommentInfoResp struct { + CommentID string `json:"comment_id"` + Content string `json:"content"` + ObjectID string `json:"object_id"` + Link string `json:"link"` +} + +func NewMCPSearchCond(request mcp.CallToolRequest) *MCPSearchCond { + cond := &MCPSearchCond{} + if keyword, ok := getRequestValue(request, MCPSearchCondKeyword); ok { + cond.Keyword = keyword + } + if username, ok := getRequestValue(request, MCPSearchCondUsername); ok { + cond.Username = username + } + if score, ok := getRequestNumber(request, MCPSearchCondScore); ok { + cond.Score = score + } + if tag, ok := getRequestValue(request, MCPSearchCondTag); ok { + cond.Tags = strings.Split(tag, ",") + } + if questionID, ok := getRequestValue(request, MCPSearchCondQuestionID); ok { + cond.QuestionID = questionID + } + return cond +} + +func NewMCPSearchAnswerCond(request mcp.CallToolRequest) *MCPSearchCond { + cond := &MCPSearchCond{} + if questionID, ok := getRequestValue(request, MCPSearchCondQuestionID); ok { + cond.QuestionID = questionID + } + return cond +} + +func NewMCPSearchQuestionDetail(request mcp.CallToolRequest) *MCPSearchQuestionDetail { + cond := &MCPSearchQuestionDetail{} + if questionID, ok := getRequestValue(request, MCPSearchCondQuestionID); ok { + cond.QuestionID = questionID + } + return cond +} + +func NewMCPSearchCommentCond(request mcp.CallToolRequest) *MCPSearchCommentCond { + cond := &MCPSearchCommentCond{} + if keyword, ok := getRequestValue(request, MCPSearchCondObjectID); ok { + cond.ObjectID = keyword + } + return cond +} + +func NewMCPSearchTagCond(request mcp.CallToolRequest) *MCPSearchTagCond { + cond := &MCPSearchTagCond{} + if tagName, ok := getRequestValue(request, MCPSearchCondTagName); ok { + cond.TagName = tagName + } + return cond +} + +func NewMCPSearchUserCond(request mcp.CallToolRequest) *MCPSearchUserCond { + cond := &MCPSearchUserCond{} + if username, ok := getRequestValue(request, MCPSearchCondUsername); ok { + cond.Username = username + } + return cond +} + +func getRequestValue(request mcp.CallToolRequest, key string) (string, bool) { + value, ok := request.GetArguments()[key].(string) + if !ok { + return "", false + } + return value, true +} + +func getRequestNumber(request mcp.CallToolRequest, key string) (int, bool) { + value, ok := request.GetArguments()[key].(float64) + if !ok { + return 0, false + } + return int(value), true +} + +func (cond *MCPSearchCond) ToQueryString() string { + var queryBuilder strings.Builder + if len(cond.Keyword) > 0 { + queryBuilder.WriteString(cond.Keyword) + } + if len(cond.Username) > 0 { + queryBuilder.WriteString(" user:" + cond.Username) + } + if cond.Score > 0 { + queryBuilder.WriteString(" score:" + converter.IntToString(int64(cond.Score))) + } + if len(cond.Tags) > 0 { + for _, tag := range cond.Tags { + queryBuilder.WriteString(" [" + tag + "]") + } + } + return strings.TrimSpace(queryBuilder.String()) +} diff --git a/internal/schema/mcp_tools/mcp_tools.go b/internal/schema/mcp_tools/mcp_tools.go new file mode 100644 index 000000000..949a738c7 --- /dev/null +++ b/internal/schema/mcp_tools/mcp_tools.go @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package mcp_tools + +import ( + "github.com/apache/answer/internal/schema" + "github.com/mark3labs/mcp-go/mcp" +) + +var ( + MCPToolsList = []mcp.Tool{ + NewQuestionsTool(), + NewAnswersTool(), + NewCommentsTool(), + NewTagsTool(), + NewTagDetailTool(), + NewUserTool(), + } +) + +func NewQuestionsTool() mcp.Tool { + listFilesTool := mcp.NewTool("get_questions", + mcp.WithDescription("Searching for questions that already existed in the system. After the search, you can use the get_answers_by_question_id tool to get answers for the questions."), + mcp.WithString(schema.MCPSearchCondKeyword, + mcp.Description("Keyword to search for questions. Multiple keywords separated by spaces"), + ), + mcp.WithString(schema.MCPSearchCondUsername, + mcp.Description("Search for questions that contain only those created by the specified user"), + ), + mcp.WithString(schema.MCPSearchCondTag, + mcp.Description("Filter by tag (semicolon separated for multiple tags)"), + ), + mcp.WithString(schema.MCPSearchCondScore, + mcp.Description("Minimum score that the question must have"), + ), + ) + return listFilesTool +} + +func NewAnswersTool() mcp.Tool { + listFilesTool := mcp.NewTool("get_answers_by_question_id", + mcp.WithDescription("Search for all answers corresponding to the question ID. The question ID is provided by get_questions tool."), + mcp.WithString(schema.MCPSearchCondQuestionID, + mcp.Description("The ID of the question to which the answer belongs. The question ID is provided by get_questions tool."), + ), + ) + return listFilesTool +} + +func NewCommentsTool() mcp.Tool { + listFilesTool := mcp.NewTool("get_comments", + mcp.WithDescription("Searching for comments that already existed in the system"), + mcp.WithString(schema.MCPSearchCondObjectID, + mcp.Description("Queries comments on an object, either a question or an answer. object_id is the id of the object."), + ), + ) + return listFilesTool +} + +func NewTagsTool() mcp.Tool { + listFilesTool := mcp.NewTool("get_tags", + mcp.WithDescription("Searching for tags that already existed in the system"), + mcp.WithString(schema.MCPSearchCondTagName, + mcp.Description("Tag name"), + ), + ) + return listFilesTool +} + +func NewTagDetailTool() mcp.Tool { + listFilesTool := mcp.NewTool("get_tag_detail", + mcp.WithDescription("Get detailed information about a specific tag"), + mcp.WithString(schema.MCPSearchCondTagName, + mcp.Description("Tag name"), + ), + ) + return listFilesTool +} + +func NewUserTool() mcp.Tool { + listFilesTool := mcp.NewTool("get_user", + mcp.WithDescription("Searching for users that already existed in the system"), + mcp.WithString(schema.MCPSearchCondUsername, + mcp.Description("Username"), + ), + ) + return listFilesTool +} diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index bf1c7713e..3338e80ab 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -253,6 +253,56 @@ func (s *SiteSeoResp) IsShortLink() bool { s.Permalink == constant.PermalinkQuestionIDByShortID } +// AIPromptConfig AI prompt configuration for different languages +type AIPromptConfig struct { + ZhCN string `json:"zh_cn"` + EnUS string `json:"en_us"` +} + +// SiteAIReq AI configuration request +type SiteAIReq struct { + Enabled bool `validate:"omitempty" form:"enabled" json:"enabled"` + ChosenProvider string `validate:"omitempty,lte=50" form:"chosen_provider" json:"chosen_provider"` + SiteAIProviders []*SiteAIProvider `validate:"omitempty,dive" form:"ai_providers" json:"ai_providers"` + PromptConfig *AIPromptConfig `validate:"omitempty" form:"prompt_config" json:"prompt_config,omitempty"` +} + +func (s *SiteAIResp) GetProvider() *SiteAIProvider { + if !s.Enabled || s.ChosenProvider == "" { + return &SiteAIProvider{} + } + if len(s.SiteAIProviders) == 0 { + return &SiteAIProvider{} + } + for _, provider := range s.SiteAIProviders { + if provider.Provider == s.ChosenProvider { + return provider + } + } + return &SiteAIProvider{} +} + +type SiteAIProvider struct { + Provider string `validate:"omitempty,lte=50" form:"provider" json:"provider"` + APIHost string `validate:"omitempty,lte=512" form:"api_host" json:"api_host"` + APIKey string `validate:"omitempty,lte=256" form:"api_key" json:"api_key"` + Model string `validate:"omitempty,lte=100" form:"model" json:"model"` +} + +// SiteAIResp AI configuration response +type SiteAIResp SiteAIReq + +type SiteMCPReq struct { + Enabled bool `validate:"omitempty" form:"enabled" json:"enabled"` +} + +type SiteMCPResp struct { + Enabled bool `json:"enabled"` + Type string `json:"type"` + URL string `json:"url"` + HTTPHeader string `json:"http_header"` +} + // SiteGeneralResp site general response type SiteGeneralResp SiteGeneralReq @@ -331,6 +381,8 @@ type SiteInfoResp struct { Security *SiteSecurityResp `json:"site_security"` Version string `json:"version"` Revision string `json:"revision"` + AIEnabled bool `json:"ai_enabled"` + MCPEnabled bool `json:"mcp_enabled"` } type TemplateSiteInfoResp struct { diff --git a/internal/service/ai_conversation/ai_conversation_service.go b/internal/service/ai_conversation/ai_conversation_service.go new file mode 100644 index 000000000..d095ac0e9 --- /dev/null +++ b/internal/service/ai_conversation/ai_conversation_service.go @@ -0,0 +1,372 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package ai_conversation + +import ( + "context" + "strings" + "time" + + "github.com/apache/answer/internal/base/pager" + "github.com/apache/answer/internal/base/reason" + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/repo/ai_conversation" + "github.com/apache/answer/internal/schema" + usercommon "github.com/apache/answer/internal/service/user_common" + "github.com/segmentfault/pacman/errors" + "github.com/segmentfault/pacman/log" +) + +// AIConversationService +type AIConversationService interface { + CreateConversation(ctx context.Context, userID, conversationID, topic string) error + SaveConversationRecords(ctx context.Context, conversationID, chatcmplID string, records []*ConversationMessage) error + GetConversationList(ctx context.Context, req *schema.AIConversationListReq) (*pager.PageModel, error) + GetConversationDetail(ctx context.Context, req *schema.AIConversationDetailReq) (resp *schema.AIConversationDetailResp, exist bool, err error) + VoteRecord(ctx context.Context, req *schema.AIConversationVoteReq) error + GetConversationListForAdmin(ctx context.Context, req *schema.AIConversationAdminListReq) (*pager.PageModel, error) + GetConversationDetailForAdmin(ctx context.Context, req *schema.AIConversationAdminDetailReq) (*schema.AIConversationAdminDetailResp, error) + DeleteConversationForAdmin(ctx context.Context, req *schema.AIConversationAdminDeleteReq) error +} + +// ConversationMessage +type ConversationMessage struct { + ChatCompletionID string `json:"chat_completion_id"` + Role string `json:"role"` + Content string `json:"content"` +} + +// aiConversationService +type aiConversationService struct { + aiConversationRepo ai_conversation.AIConversationRepo + userCommon *usercommon.UserCommon +} + +// NewAIConversationService +func NewAIConversationService( + aiConversationRepo ai_conversation.AIConversationRepo, + userCommon *usercommon.UserCommon, +) AIConversationService { + return &aiConversationService{ + aiConversationRepo: aiConversationRepo, + userCommon: userCommon, + } +} + +// CreateConversation +func (s *aiConversationService) CreateConversation(ctx context.Context, userID, conversationID, topic string) error { + conversation := &entity.AIConversation{ + ConversationID: conversationID, + Topic: topic, + UserID: userID, + } + err := s.aiConversationRepo.CreateConversation(ctx, conversation) + if err != nil { + log.Errorf("create conversation failed: %v", err) + return err + } + + return nil +} + +// SaveConversationRecords +func (s *aiConversationService) SaveConversationRecords(ctx context.Context, conversationID, chatcmplID string, records []*ConversationMessage) error { + conversation, exist, err := s.aiConversationRepo.GetConversation(ctx, conversationID) + if err != nil { + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + if !exist { + return errors.BadRequest(reason.ObjectNotFound) + } + + content := strings.Builder{} + + for _, record := range records { + if len(record.ChatCompletionID) > 0 { + continue + } + if record.Role == "user" { + aiRecord := &entity.AIConversationRecord{ + ConversationID: conversationID, + ChatCompletionID: chatcmplID, + Role: "user", + Content: record.Content, + } + + err = s.aiConversationRepo.CreateRecord(ctx, aiRecord) + if err != nil { + log.Errorf("create conversation record failed: %v", err) + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + continue + } + + content.WriteString(record.Content) + content.WriteString("\n") + } + aiRecord := &entity.AIConversationRecord{ + ConversationID: conversationID, + ChatCompletionID: chatcmplID, + Role: "assistant", + Content: content.String(), + Helpful: 0, + Unhelpful: 0, + } + + err = s.aiConversationRepo.CreateRecord(ctx, aiRecord) + if err != nil { + log.Errorf("create conversation record failed: %v", err) + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + + conversation.UpdatedAt = time.Now() + err = s.aiConversationRepo.UpdateConversation(ctx, conversation) + if err != nil { + log.Errorf("update conversation failed: %v", err) + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + + return nil +} + +// GetConversationList +func (s *aiConversationService) GetConversationList(ctx context.Context, req *schema.AIConversationListReq) (*pager.PageModel, error) { + conversations, total, err := s.aiConversationRepo.GetConversationsPage(ctx, req.Page, req.PageSize, &entity.AIConversation{UserID: req.UserID}) + if err != nil { + return nil, errors.InternalServer(reason.DatabaseError).WithError(err) + } + + list := make([]schema.AIConversationListItem, 0, len(conversations)) + for _, conversation := range conversations { + list = append(list, schema.AIConversationListItem{ + ConversationID: conversation.ConversationID, + CreatedAt: conversation.CreatedAt.Unix(), + Topic: conversation.Topic, + }) + } + + return pager.NewPageModel(total, list), nil +} + +// GetConversationDetail +func (s *aiConversationService) GetConversationDetail(ctx context.Context, req *schema.AIConversationDetailReq) ( + resp *schema.AIConversationDetailResp, exist bool, err error) { + conversation, exist, err := s.aiConversationRepo.GetConversation(ctx, req.ConversationID) + if err != nil { + return nil, false, errors.InternalServer(reason.DatabaseError).WithError(err) + } + if !exist || conversation.UserID != req.UserID { + return nil, false, nil + } + + records, err := s.aiConversationRepo.GetRecordsByConversationID(ctx, req.ConversationID) + if err != nil { + return nil, false, errors.InternalServer(reason.DatabaseError).WithError(err) + } + + recordList := make([]*schema.AIConversationRecord, 0, len(records)) + for i, record := range records { + if i == 0 { + record.Content = conversation.Topic + } + recordList = append(recordList, &schema.AIConversationRecord{ + ChatCompletionID: record.ChatCompletionID, + Role: record.Role, + Content: record.Content, + Helpful: record.Helpful, + Unhelpful: record.Unhelpful, + CreatedAt: record.CreatedAt.Unix(), + }) + } + + return &schema.AIConversationDetailResp{ + ConversationID: conversation.ConversationID, + Topic: conversation.Topic, + Records: recordList, + CreatedAt: conversation.CreatedAt.Unix(), + UpdatedAt: conversation.UpdatedAt.Unix(), + }, true, nil +} + +// VoteRecord +func (s *aiConversationService) VoteRecord(ctx context.Context, req *schema.AIConversationVoteReq) error { + record, exist, err := s.aiConversationRepo.GetRecordByChatCompletionID(ctx, "assistant", req.ChatCompletionID) + if err != nil { + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + if !exist { + return errors.BadRequest(reason.ObjectNotFound) + } + + conversation, exist, err := s.aiConversationRepo.GetConversation(ctx, record.ConversationID) + if err != nil { + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + if !exist { + return errors.BadRequest(reason.ObjectNotFound) + } + + if conversation.UserID != req.UserID { + return errors.Forbidden(reason.UnauthorizedError) + } + + if record.Role != "assistant" { + return errors.BadRequest("Only AI responses can be voted") + } + + if req.VoteType == "helpful" { + if req.Cancel { + record.Helpful = 0 + } else { + record.Helpful = 1 + record.Unhelpful = 0 + } + } else { + if req.Cancel { + record.Unhelpful = 0 + } else { + record.Unhelpful = 1 + record.Helpful = 0 + } + } + + err = s.aiConversationRepo.UpdateRecordVote(ctx, record) + if err != nil { + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + + return nil +} + +// GetConversationListForAdmin +func (s *aiConversationService) GetConversationListForAdmin( + ctx context.Context, req *schema.AIConversationAdminListReq) (*pager.PageModel, error) { + conversations, total, err := s.aiConversationRepo.GetConversationsForAdmin(ctx, req.Page, req.PageSize, &entity.AIConversation{}) + if err != nil { + return nil, errors.InternalServer(reason.DatabaseError).WithError(err) + } + + list := make([]*schema.AIConversationAdminListItem, 0, len(conversations)) + for _, conversation := range conversations { + userInfo, err := s.getUserInfo(ctx, conversation.UserID) + if err != nil { + log.Errorf("get user info failed for user %s: %v", conversation.UserID, err) + continue + } + + helpful, unhelpful, err := s.aiConversationRepo.GetConversationWithVoteStats(ctx, conversation.ConversationID) + if err != nil { + log.Errorf("get conversation vote stats failed for conversation %s: %v", conversation.ConversationID, err) + continue + } + + list = append(list, &schema.AIConversationAdminListItem{ + ID: conversation.ConversationID, + Topic: conversation.Topic, + UserInfo: userInfo, + HelpfulCount: helpful, + UnhelpfulCount: unhelpful, + CreatedAt: conversation.CreatedAt.Unix(), + }) + } + + return pager.NewPageModel(total, list), nil +} + +// GetConversationDetailForAdmin +func (s *aiConversationService) GetConversationDetailForAdmin(ctx context.Context, req *schema.AIConversationAdminDetailReq) (*schema.AIConversationAdminDetailResp, error) { + conversation, exist, err := s.aiConversationRepo.GetConversation(ctx, req.ConversationID) + if err != nil { + return nil, errors.InternalServer(reason.DatabaseError).WithError(err) + } + if !exist { + return nil, errors.BadRequest(reason.ObjectNotFound) + } + + userInfo, err := s.getUserInfo(ctx, conversation.UserID) + if err != nil { + return nil, errors.InternalServer(reason.DatabaseError).WithError(err) + } + + records, err := s.aiConversationRepo.GetRecordsByConversationID(ctx, req.ConversationID) + if err != nil { + return nil, errors.InternalServer(reason.DatabaseError).WithError(err) + } + + recordList := make([]schema.AIConversationRecord, 0, len(records)) + for i, record := range records { + if i == 0 { + record.Content = conversation.Topic + } + recordList = append(recordList, schema.AIConversationRecord{ + ChatCompletionID: record.ChatCompletionID, + Role: record.Role, + Content: record.Content, + Helpful: record.Helpful, + Unhelpful: record.Unhelpful, + CreatedAt: record.CreatedAt.Unix(), + }) + } + + return &schema.AIConversationAdminDetailResp{ + ConversationID: conversation.ConversationID, + Topic: conversation.Topic, + UserInfo: userInfo, + Records: recordList, + CreatedAt: conversation.CreatedAt.Unix(), + }, nil +} + +// getUserInfo +func (s *aiConversationService) getUserInfo(ctx context.Context, userID string) (schema.AIConversationUserInfo, error) { + userInfo := schema.AIConversationUserInfo{} + + user, exist, err := s.userCommon.GetUserBasicInfoByID(ctx, userID) + if err != nil { + return userInfo, err + } + if !exist { + return userInfo, errors.BadRequest(reason.ObjectNotFound) + } + + userInfo.ID = user.ID + userInfo.Username = user.Username + userInfo.DisplayName = user.DisplayName + userInfo.Avatar = user.Avatar + userInfo.Rank = user.Rank + return userInfo, nil +} + +// DeleteConversationForAdmin +func (s *aiConversationService) DeleteConversationForAdmin(ctx context.Context, req *schema.AIConversationAdminDeleteReq) error { + _, exist, err := s.aiConversationRepo.GetConversation(ctx, req.ConversationID) + if err != nil { + return errors.InternalServer(reason.DatabaseError).WithError(err) + } + if !exist { + return errors.BadRequest(reason.ObjectNotFound) + } + + if err := s.aiConversationRepo.DeleteConversation(ctx, req.ConversationID); err != nil { + return err + } + + return nil +} diff --git a/internal/service/apikey/apikey_service.go b/internal/service/apikey/apikey_service.go new file mode 100644 index 000000000..43c1294ce --- /dev/null +++ b/internal/service/apikey/apikey_service.go @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package apikey + +import ( + "context" + "strings" + "time" + + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/schema" + "github.com/apache/answer/pkg/token" +) + +type APIKeyRepo interface { + GetAPIKeyList(ctx context.Context) (keys []*entity.APIKey, err error) + GetAPIKey(ctx context.Context, apiKey string) (key *entity.APIKey, exist bool, err error) + UpdateAPIKey(ctx context.Context, apiKey entity.APIKey) (err error) + AddAPIKey(ctx context.Context, apiKey entity.APIKey) (err error) + DeleteAPIKey(ctx context.Context, id int) (err error) +} + +type APIKeyService struct { + apiKeyRepo APIKeyRepo +} + +func NewAPIKeyService( + apiKeyRepo APIKeyRepo, +) *APIKeyService { + return &APIKeyService{ + apiKeyRepo: apiKeyRepo, + } +} + +func (s *APIKeyService) GetAPIKeyList(ctx context.Context, req *schema.GetAPIKeyReq) (resp []*schema.GetAPIKeyResp, err error) { + keys, err := s.apiKeyRepo.GetAPIKeyList(ctx) + if err != nil { + return nil, err + } + resp = make([]*schema.GetAPIKeyResp, 0) + for _, key := range keys { + // hide access key middle part, replace with * + if len(key.AccessKey) < 10 { + // If the access key is too short, do not mask it + key.AccessKey = strings.Repeat("*", len(key.AccessKey)) + } else { + key.AccessKey = key.AccessKey[:7] + strings.Repeat("*", 8) + key.AccessKey[len(key.AccessKey)-4:] + } + + resp = append(resp, &schema.GetAPIKeyResp{ + ID: key.ID, + AccessKey: key.AccessKey, + Description: key.Description, + Scope: key.Scope, + CreatedAt: key.CreatedAt.Unix(), + LastUsedAt: key.LastUsedAt.Unix(), + }) + } + return resp, nil +} + +func (s *APIKeyService) UpdateAPIKey(ctx context.Context, req *schema.UpdateAPIKeyReq) (err error) { + apiKey := entity.APIKey{ + ID: req.ID, + Description: req.Description, + } + err = s.apiKeyRepo.UpdateAPIKey(ctx, apiKey) + if err != nil { + return err + } + return nil +} + +func (s *APIKeyService) AddAPIKey(ctx context.Context, req *schema.AddAPIKeyReq) (resp *schema.AddAPIKeyResp, err error) { + ak := "sk_" + strings.ReplaceAll(token.GenerateToken(), "-", "") + apiKey := entity.APIKey{ + Description: req.Description, + AccessKey: ak, + Scope: req.Scope, + LastUsedAt: time.Now(), + UserID: req.UserID, + } + err = s.apiKeyRepo.AddAPIKey(ctx, apiKey) + if err != nil { + return nil, err + } + resp = &schema.AddAPIKeyResp{ + AccessKey: apiKey.AccessKey, + } + return resp, nil +} + +func (s *APIKeyService) DeleteAPIKey(ctx context.Context, req *schema.DeleteAPIKeyReq) (err error) { + err = s.apiKeyRepo.DeleteAPIKey(ctx, req.ID) + if err != nil { + return err + } + return nil +} diff --git a/internal/service/feature_toggle/feature_toggle_service.go b/internal/service/feature_toggle/feature_toggle_service.go new file mode 100644 index 000000000..b5bdad541 --- /dev/null +++ b/internal/service/feature_toggle/feature_toggle_service.go @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package feature_toggle + +import ( + "context" + "encoding/json" + + "github.com/apache/answer/internal/base/constant" + "github.com/apache/answer/internal/base/reason" + "github.com/apache/answer/internal/entity" + "github.com/apache/answer/internal/service/siteinfo_common" + "github.com/segmentfault/pacman/errors" +) + +// Feature keys +const ( + FeatureBadge = "badge" + FeatureCustomDomain = "custom_domain" + FeatureMCP = "mcp" + FeaturePrivateAPI = "private_api" + FeatureAIChatbot = "ai_chatbot" + FeatureArticle = "article" + FeatureCategory = "category" +) + +type toggleConfig struct { + Toggles map[string]bool `json:"toggles"` +} + +// FeatureToggleService persist and query feature switches. +type FeatureToggleService struct { + siteInfoRepo siteinfo_common.SiteInfoRepo +} + +// NewFeatureToggleService creates a new feature toggle service instance. +func NewFeatureToggleService(siteInfoRepo siteinfo_common.SiteInfoRepo) *FeatureToggleService { + return &FeatureToggleService{ + siteInfoRepo: siteInfoRepo, + } +} + +// UpdateAll overwrites the feature toggle configuration. +func (s *FeatureToggleService) UpdateAll(ctx context.Context, toggles map[string]bool) error { + cfg := &toggleConfig{ + Toggles: sanitizeToggleMap(toggles), + } + + data, err := json.Marshal(cfg) + if err != nil { + return err + } + + info := &entity.SiteInfo{ + Type: constant.SiteTypeFeatureToggle, + Content: string(data), + Status: 1, + } + + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeFeatureToggle, info) +} + +// GetAll returns all feature toggles. +func (s *FeatureToggleService) GetAll(ctx context.Context) (map[string]bool, error) { + siteInfo, exist, err := s.siteInfoRepo.GetByType(ctx, constant.SiteTypeFeatureToggle, true) + if err != nil { + return nil, err + } + if !exist || siteInfo == nil || siteInfo.Content == "" { + return map[string]bool{}, nil + } + + cfg := &toggleConfig{} + if err := json.Unmarshal([]byte(siteInfo.Content), cfg); err != nil { + return map[string]bool{}, err + } + return sanitizeToggleMap(cfg.Toggles), nil +} + +// IsEnabled returns whether a feature is enabled. Missing config defaults to true. +func (s *FeatureToggleService) IsEnabled(ctx context.Context, feature string) (bool, error) { + toggles, err := s.GetAll(ctx) + if err != nil { + return false, err + } + if len(toggles) == 0 { + return true, nil + } + value, ok := toggles[feature] + if !ok { + return true, nil + } + return value, nil +} + +// EnsureEnabled returns error if feature disabled. +func (s *FeatureToggleService) EnsureEnabled(ctx context.Context, feature string) error { + enabled, err := s.IsEnabled(ctx, feature) + if err != nil { + return err + } + if !enabled { + return errors.BadRequest(reason.ErrFeatureDisabled) + } + return nil +} + +func sanitizeToggleMap(in map[string]bool) map[string]bool { + if in == nil { + return map[string]bool{} + } + return in +} diff --git a/internal/service/mock/siteinfo_repo_mock.go b/internal/service/mock/siteinfo_repo_mock.go index 8feb6a27c..16f7abd8a 100644 --- a/internal/service/mock/siteinfo_repo_mock.go +++ b/internal/service/mock/siteinfo_repo_mock.go @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + // Code generated by MockGen. DO NOT EDIT. // Source: ./siteinfo_service.go // @@ -42,9 +61,13 @@ func (m *MockSiteInfoRepo) EXPECT() *MockSiteInfoRepoMockRecorder { } // GetByType mocks base method. -func (m *MockSiteInfoRepo) GetByType(ctx context.Context, siteType string) (*entity.SiteInfo, bool, error) { +func (m *MockSiteInfoRepo) GetByType(ctx context.Context, siteType string, withoutCache ...bool) (*entity.SiteInfo, bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByType", ctx, siteType) + varargs := []any{ctx, siteType} + for _, a := range withoutCache { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetByType", varargs...) ret0, _ := ret[0].(*entity.SiteInfo) ret1, _ := ret[1].(bool) ret2, _ := ret[2].(error) @@ -54,7 +77,8 @@ func (m *MockSiteInfoRepo) GetByType(ctx context.Context, siteType string) (*ent // GetByType indicates an expected call of GetByType. func (mr *MockSiteInfoRepoMockRecorder) GetByType(ctx, siteType interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByType", reflect.TypeOf((*MockSiteInfoRepo)(nil).GetByType), ctx, siteType) + varargs := append([]any{ctx, siteType}, withoutCache...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByType", reflect.TypeOf((*MockSiteInfoRepo)(nil).GetByType), varargs...) } // IsBrandingFileUsed mocks base method. diff --git a/internal/service/provider.go b/internal/service/provider.go index f6d954709..3e43b0ae0 100644 --- a/internal/service/provider.go +++ b/internal/service/provider.go @@ -24,7 +24,9 @@ import ( "github.com/apache/answer/internal/service/activity" "github.com/apache/answer/internal/service/activity_common" "github.com/apache/answer/internal/service/activityqueue" + "github.com/apache/answer/internal/service/ai_conversation" answercommon "github.com/apache/answer/internal/service/answer_common" + "github.com/apache/answer/internal/service/apikey" "github.com/apache/answer/internal/service/auth" "github.com/apache/answer/internal/service/badge" "github.com/apache/answer/internal/service/collection" @@ -36,6 +38,7 @@ import ( "github.com/apache/answer/internal/service/dashboard" "github.com/apache/answer/internal/service/eventqueue" "github.com/apache/answer/internal/service/export" + "github.com/apache/answer/internal/service/feature_toggle" "github.com/apache/answer/internal/service/file_record" "github.com/apache/answer/internal/service/follow" "github.com/apache/answer/internal/service/importer" @@ -128,4 +131,7 @@ var ProviderSetService = wire.NewSet( badge.NewBadgeGroupService, importer.NewImporterService, file_record.NewFileRecordService, + apikey.NewAPIKeyService, + ai_conversation.NewAIConversationService, + feature_toggle.NewFeatureToggleService, ) diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index cc0cb5997..6cdb8ae5a 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -39,7 +39,9 @@ import ( "github.com/apache/answer/internal/service/siteinfo_common" tagcommon "github.com/apache/answer/internal/service/tag_common" "github.com/apache/answer/plugin" + "github.com/go-resty/resty/v2" "github.com/jinzhu/copier" + "github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/log" ) @@ -335,6 +337,154 @@ func (s *SiteInfoService) SaveSiteUsers(ctx context.Context, req *schema.SiteUse return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeUsers, data) } +// GetSiteAI get site AI configuration +func (s *SiteInfoService) GetSiteAI(ctx context.Context) (resp *schema.SiteAIResp, err error) { + resp, err = s.siteInfoCommonService.GetSiteAI(ctx) + if err != nil { + return nil, err + } + aiProvider, err := s.GetAIProvider(ctx) + if err != nil { + return nil, err + } + providerMapping := make(map[string]*schema.SiteAIProvider) + for _, provider := range resp.SiteAIProviders { + providerMapping[provider.Provider] = provider + } + providers := make([]*schema.SiteAIProvider, 0) + for _, p := range aiProvider { + if provider, ok := providerMapping[p.Name]; ok { + providers = append(providers, provider) + } else { + providers = append(providers, &schema.SiteAIProvider{ + Provider: p.Name, + }) + } + } + resp.SiteAIProviders = providers + s.maskAIKeys(resp) + return resp, nil +} + +// SaveSiteAI save site AI configuration +func (s *SiteInfoService) SaveSiteAI(ctx context.Context, req *schema.SiteAIReq) (err error) { + if err := s.restoreMaskedAIKeys(ctx, req); err != nil { + return err + } + if req.PromptConfig == nil { + req.PromptConfig = &schema.AIPromptConfig{ + ZhCN: constant.DefaultAIPromptConfigZhCN, + EnUS: constant.DefaultAIPromptConfigEnUS, + } + } + + aiProvider, err := s.GetAIProvider(ctx) + if err != nil { + return err + } + + providerMapping := make(map[string]*schema.SiteAIProvider) + for _, provider := range req.SiteAIProviders { + providerMapping[provider.Provider] = provider + } + + providers := make([]*schema.SiteAIProvider, 0) + for _, p := range aiProvider { + if provider, ok := providerMapping[p.Name]; ok { + if len(provider.APIHost) == 0 && provider.Provider == req.ChosenProvider { + provider.APIHost = p.DefaultAPIHost + } + providers = append(providers, provider) + } else { + providers = append(providers, &schema.SiteAIProvider{ + Provider: p.Name, + APIHost: p.DefaultAPIHost, + }) + } + } + req.SiteAIProviders = providers + + content, _ := json.Marshal(req) + siteInfo := &entity.SiteInfo{ + Type: constant.SiteTypeAI, + Content: string(content), + Status: 1, + } + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeAI, siteInfo) +} + +func (s *SiteInfoService) maskAIKeys(resp *schema.SiteAIResp) { + for _, provider := range resp.SiteAIProviders { + if provider.APIKey == "" { + continue + } + provider.APIKey = strings.Repeat("*", len(provider.APIKey)) + } +} + +func (s *SiteInfoService) restoreMaskedAIKeys(ctx context.Context, req *schema.SiteAIReq) error { + hasMasked := false + for _, provider := range req.SiteAIProviders { + if provider.APIKey != "" && isAllMask(provider.APIKey) { + hasMasked = true + break + } + } + if !hasMasked { + return nil + } + + current, err := s.siteInfoCommonService.GetSiteAI(ctx) + if err != nil { + return err + } + currentMapping := make(map[string]*schema.SiteAIProvider) + for _, provider := range current.SiteAIProviders { + currentMapping[provider.Provider] = provider + } + for _, provider := range req.SiteAIProviders { + if provider.APIKey == "" || !isAllMask(provider.APIKey) { + continue + } + if stored, ok := currentMapping[provider.Provider]; ok { + provider.APIKey = stored.APIKey + } + } + return nil +} + +func isAllMask(value string) bool { + return strings.Trim(value, "*") == "" +} + +// GetSiteMCP get site MCP configuration +func (s *SiteInfoService) GetSiteMCP(ctx context.Context) (resp *schema.SiteMCPResp, err error) { + resp, err = s.siteInfoCommonService.GetSiteMCP(ctx) + if err != nil { + return nil, err + } + siteInfo, err := s.GetSiteGeneral(ctx) + if err != nil { + return nil, err + } + + resp.Type = "Server-Sent Event (SSE)" + resp.URL = fmt.Sprintf("%s/answer/api/v1/mcp/sse", siteInfo.SiteUrl) + resp.HTTPHeader = "Authorization={key}" + return +} + +// SaveSiteMCP save site MCP configuration +func (s *SiteInfoService) SaveSiteMCP(ctx context.Context, req *schema.SiteMCPReq) (err error) { + content, _ := json.Marshal(req) + siteInfo := &entity.SiteInfo{ + Type: constant.SiteTypeMCP, + Content: string(content), + Status: 1, + } + return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeMCP, siteInfo) +} + // GetSMTPConfig get smtp config func (s *SiteInfoService) GetSMTPConfig(ctx context.Context) (resp *schema.GetSMTPConfigResp, err error) { emailConfig, err := s.emailService.GetEmailConfig(ctx) @@ -548,3 +698,76 @@ func (s *SiteInfoService) CleanUpRemovedBrandingFiles( } return nil } + +func (s *SiteInfoService) GetAIProvider(ctx context.Context) (resp []*schema.GetAIProviderResp, err error) { + resp = make([]*schema.GetAIProviderResp, 0) + aiProviderConfig, err := s.configService.GetStringValue(context.TODO(), constant.AIConfigProvider) + if err != nil { + log.Error(err) + return resp, nil + } + + _ = json.Unmarshal([]byte(aiProviderConfig), &resp) + return resp, nil +} + +func (s *SiteInfoService) GetAIModels(ctx context.Context, req *schema.GetAIModelsReq) (resp []*schema.GetAIModelResp, err error) { + resp = make([]*schema.GetAIModelResp, 0) + if req.APIKey != "" && isAllMask(req.APIKey) { + storedKey, err := s.getStoredAIKey(ctx, req.APIHost) + if err != nil { + return resp, err + } + if storedKey == "" { + return resp, errors.BadRequest("api_key is required") + } + req.APIKey = storedKey + } + + r := resty.New() + r.SetHeader("Authorization", fmt.Sprintf("Bearer %s", req.APIKey)) + r.SetHeader("Content-Type", "application/json") + respBody, err := r.R().Get(req.APIHost + "/v1/models") + if err != nil { + log.Error(err) + return resp, errors.BadRequest(fmt.Sprintf("failed to get AI models %s", err.Error())) + } + if !respBody.IsSuccess() { + log.Error(fmt.Sprintf("failed to get AI models, status code: %d, body: %s", respBody.StatusCode(), respBody.String())) + return resp, errors.BadRequest(fmt.Sprintf("failed to get AI models, response: %s", respBody.String())) + } + + data := schema.GetAIModelsResp{} + _ = json.Unmarshal(respBody.Body(), &data) + + for _, model := range data.Data { + resp = append(resp, &schema.GetAIModelResp{ + Id: model.Id, + Object: model.Object, + Created: model.Created, + OwnedBy: model.OwnedBy, + }) + } + return resp, nil +} + +func (s *SiteInfoService) getStoredAIKey(ctx context.Context, apiHost string) (string, error) { + current, err := s.siteInfoCommonService.GetSiteAI(ctx) + if err != nil { + return "", err + } + apiHost = strings.TrimRight(apiHost, "/") + for _, provider := range current.SiteAIProviders { + if strings.TrimRight(provider.APIHost, "/") == apiHost && provider.APIKey != "" { + return provider.APIKey, nil + } + } + if current.ChosenProvider != "" { + for _, provider := range current.SiteAIProviders { + if provider.Provider == current.ChosenProvider { + return provider.APIKey, nil + } + } + } + return "", nil +} diff --git a/internal/service/siteinfo_common/siteinfo_service.go b/internal/service/siteinfo_common/siteinfo_service.go index 2f2efb799..90d48fc3a 100644 --- a/internal/service/siteinfo_common/siteinfo_service.go +++ b/internal/service/siteinfo_common/siteinfo_service.go @@ -34,7 +34,7 @@ import ( //go:generate mockgen -source=./siteinfo_service.go -destination=../mock/siteinfo_repo_mock.go -package=mock type SiteInfoRepo interface { SaveByType(ctx context.Context, siteType string, data *entity.SiteInfo) (err error) - GetByType(ctx context.Context, siteType string) (siteInfo *entity.SiteInfo, exist bool, err error) + GetByType(ctx context.Context, siteType string, withoutCache ...bool) (siteInfo *entity.SiteInfo, exist bool, err error) IsBrandingFileUsed(ctx context.Context, filePath string) (bool, error) } @@ -63,6 +63,8 @@ type SiteInfoCommonService interface { GetSiteSeo(ctx context.Context) (resp *schema.SiteSeoResp, err error) GetSiteInfoByType(ctx context.Context, siteType string, resp any) (err error) IsBrandingFileUsed(ctx context.Context, filePath string) bool + GetSiteAI(ctx context.Context) (resp *schema.SiteAIResp, err error) + GetSiteMCP(ctx context.Context) (resp *schema.SiteMCPResp, err error) } // NewSiteInfoCommonService new site info common service @@ -299,3 +301,21 @@ func (s *siteInfoCommonService) IsBrandingFileUsed(ctx context.Context, filePath } return used } + +// GetSiteAI get site AI configuration +func (s *siteInfoCommonService) GetSiteAI(ctx context.Context) (resp *schema.SiteAIResp, err error) { + resp = &schema.SiteAIResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeAI, resp); err != nil { + return nil, err + } + return resp, nil +} + +// GetSiteMCP get site AI configuration +func (s *siteInfoCommonService) GetSiteMCP(ctx context.Context) (resp *schema.SiteMCPResp, err error) { + resp = &schema.SiteMCPResp{} + if err = s.GetSiteInfoByType(ctx, constant.SiteTypeMCP, resp); err != nil { + return nil, err + } + return resp, nil +} From 94c030829d94910179ff8f3a03285f5f8c51bbdd Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Fri, 23 Jan 2026 17:22:13 +0800 Subject: [PATCH 83/92] fix: correct loop iteration in AI conversation rounds --- internal/controller/ai_controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/controller/ai_controller.go b/internal/controller/ai_controller.go index aa7d2819b..85db78a93 100644 --- a/internal/controller/ai_controller.go +++ b/internal/controller/ai_controller.go @@ -433,7 +433,7 @@ func (c *AIController) handleAIConversation(ctx *gin.Context, w http.ResponseWri maxRounds := 10 messages := conversationCtx.GetOpenAIMessages() - for round := 0; round < maxRounds; round++ { + for round := range maxRounds { log.Debugf("AI conversation round: %d", round+1) aiReq := openai.ChatCompletionRequest{ From f403eadb2c8b7b560623325c4d0dc49406468bdb Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Fri, 23 Jan 2026 17:28:19 +0800 Subject: [PATCH 84/92] feat: add AI conversation management endpoints and update related schemas --- docs/docs.go | 1322 +++++++++++++++-- docs/swagger.json | 1322 +++++++++++++++-- docs/swagger.yaml | 628 ++++++++ go.mod | 10 +- internal/base/constant/site_type.go | 4 +- internal/migrations/{v32.go => v31.go} | 0 internal/schema/siteinfo_schema.go | 4 +- internal/service/mock/siteinfo_repo_mock.go | 76 +- ui/src/components/TabNav/index.tsx | 19 + .../AiAssistant/components/Action/index.tsx | 1 + .../components/ConversationList/index.tsx | 1 + .../pages/Search/components/AiCard/index.tsx | 19 + ui/src/utils/requestAi.ts | 19 + 13 files changed, 3106 insertions(+), 319 deletions(-) rename internal/migrations/{v32.go => v31.go} (100%) diff --git a/docs/docs.go b/docs/docs.go index 0cd064294..57a23d432 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -50,6 +50,297 @@ const docTemplate = `{ "responses": {} } }, + "/answer/admin/api/ai-config": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get AI configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get AI configuration", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteAIResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update AI configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update AI configuration", + "parameters": [ + { + "description": "AI config", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteAIReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/ai-models": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get AI models", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get AI models", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetAIModelResp" + } + } + } + } + ] + } + } + } + } + }, + "/answer/admin/api/ai-provider": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get AI provider configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get AI provider configuration", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetAIProviderResp" + } + } + } + } + ] + } + } + } + } + }, + "/answer/admin/api/ai/conversation": { + "get": { + "description": "get conversation detail for admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation-admin" + ], + "summary": "get conversation detail for admin", + "parameters": [ + { + "type": "string", + "description": "conversation id", + "name": "conversation_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.AIConversationAdminDetailResp" + } + } + } + ] + } + } + } + }, + "delete": { + "description": "delete conversation and its related records for admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation-admin" + ], + "summary": "delete conversation for admin", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AIConversationAdminDeleteReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/ai/conversation/page": { + "get": { + "description": "get conversation list for admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation-admin" + ], + "summary": "get conversation list for admin", + "parameters": [ + { + "type": "integer", + "description": "page", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "page size", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/pager.PageModel" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationAdminListItem" + } + } + } + } + ] + } + } + } + ] + } + } + } + } + }, "/answer/admin/api/answer/page": { "get": { "security": [ @@ -132,23 +423,179 @@ const docTemplate = `{ "tags": [ "admin" ], - "summary": "update answer status", - "parameters": [ - { - "description": "AdminUpdateAnswerStatusReq", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/schema.AdminUpdateAnswerStatusReq" - } - } - ], + "summary": "update answer status", + "parameters": [ + { + "description": "AdminUpdateAnswerStatusReq", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AdminUpdateAnswerStatusReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/api-key": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update apikey", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update apikey", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.UpdateAPIKeyReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + }, + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "add apikey", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "add apikey", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AddAPIKeyReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.AddAPIKeyResp" + } + } + } + ] + } + } + } + }, + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "delete apikey", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "delete apikey", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.DeleteAPIKeyReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/api-key/all": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get all api keys", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get all api keys", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/handler.RespBody" + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetAPIKeyResp" + } + } + } + } + ] } } } @@ -359,6 +806,77 @@ const docTemplate = `{ } } }, + "/answer/admin/api/mcp-config": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get MCP configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get MCP configuration", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteMCPResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update MCP configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update MCP configuration", + "parameters": [ + { + "description": "MCP config", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteMCPReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/plugin/config": { "get": { "security": [ @@ -2251,15 +2769,178 @@ const docTemplate = `{ "in": "query" }, { - "enum": [ - "suspended", - "deleted", - "inactive" - ], + "enum": [ + "suspended", + "deleted", + "inactive" + ], + "type": "string", + "description": "user status", + "name": "status", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/pager.PageModel" + }, + { + "type": "object", + "properties": { + "records": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetUserPageResp" + } + } + } + } + ] + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/activity/timeline": { + "get": { + "description": "get object timeline", + "produces": [ + "application/json" + ], + "tags": [ + "Comment" + ], + "summary": "get object timeline", + "parameters": [ + { + "type": "string", + "description": "object id", + "name": "object_id", + "in": "query" + }, + { + "type": "string", + "description": "tag slug name", + "name": "tag_slug_name", + "in": "query" + }, + { + "enum": [ + "question", + "answer", + "tag" + ], + "type": "string", + "description": "object type", + "name": "object_type", + "in": "query" + }, + { + "type": "boolean", + "description": "is show vote", + "name": "show_vote", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.GetObjectTimelineResp" + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/activity/timeline/detail": { + "get": { + "description": "get object timeline detail", + "produces": [ + "application/json" + ], + "tags": [ + "Comment" + ], + "summary": "get object timeline detail", + "parameters": [ + { + "type": "string", + "description": "revision id", + "name": "revision_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.GetObjectTimelineResp" + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/ai/conversation": { + "get": { + "description": "get conversation detail", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation" + ], + "summary": "get conversation detail", + "parameters": [ + { "type": "string", - "description": "user status", - "name": "status", - "in": "query" + "description": "conversation id", + "name": "conversation_id", + "in": "query", + "required": true } ], "responses": { @@ -2274,22 +2955,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "allOf": [ - { - "$ref": "#/definitions/pager.PageModel" - }, - { - "type": "object", - "properties": { - "records": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.GetUserPageResp" - } - } - } - } - ] + "$ref": "#/definitions/schema.AIConversationDetailResp" } } } @@ -2299,44 +2965,30 @@ const docTemplate = `{ } } }, - "/answer/api/v1/activity/timeline": { + "/answer/api/v1/ai/conversation/page": { "get": { - "description": "get object timeline", + "description": "get conversation list", + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "Comment" + "ai-conversation" ], - "summary": "get object timeline", + "summary": "get conversation list", "parameters": [ { - "type": "string", - "description": "object id", - "name": "object_id", - "in": "query" - }, - { - "type": "string", - "description": "tag slug name", - "name": "tag_slug_name", - "in": "query" - }, - { - "enum": [ - "question", - "answer", - "tag" - ], - "type": "string", - "description": "object type", - "name": "object_type", + "type": "integer", + "description": "page", + "name": "page", "in": "query" }, { - "type": "boolean", - "description": "is show vote", - "name": "show_vote", + "type": "integer", + "description": "page size", + "name": "page_size", "in": "query" } ], @@ -2352,7 +3004,22 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.GetObjectTimelineResp" + "allOf": [ + { + "$ref": "#/definitions/pager.PageModel" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationListItem" + } + } + } + } + ] } } } @@ -2362,42 +3029,35 @@ const docTemplate = `{ } } }, - "/answer/api/v1/activity/timeline/detail": { - "get": { - "description": "get object timeline detail", + "/answer/api/v1/ai/conversation/vote": { + "post": { + "description": "vote record", + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "Comment" + "ai-conversation" ], - "summary": "get object timeline detail", + "summary": "vote record", "parameters": [ { - "type": "string", - "description": "revision id", - "name": "revision_id", - "in": "query", - "required": true + "description": "vote request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AIConversationVoteReq" + } } ], "responses": { "200": { "description": "OK", "schema": { - "allOf": [ - { - "$ref": "#/definitions/handler.RespBody" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/schema.GetObjectTimelineResp" - } - } - } - ] + "$ref": "#/definitions/handler.RespBody" } } } @@ -7915,99 +8575,269 @@ const docTemplate = `{ "ssl_cert": { "type": "string" }, - "ssl_enabled": { - "type": "boolean" + "ssl_enabled": { + "type": "boolean" + }, + "ssl_key": { + "type": "string" + }, + "ssl_mode": { + "type": "string" + }, + "ssl_root_cert": { + "type": "string" + } + } + }, + "install.InitBaseInfoReq": { + "type": "object", + "required": [ + "contact_email", + "email", + "external_content_display", + "lang", + "name", + "password", + "site_name", + "site_url" + ], + "properties": { + "contact_email": { + "type": "string", + "maxLength": 500 + }, + "email": { + "type": "string", + "maxLength": 500 + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "lang": { + "type": "string", + "maxLength": 30 + }, + "login_required": { + "type": "boolean" + }, + "name": { + "type": "string", + "maxLength": 30, + "minLength": 2 + }, + "password": { + "type": "string", + "maxLength": 32, + "minLength": 8 + }, + "site_name": { + "type": "string", + "maxLength": 30 + }, + "site_url": { + "type": "string", + "maxLength": 512 + } + } + }, + "pager.PageModel": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "list": {} + } + }, + "plugin.EmbedConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "platform": { + "type": "string" + } + } + }, + "plugin.RenderConfig": { + "type": "object", + "properties": { + "select_theme": { + "type": "string" + } + } + }, + "schema.AIConversationAdminDeleteReq": { + "type": "object", + "required": [ + "conversation_id" + ], + "properties": { + "conversation_id": { + "type": "string" + } + } + }, + "schema.AIConversationAdminDetailResp": { + "type": "object", + "properties": { + "conversation_id": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "records": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationRecord" + } + }, + "topic": { + "type": "string" + }, + "user_info": { + "$ref": "#/definitions/schema.AIConversationUserInfo" + } + } + }, + "schema.AIConversationAdminListItem": { + "type": "object", + "properties": { + "created_at": { + "type": "integer" + }, + "helpful_count": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "topic": { + "type": "string" + }, + "unhelpful_count": { + "type": "integer" + }, + "user_info": { + "$ref": "#/definitions/schema.AIConversationUserInfo" + } + } + }, + "schema.AIConversationDetailResp": { + "type": "object", + "properties": { + "conversation_id": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "records": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationRecord" + } }, - "ssl_key": { + "topic": { "type": "string" }, - "ssl_mode": { + "updated_at": { + "type": "integer" + } + } + }, + "schema.AIConversationListItem": { + "type": "object", + "properties": { + "conversation_id": { "type": "string" }, - "ssl_root_cert": { + "created_at": { + "type": "integer" + }, + "topic": { "type": "string" } } }, - "install.InitBaseInfoReq": { + "schema.AIConversationRecord": { "type": "object", - "required": [ - "contact_email", - "email", - "external_content_display", - "lang", - "name", - "password", - "site_name", - "site_url" - ], "properties": { - "contact_email": { - "type": "string", - "maxLength": 500 - }, - "email": { - "type": "string", - "maxLength": 500 - }, - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "lang": { - "type": "string", - "maxLength": 30 + "chat_completion_id": { + "type": "string" }, - "login_required": { - "type": "boolean" + "content": { + "type": "string" }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 2 + "created_at": { + "type": "integer" }, - "password": { - "type": "string", - "maxLength": 32, - "minLength": 8 + "helpful": { + "type": "integer" }, - "site_name": { - "type": "string", - "maxLength": 30 + "role": { + "type": "string" }, - "site_url": { - "type": "string", - "maxLength": 512 + "unhelpful": { + "type": "integer" } } }, - "pager.PageModel": { + "schema.AIConversationUserInfo": { "type": "object", "properties": { - "count": { + "avatar": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "rank": { "type": "integer" }, - "list": {} + "username": { + "type": "string" + } } }, - "plugin.EmbedConfig": { + "schema.AIConversationVoteReq": { "type": "object", + "required": [ + "chat_completion_id", + "vote_type" + ], "properties": { - "enable": { + "cancel": { "type": "boolean" }, - "platform": { + "chat_completion_id": { "type": "string" + }, + "vote_type": { + "type": "string", + "enum": [ + "helpful", + "unhelpful" + ] } } }, - "plugin.RenderConfig": { + "schema.AIPromptConfig": { "type": "object", "properties": { - "select_theme": { + "en_us": { + "type": "string" + }, + "zh_cn": { "type": "string" } } @@ -8102,6 +8932,34 @@ const docTemplate = `{ } } }, + "schema.AddAPIKeyReq": { + "type": "object", + "required": [ + "description", + "scope" + ], + "properties": { + "description": { + "type": "string", + "maxLength": 150 + }, + "scope": { + "type": "string", + "enum": [ + "read-only", + "global" + ] + } + } + }, + "schema.AddAPIKeyResp": { + "type": "object", + "properties": { + "access_key": { + "type": "string" + } + } + }, "schema.AddCommentReq": { "type": "object", "required": [ @@ -8582,6 +9440,14 @@ const docTemplate = `{ } } }, + "schema.DeleteAPIKeyReq": { + "type": "object", + "properties": { + "id": { + "type": "integer" + } + } + }, "schema.DeletePermanentlyReq": { "type": "object", "required": [ @@ -8698,6 +9564,60 @@ const docTemplate = `{ } } }, + "schema.GetAIModelResp": { + "type": "object", + "properties": { + "created": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "object": { + "type": "string" + }, + "owned_by": { + "type": "string" + } + } + }, + "schema.GetAIProviderResp": { + "type": "object", + "properties": { + "default_api_host": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "schema.GetAPIKeyResp": { + "type": "object", + "properties": { + "access_key": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "last_used_at": { + "type": "integer" + }, + "scope": { + "type": "string" + } + } + }, "schema.GetAnswerInfoResp": { "type": "object", "properties": { @@ -10781,6 +11701,69 @@ const docTemplate = `{ } } }, + "schema.SiteAIProvider": { + "type": "object", + "properties": { + "api_host": { + "type": "string", + "maxLength": 512 + }, + "api_key": { + "type": "string", + "maxLength": 256 + }, + "model": { + "type": "string", + "maxLength": 100 + }, + "provider": { + "type": "string", + "maxLength": 50 + } + } + }, + "schema.SiteAIReq": { + "type": "object", + "properties": { + "ai_providers": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteAIProvider" + } + }, + "chosen_provider": { + "type": "string", + "maxLength": 50 + }, + "enabled": { + "type": "boolean" + }, + "prompt_config": { + "$ref": "#/definitions/schema.AIPromptConfig" + } + } + }, + "schema.SiteAIResp": { + "type": "object", + "properties": { + "ai_providers": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteAIProvider" + } + }, + "chosen_provider": { + "type": "string", + "maxLength": 50 + }, + "enabled": { + "type": "boolean" + }, + "prompt_config": { + "$ref": "#/definitions/schema.AIPromptConfig" + } + } + }, "schema.SiteAdvancedReq": { "type": "object", "properties": { @@ -10988,6 +11971,9 @@ const docTemplate = `{ "schema.SiteInfoResp": { "type": "object", "properties": { + "ai_enabled": { + "type": "boolean" + }, "branding": { "$ref": "#/definitions/schema.SiteBrandingResp" }, @@ -11003,6 +11989,9 @@ const docTemplate = `{ "login": { "$ref": "#/definitions/schema.SiteLoginResp" }, + "mcp_enabled": { + "type": "boolean" + }, "revision": { "type": "string" }, @@ -11127,6 +12116,31 @@ const docTemplate = `{ } } }, + "schema.SiteMCPReq": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "schema.SiteMCPResp": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "http_header": { + "type": "string" + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, "schema.SitePoliciesReq": { "type": "object", "properties": { @@ -11631,6 +12645,22 @@ const docTemplate = `{ } } }, + "schema.UpdateAPIKeyReq": { + "type": "object", + "required": [ + "description", + "id" + ], + "properties": { + "description": { + "type": "string", + "maxLength": 150 + }, + "id": { + "type": "integer" + } + } + }, "schema.UpdateBadgeStatusReq": { "type": "object", "required": [ diff --git a/docs/swagger.json b/docs/swagger.json index a59867f96..dac2b38fd 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -23,6 +23,297 @@ "responses": {} } }, + "/answer/admin/api/ai-config": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get AI configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get AI configuration", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteAIResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update AI configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update AI configuration", + "parameters": [ + { + "description": "AI config", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteAIReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/ai-models": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get AI models", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get AI models", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetAIModelResp" + } + } + } + } + ] + } + } + } + } + }, + "/answer/admin/api/ai-provider": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get AI provider configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get AI provider configuration", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetAIProviderResp" + } + } + } + } + ] + } + } + } + } + }, + "/answer/admin/api/ai/conversation": { + "get": { + "description": "get conversation detail for admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation-admin" + ], + "summary": "get conversation detail for admin", + "parameters": [ + { + "type": "string", + "description": "conversation id", + "name": "conversation_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.AIConversationAdminDetailResp" + } + } + } + ] + } + } + } + }, + "delete": { + "description": "delete conversation and its related records for admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation-admin" + ], + "summary": "delete conversation for admin", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AIConversationAdminDeleteReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/ai/conversation/page": { + "get": { + "description": "get conversation list for admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation-admin" + ], + "summary": "get conversation list for admin", + "parameters": [ + { + "type": "integer", + "description": "page", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "page size", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/pager.PageModel" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationAdminListItem" + } + } + } + } + ] + } + } + } + ] + } + } + } + } + }, "/answer/admin/api/answer/page": { "get": { "security": [ @@ -105,23 +396,179 @@ "tags": [ "admin" ], - "summary": "update answer status", - "parameters": [ - { - "description": "AdminUpdateAnswerStatusReq", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/schema.AdminUpdateAnswerStatusReq" - } - } - ], + "summary": "update answer status", + "parameters": [ + { + "description": "AdminUpdateAnswerStatusReq", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AdminUpdateAnswerStatusReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/api-key": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update apikey", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update apikey", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.UpdateAPIKeyReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + }, + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "add apikey", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "add apikey", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AddAPIKeyReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.AddAPIKeyResp" + } + } + } + ] + } + } + } + }, + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "delete apikey", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "delete apikey", + "parameters": [ + { + "description": "apikey", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.DeleteAPIKeyReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/api-key/all": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get all api keys", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get all api keys", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/handler.RespBody" + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetAPIKeyResp" + } + } + } + } + ] } } } @@ -332,6 +779,77 @@ } } }, + "/answer/admin/api/mcp-config": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get MCP configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get MCP configuration", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteMCPResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update MCP configuration", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update MCP configuration", + "parameters": [ + { + "description": "MCP config", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteMCPReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/plugin/config": { "get": { "security": [ @@ -2224,15 +2742,178 @@ "in": "query" }, { - "enum": [ - "suspended", - "deleted", - "inactive" - ], + "enum": [ + "suspended", + "deleted", + "inactive" + ], + "type": "string", + "description": "user status", + "name": "status", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/pager.PageModel" + }, + { + "type": "object", + "properties": { + "records": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.GetUserPageResp" + } + } + } + } + ] + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/activity/timeline": { + "get": { + "description": "get object timeline", + "produces": [ + "application/json" + ], + "tags": [ + "Comment" + ], + "summary": "get object timeline", + "parameters": [ + { + "type": "string", + "description": "object id", + "name": "object_id", + "in": "query" + }, + { + "type": "string", + "description": "tag slug name", + "name": "tag_slug_name", + "in": "query" + }, + { + "enum": [ + "question", + "answer", + "tag" + ], + "type": "string", + "description": "object type", + "name": "object_type", + "in": "query" + }, + { + "type": "boolean", + "description": "is show vote", + "name": "show_vote", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.GetObjectTimelineResp" + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/activity/timeline/detail": { + "get": { + "description": "get object timeline detail", + "produces": [ + "application/json" + ], + "tags": [ + "Comment" + ], + "summary": "get object timeline detail", + "parameters": [ + { + "type": "string", + "description": "revision id", + "name": "revision_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.GetObjectTimelineResp" + } + } + } + ] + } + } + } + } + }, + "/answer/api/v1/ai/conversation": { + "get": { + "description": "get conversation detail", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ai-conversation" + ], + "summary": "get conversation detail", + "parameters": [ + { "type": "string", - "description": "user status", - "name": "status", - "in": "query" + "description": "conversation id", + "name": "conversation_id", + "in": "query", + "required": true } ], "responses": { @@ -2247,22 +2928,7 @@ "type": "object", "properties": { "data": { - "allOf": [ - { - "$ref": "#/definitions/pager.PageModel" - }, - { - "type": "object", - "properties": { - "records": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.GetUserPageResp" - } - } - } - } - ] + "$ref": "#/definitions/schema.AIConversationDetailResp" } } } @@ -2272,44 +2938,30 @@ } } }, - "/answer/api/v1/activity/timeline": { + "/answer/api/v1/ai/conversation/page": { "get": { - "description": "get object timeline", + "description": "get conversation list", + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "Comment" + "ai-conversation" ], - "summary": "get object timeline", + "summary": "get conversation list", "parameters": [ { - "type": "string", - "description": "object id", - "name": "object_id", - "in": "query" - }, - { - "type": "string", - "description": "tag slug name", - "name": "tag_slug_name", - "in": "query" - }, - { - "enum": [ - "question", - "answer", - "tag" - ], - "type": "string", - "description": "object type", - "name": "object_type", + "type": "integer", + "description": "page", + "name": "page", "in": "query" }, { - "type": "boolean", - "description": "is show vote", - "name": "show_vote", + "type": "integer", + "description": "page size", + "name": "page_size", "in": "query" } ], @@ -2325,7 +2977,22 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.GetObjectTimelineResp" + "allOf": [ + { + "$ref": "#/definitions/pager.PageModel" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationListItem" + } + } + } + } + ] } } } @@ -2335,42 +3002,35 @@ } } }, - "/answer/api/v1/activity/timeline/detail": { - "get": { - "description": "get object timeline detail", + "/answer/api/v1/ai/conversation/vote": { + "post": { + "description": "vote record", + "consumes": [ + "application/json" + ], "produces": [ "application/json" ], "tags": [ - "Comment" + "ai-conversation" ], - "summary": "get object timeline detail", + "summary": "vote record", "parameters": [ { - "type": "string", - "description": "revision id", - "name": "revision_id", - "in": "query", - "required": true + "description": "vote request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AIConversationVoteReq" + } } ], "responses": { "200": { "description": "OK", "schema": { - "allOf": [ - { - "$ref": "#/definitions/handler.RespBody" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/schema.GetObjectTimelineResp" - } - } - } - ] + "$ref": "#/definitions/handler.RespBody" } } } @@ -7888,99 +8548,269 @@ "ssl_cert": { "type": "string" }, - "ssl_enabled": { - "type": "boolean" + "ssl_enabled": { + "type": "boolean" + }, + "ssl_key": { + "type": "string" + }, + "ssl_mode": { + "type": "string" + }, + "ssl_root_cert": { + "type": "string" + } + } + }, + "install.InitBaseInfoReq": { + "type": "object", + "required": [ + "contact_email", + "email", + "external_content_display", + "lang", + "name", + "password", + "site_name", + "site_url" + ], + "properties": { + "contact_email": { + "type": "string", + "maxLength": 500 + }, + "email": { + "type": "string", + "maxLength": 500 + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "lang": { + "type": "string", + "maxLength": 30 + }, + "login_required": { + "type": "boolean" + }, + "name": { + "type": "string", + "maxLength": 30, + "minLength": 2 + }, + "password": { + "type": "string", + "maxLength": 32, + "minLength": 8 + }, + "site_name": { + "type": "string", + "maxLength": 30 + }, + "site_url": { + "type": "string", + "maxLength": 512 + } + } + }, + "pager.PageModel": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "list": {} + } + }, + "plugin.EmbedConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "platform": { + "type": "string" + } + } + }, + "plugin.RenderConfig": { + "type": "object", + "properties": { + "select_theme": { + "type": "string" + } + } + }, + "schema.AIConversationAdminDeleteReq": { + "type": "object", + "required": [ + "conversation_id" + ], + "properties": { + "conversation_id": { + "type": "string" + } + } + }, + "schema.AIConversationAdminDetailResp": { + "type": "object", + "properties": { + "conversation_id": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "records": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationRecord" + } + }, + "topic": { + "type": "string" + }, + "user_info": { + "$ref": "#/definitions/schema.AIConversationUserInfo" + } + } + }, + "schema.AIConversationAdminListItem": { + "type": "object", + "properties": { + "created_at": { + "type": "integer" + }, + "helpful_count": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "topic": { + "type": "string" + }, + "unhelpful_count": { + "type": "integer" + }, + "user_info": { + "$ref": "#/definitions/schema.AIConversationUserInfo" + } + } + }, + "schema.AIConversationDetailResp": { + "type": "object", + "properties": { + "conversation_id": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "records": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.AIConversationRecord" + } }, - "ssl_key": { + "topic": { "type": "string" }, - "ssl_mode": { + "updated_at": { + "type": "integer" + } + } + }, + "schema.AIConversationListItem": { + "type": "object", + "properties": { + "conversation_id": { "type": "string" }, - "ssl_root_cert": { + "created_at": { + "type": "integer" + }, + "topic": { "type": "string" } } }, - "install.InitBaseInfoReq": { + "schema.AIConversationRecord": { "type": "object", - "required": [ - "contact_email", - "email", - "external_content_display", - "lang", - "name", - "password", - "site_name", - "site_url" - ], "properties": { - "contact_email": { - "type": "string", - "maxLength": 500 - }, - "email": { - "type": "string", - "maxLength": 500 - }, - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "lang": { - "type": "string", - "maxLength": 30 + "chat_completion_id": { + "type": "string" }, - "login_required": { - "type": "boolean" + "content": { + "type": "string" }, - "name": { - "type": "string", - "maxLength": 30, - "minLength": 2 + "created_at": { + "type": "integer" }, - "password": { - "type": "string", - "maxLength": 32, - "minLength": 8 + "helpful": { + "type": "integer" }, - "site_name": { - "type": "string", - "maxLength": 30 + "role": { + "type": "string" }, - "site_url": { - "type": "string", - "maxLength": 512 + "unhelpful": { + "type": "integer" } } }, - "pager.PageModel": { + "schema.AIConversationUserInfo": { "type": "object", "properties": { - "count": { + "avatar": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "rank": { "type": "integer" }, - "list": {} + "username": { + "type": "string" + } } }, - "plugin.EmbedConfig": { + "schema.AIConversationVoteReq": { "type": "object", + "required": [ + "chat_completion_id", + "vote_type" + ], "properties": { - "enable": { + "cancel": { "type": "boolean" }, - "platform": { + "chat_completion_id": { "type": "string" + }, + "vote_type": { + "type": "string", + "enum": [ + "helpful", + "unhelpful" + ] } } }, - "plugin.RenderConfig": { + "schema.AIPromptConfig": { "type": "object", "properties": { - "select_theme": { + "en_us": { + "type": "string" + }, + "zh_cn": { "type": "string" } } @@ -8075,6 +8905,34 @@ } } }, + "schema.AddAPIKeyReq": { + "type": "object", + "required": [ + "description", + "scope" + ], + "properties": { + "description": { + "type": "string", + "maxLength": 150 + }, + "scope": { + "type": "string", + "enum": [ + "read-only", + "global" + ] + } + } + }, + "schema.AddAPIKeyResp": { + "type": "object", + "properties": { + "access_key": { + "type": "string" + } + } + }, "schema.AddCommentReq": { "type": "object", "required": [ @@ -8555,6 +9413,14 @@ } } }, + "schema.DeleteAPIKeyReq": { + "type": "object", + "properties": { + "id": { + "type": "integer" + } + } + }, "schema.DeletePermanentlyReq": { "type": "object", "required": [ @@ -8671,6 +9537,60 @@ } } }, + "schema.GetAIModelResp": { + "type": "object", + "properties": { + "created": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "object": { + "type": "string" + }, + "owned_by": { + "type": "string" + } + } + }, + "schema.GetAIProviderResp": { + "type": "object", + "properties": { + "default_api_host": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "schema.GetAPIKeyResp": { + "type": "object", + "properties": { + "access_key": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "last_used_at": { + "type": "integer" + }, + "scope": { + "type": "string" + } + } + }, "schema.GetAnswerInfoResp": { "type": "object", "properties": { @@ -10754,6 +11674,69 @@ } } }, + "schema.SiteAIProvider": { + "type": "object", + "properties": { + "api_host": { + "type": "string", + "maxLength": 512 + }, + "api_key": { + "type": "string", + "maxLength": 256 + }, + "model": { + "type": "string", + "maxLength": 100 + }, + "provider": { + "type": "string", + "maxLength": 50 + } + } + }, + "schema.SiteAIReq": { + "type": "object", + "properties": { + "ai_providers": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteAIProvider" + } + }, + "chosen_provider": { + "type": "string", + "maxLength": 50 + }, + "enabled": { + "type": "boolean" + }, + "prompt_config": { + "$ref": "#/definitions/schema.AIPromptConfig" + } + } + }, + "schema.SiteAIResp": { + "type": "object", + "properties": { + "ai_providers": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteAIProvider" + } + }, + "chosen_provider": { + "type": "string", + "maxLength": 50 + }, + "enabled": { + "type": "boolean" + }, + "prompt_config": { + "$ref": "#/definitions/schema.AIPromptConfig" + } + } + }, "schema.SiteAdvancedReq": { "type": "object", "properties": { @@ -10961,6 +11944,9 @@ "schema.SiteInfoResp": { "type": "object", "properties": { + "ai_enabled": { + "type": "boolean" + }, "branding": { "$ref": "#/definitions/schema.SiteBrandingResp" }, @@ -10976,6 +11962,9 @@ "login": { "$ref": "#/definitions/schema.SiteLoginResp" }, + "mcp_enabled": { + "type": "boolean" + }, "revision": { "type": "string" }, @@ -11100,6 +12089,31 @@ } } }, + "schema.SiteMCPReq": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "schema.SiteMCPResp": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "http_header": { + "type": "string" + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, "schema.SitePoliciesReq": { "type": "object", "properties": { @@ -11604,6 +12618,22 @@ } } }, + "schema.UpdateAPIKeyReq": { + "type": "object", + "required": [ + "description", + "id" + ], + "properties": { + "description": { + "type": "string", + "maxLength": 150 + }, + "id": { + "type": "integer" + } + } + }, "schema.UpdateBadgeStatusReq": { "type": "object", "required": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 426f5332a..7a7adb681 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -157,6 +157,117 @@ definitions: select_theme: type: string type: object + schema.AIConversationAdminDeleteReq: + properties: + conversation_id: + type: string + required: + - conversation_id + type: object + schema.AIConversationAdminDetailResp: + properties: + conversation_id: + type: string + created_at: + type: integer + records: + items: + $ref: '#/definitions/schema.AIConversationRecord' + type: array + topic: + type: string + user_info: + $ref: '#/definitions/schema.AIConversationUserInfo' + type: object + schema.AIConversationAdminListItem: + properties: + created_at: + type: integer + helpful_count: + type: integer + id: + type: string + topic: + type: string + unhelpful_count: + type: integer + user_info: + $ref: '#/definitions/schema.AIConversationUserInfo' + type: object + schema.AIConversationDetailResp: + properties: + conversation_id: + type: string + created_at: + type: integer + records: + items: + $ref: '#/definitions/schema.AIConversationRecord' + type: array + topic: + type: string + updated_at: + type: integer + type: object + schema.AIConversationListItem: + properties: + conversation_id: + type: string + created_at: + type: integer + topic: + type: string + type: object + schema.AIConversationRecord: + properties: + chat_completion_id: + type: string + content: + type: string + created_at: + type: integer + helpful: + type: integer + role: + type: string + unhelpful: + type: integer + type: object + schema.AIConversationUserInfo: + properties: + avatar: + type: string + display_name: + type: string + id: + type: string + rank: + type: integer + username: + type: string + type: object + schema.AIConversationVoteReq: + properties: + cancel: + type: boolean + chat_completion_id: + type: string + vote_type: + enum: + - helpful + - unhelpful + type: string + required: + - chat_completion_id + - vote_type + type: object + schema.AIPromptConfig: + properties: + en_us: + type: string + zh_cn: + type: string + type: object schema.AcceptAnswerReq: properties: answer_id: @@ -216,6 +327,25 @@ definitions: verify: type: boolean type: object + schema.AddAPIKeyReq: + properties: + description: + maxLength: 150 + type: string + scope: + enum: + - read-only + - global + type: string + required: + - description + - scope + type: object + schema.AddAPIKeyResp: + properties: + access_key: + type: string + type: object schema.AddCommentReq: properties: captcha_code: @@ -546,6 +676,11 @@ definitions: name: type: string type: object + schema.DeleteAPIKeyReq: + properties: + id: + type: integer + type: object schema.DeletePermanentlyReq: properties: type: @@ -629,6 +764,41 @@ definitions: description: if user is followed object will be true,otherwise false type: boolean type: object + schema.GetAIModelResp: + properties: + created: + type: integer + id: + type: string + object: + type: string + owned_by: + type: string + type: object + schema.GetAIProviderResp: + properties: + default_api_host: + type: string + display_name: + type: string + name: + type: string + type: object + schema.GetAPIKeyResp: + properties: + access_key: + type: string + created_at: + type: integer + description: + type: string + id: + type: integer + last_used_at: + type: integer + scope: + type: string + type: object schema.GetAnswerInfoResp: properties: info: @@ -2072,6 +2242,49 @@ definitions: required: - user_id type: object + schema.SiteAIProvider: + properties: + api_host: + maxLength: 512 + type: string + api_key: + maxLength: 256 + type: string + model: + maxLength: 100 + type: string + provider: + maxLength: 50 + type: string + type: object + schema.SiteAIReq: + properties: + ai_providers: + items: + $ref: '#/definitions/schema.SiteAIProvider' + type: array + chosen_provider: + maxLength: 50 + type: string + enabled: + type: boolean + prompt_config: + $ref: '#/definitions/schema.AIPromptConfig' + type: object + schema.SiteAIResp: + properties: + ai_providers: + items: + $ref: '#/definitions/schema.SiteAIProvider' + type: array + chosen_provider: + maxLength: 50 + type: string + enabled: + type: boolean + prompt_config: + $ref: '#/definitions/schema.AIPromptConfig' + type: object schema.SiteAdvancedReq: properties: authorized_attachment_extensions: @@ -2218,6 +2431,8 @@ definitions: type: object schema.SiteInfoResp: properties: + ai_enabled: + type: boolean branding: $ref: '#/definitions/schema.SiteBrandingResp' custom_css_html: @@ -2228,6 +2443,8 @@ definitions: $ref: '#/definitions/schema.SiteInterfaceSettingsResp' login: $ref: '#/definitions/schema.SiteLoginResp' + mcp_enabled: + type: boolean revision: type: string site_advanced: @@ -2311,6 +2528,22 @@ definitions: allow_password_login: type: boolean type: object + schema.SiteMCPReq: + properties: + enabled: + type: boolean + type: object + schema.SiteMCPResp: + properties: + enabled: + type: boolean + http_header: + type: string + type: + type: string + url: + type: string + type: object schema.SitePoliciesReq: properties: privacy_policy_original_text: @@ -2653,6 +2886,17 @@ definitions: url_title: type: string type: object + schema.UpdateAPIKeyReq: + properties: + description: + maxLength: 150 + type: string + id: + type: integer + required: + - description + - id + type: object schema.UpdateBadgeStatusReq: properties: id: @@ -3241,6 +3485,174 @@ paths: summary: if config file not exist try to redirect to install page tags: - installation + /answer/admin/api/ai-config: + get: + description: get AI configuration + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteAIResp' + type: object + security: + - ApiKeyAuth: [] + summary: get AI configuration + tags: + - admin + put: + description: update AI configuration + parameters: + - description: AI config + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteAIReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update AI configuration + tags: + - admin + /answer/admin/api/ai-models: + post: + description: get AI models + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + items: + $ref: '#/definitions/schema.GetAIModelResp' + type: array + type: object + security: + - ApiKeyAuth: [] + summary: get AI models + tags: + - admin + /answer/admin/api/ai-provider: + get: + description: get AI provider configuration + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + items: + $ref: '#/definitions/schema.GetAIProviderResp' + type: array + type: object + security: + - ApiKeyAuth: [] + summary: get AI provider configuration + tags: + - admin + /answer/admin/api/ai/conversation: + delete: + consumes: + - application/json + description: delete conversation and its related records for admin + parameters: + - description: apikey + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.AIConversationAdminDeleteReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + summary: delete conversation for admin + tags: + - ai-conversation-admin + get: + consumes: + - application/json + description: get conversation detail for admin + parameters: + - description: conversation id + in: query + name: conversation_id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.AIConversationAdminDetailResp' + type: object + summary: get conversation detail for admin + tags: + - ai-conversation-admin + /answer/admin/api/ai/conversation/page: + get: + consumes: + - application/json + description: get conversation list for admin + parameters: + - description: page + in: query + name: page + type: integer + - description: page size + in: query + name: page_size + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + allOf: + - $ref: '#/definitions/pager.PageModel' + - properties: + list: + items: + $ref: '#/definitions/schema.AIConversationAdminListItem' + type: array + type: object + type: object + summary: get conversation list for admin + tags: + - ai-conversation-admin /answer/admin/api/answer/page: get: consumes: @@ -3307,6 +3719,97 @@ paths: summary: update answer status tags: - admin + /answer/admin/api/api-key: + delete: + description: delete apikey + parameters: + - description: apikey + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.DeleteAPIKeyReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: delete apikey + tags: + - admin + post: + description: add apikey + parameters: + - description: apikey + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.AddAPIKeyReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.AddAPIKeyResp' + type: object + security: + - ApiKeyAuth: [] + summary: add apikey + tags: + - admin + put: + description: update apikey + parameters: + - description: apikey + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.UpdateAPIKeyReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update apikey + tags: + - admin + /answer/admin/api/api-key/all: + get: + description: get all api keys + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + items: + $ref: '#/definitions/schema.GetAPIKeyResp' + type: array + type: object + security: + - ApiKeyAuth: [] + summary: get all api keys + tags: + - admin /answer/admin/api/badge/status: put: consumes: @@ -3432,6 +3935,47 @@ paths: summary: Get language options tags: - Lang + /answer/admin/api/mcp-config: + get: + description: get MCP configuration + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteMCPResp' + type: object + security: + - ApiKeyAuth: [] + summary: get MCP configuration + tags: + - admin + put: + description: update MCP configuration + parameters: + - description: MCP config + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteMCPReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update MCP configuration + tags: + - admin /answer/admin/api/plugin/config: get: description: get plugin config @@ -4639,6 +5183,90 @@ paths: summary: get object timeline detail tags: - Comment + /answer/api/v1/ai/conversation: + get: + consumes: + - application/json + description: get conversation detail + parameters: + - description: conversation id + in: query + name: conversation_id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.AIConversationDetailResp' + type: object + summary: get conversation detail + tags: + - ai-conversation + /answer/api/v1/ai/conversation/page: + get: + consumes: + - application/json + description: get conversation list + parameters: + - description: page + in: query + name: page + type: integer + - description: page size + in: query + name: page_size + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + allOf: + - $ref: '#/definitions/pager.PageModel' + - properties: + list: + items: + $ref: '#/definitions/schema.AIConversationListItem' + type: array + type: object + type: object + summary: get conversation list + tags: + - ai-conversation + /answer/api/v1/ai/conversation/vote: + post: + consumes: + - application/json + description: vote record + parameters: + - description: vote request + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.AIConversationVoteReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + summary: vote record + tags: + - ai-conversation /answer/api/v1/answer: delete: consumes: diff --git a/go.mod b/go.mod index d24302954..5c48abfdb 100644 --- a/go.mod +++ b/go.mod @@ -30,6 +30,7 @@ require ( github.com/go-playground/locales v0.14.1 github.com/go-playground/universal-translator v0.18.1 github.com/go-playground/validator/v10 v10.22.1 + github.com/go-resty/resty/v2 v2.17.1 github.com/go-sql-driver/mysql v1.8.1 github.com/goccy/go-json v0.10.3 github.com/google/uuid v1.6.0 @@ -39,10 +40,12 @@ require ( github.com/jinzhu/now v1.1.5 github.com/joho/godotenv v1.5.1 github.com/lib/pq v1.10.9 + github.com/mark3labs/mcp-go v0.43.2 github.com/microcosm-cc/bluemonday v1.0.27 github.com/mozillazg/go-pinyin v0.20.0 github.com/ory/dockertest/v3 v3.11.0 github.com/robfig/cron/v3 v3.0.1 + github.com/sashabaranov/go-openai v1.41.2 github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405 github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822083413-c0075a2d401f @@ -80,6 +83,8 @@ require ( github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/andybalholm/brotli v1.1.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/buger/jsonparser v1.1.1 // indirect github.com/bytedance/sonic v1.12.2 // indirect github.com/bytedance/sonic/loader v0.2.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect @@ -118,6 +123,7 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/invopop/jsonschema v0.13.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect @@ -146,7 +152,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.7.0 // indirect + github.com/spf13/cast v1.7.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.19.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect @@ -155,9 +161,11 @@ require ( github.com/tidwall/pretty v1.2.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect + github.com/yosida95/uritemplate/v3 v3.0.2 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/arch v0.10.0 // indirect diff --git a/internal/base/constant/site_type.go b/internal/base/constant/site_type.go index 64ea9c4ae..20917f12a 100644 --- a/internal/base/constant/site_type.go +++ b/internal/base/constant/site_type.go @@ -42,8 +42,8 @@ const ( SiteTypeUsersSettings = "users_settings" SiteTypeInterfaceSettings = "interface_settings" - SiteTypePolicies = "policies" - SiteTypeSecurity = "security" + SiteTypePolicies = "policies" + SiteTypeSecurity = "security" SiteTypeAI = "ai" SiteTypeFeatureToggle = "feature-toggle" SiteTypeMCP = "mcp" diff --git a/internal/migrations/v32.go b/internal/migrations/v31.go similarity index 100% rename from internal/migrations/v32.go rename to internal/migrations/v31.go diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index 3338e80ab..a72a8460e 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -381,8 +381,8 @@ type SiteInfoResp struct { Security *SiteSecurityResp `json:"site_security"` Version string `json:"version"` Revision string `json:"revision"` - AIEnabled bool `json:"ai_enabled"` - MCPEnabled bool `json:"mcp_enabled"` + AIEnabled bool `json:"ai_enabled"` + MCPEnabled bool `json:"mcp_enabled"` } type TemplateSiteInfoResp struct { diff --git a/internal/service/mock/siteinfo_repo_mock.go b/internal/service/mock/siteinfo_repo_mock.go index 16f7abd8a..ad3a170a7 100644 --- a/internal/service/mock/siteinfo_repo_mock.go +++ b/internal/service/mock/siteinfo_repo_mock.go @@ -41,6 +41,7 @@ import ( type MockSiteInfoRepo struct { ctrl *gomock.Controller recorder *MockSiteInfoRepoMockRecorder + isgomock struct{} } // MockSiteInfoRepoMockRecorder is the mock recorder for MockSiteInfoRepo. @@ -75,7 +76,7 @@ func (m *MockSiteInfoRepo) GetByType(ctx context.Context, siteType string, witho } // GetByType indicates an expected call of GetByType. -func (mr *MockSiteInfoRepoMockRecorder) GetByType(ctx, siteType interface{}) *gomock.Call { +func (mr *MockSiteInfoRepoMockRecorder) GetByType(ctx, siteType any, withoutCache ...any) *gomock.Call { mr.mock.ctrl.T.Helper() varargs := append([]any{ctx, siteType}, withoutCache...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByType", reflect.TypeOf((*MockSiteInfoRepo)(nil).GetByType), varargs...) @@ -91,7 +92,7 @@ func (m *MockSiteInfoRepo) IsBrandingFileUsed(ctx context.Context, filePath stri } // IsBrandingFileUsed indicates an expected call of IsBrandingFileUsed. -func (mr *MockSiteInfoRepoMockRecorder) IsBrandingFileUsed(ctx, filePath interface{}) *gomock.Call { +func (mr *MockSiteInfoRepoMockRecorder) IsBrandingFileUsed(ctx, filePath any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsBrandingFileUsed", reflect.TypeOf((*MockSiteInfoRepo)(nil).IsBrandingFileUsed), ctx, filePath) } @@ -105,7 +106,7 @@ func (m *MockSiteInfoRepo) SaveByType(ctx context.Context, siteType string, data } // SaveByType indicates an expected call of SaveByType. -func (mr *MockSiteInfoRepoMockRecorder) SaveByType(ctx, siteType, data interface{}) *gomock.Call { +func (mr *MockSiteInfoRepoMockRecorder) SaveByType(ctx, siteType, data any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveByType", reflect.TypeOf((*MockSiteInfoRepo)(nil).SaveByType), ctx, siteType, data) } @@ -114,6 +115,7 @@ func (mr *MockSiteInfoRepoMockRecorder) SaveByType(ctx, siteType, data interface type MockSiteInfoCommonService struct { ctrl *gomock.Controller recorder *MockSiteInfoCommonServiceMockRecorder + isgomock struct{} } // MockSiteInfoCommonServiceMockRecorder is the mock recorder for MockSiteInfoCommonService. @@ -142,7 +144,7 @@ func (m *MockSiteInfoCommonService) FormatAvatar(ctx context.Context, originalAv } // FormatAvatar indicates an expected call of FormatAvatar. -func (mr *MockSiteInfoCommonServiceMockRecorder) FormatAvatar(ctx, originalAvatarData, email, userStatus interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) FormatAvatar(ctx, originalAvatarData, email, userStatus any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FormatAvatar", reflect.TypeOf((*MockSiteInfoCommonService)(nil).FormatAvatar), ctx, originalAvatarData, email, userStatus) } @@ -156,11 +158,26 @@ func (m *MockSiteInfoCommonService) FormatListAvatar(ctx context.Context, userLi } // FormatListAvatar indicates an expected call of FormatListAvatar. -func (mr *MockSiteInfoCommonServiceMockRecorder) FormatListAvatar(ctx, userList interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) FormatListAvatar(ctx, userList any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FormatListAvatar", reflect.TypeOf((*MockSiteInfoCommonService)(nil).FormatListAvatar), ctx, userList) } +// GetSiteAI mocks base method. +func (m *MockSiteInfoCommonService) GetSiteAI(ctx context.Context) (*schema.SiteAIResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteAI", ctx) + ret0, _ := ret[0].(*schema.SiteAIResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteAI indicates an expected call of GetSiteAI. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteAI(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteAI", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteAI), ctx) +} + // GetSiteAdvanced mocks base method. func (m *MockSiteInfoCommonService) GetSiteAdvanced(ctx context.Context) (*schema.SiteAdvancedResp, error) { m.ctrl.T.Helper() @@ -171,7 +188,7 @@ func (m *MockSiteInfoCommonService) GetSiteAdvanced(ctx context.Context) (*schem } // GetSiteAdvanced indicates an expected call of GetSiteAdvanced. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteAdvanced(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteAdvanced(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteAdvanced", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteAdvanced), ctx) } @@ -186,7 +203,7 @@ func (m *MockSiteInfoCommonService) GetSiteBranding(ctx context.Context) (*schem } // GetSiteBranding indicates an expected call of GetSiteBranding. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteBranding(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteBranding(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteBranding", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteBranding), ctx) } @@ -201,7 +218,7 @@ func (m *MockSiteInfoCommonService) GetSiteCustomCssHTML(ctx context.Context) (* } // GetSiteCustomCssHTML indicates an expected call of GetSiteCustomCssHTML. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteCustomCssHTML(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteCustomCssHTML(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteCustomCssHTML", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteCustomCssHTML), ctx) } @@ -216,7 +233,7 @@ func (m *MockSiteInfoCommonService) GetSiteGeneral(ctx context.Context) (*schema } // GetSiteGeneral indicates an expected call of GetSiteGeneral. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteGeneral(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteGeneral(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteGeneral", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteGeneral), ctx) } @@ -230,7 +247,7 @@ func (m *MockSiteInfoCommonService) GetSiteInfoByType(ctx context.Context, siteT } // GetSiteInfoByType indicates an expected call of GetSiteInfoByType. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInfoByType(ctx, siteType, resp interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInfoByType(ctx, siteType, resp any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteInfoByType", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteInfoByType), ctx, siteType, resp) } @@ -245,7 +262,7 @@ func (m *MockSiteInfoCommonService) GetSiteInterface(ctx context.Context) (*sche } // GetSiteInterface indicates an expected call of GetSiteInterface. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInterface(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteInterface(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteInterface", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteInterface), ctx) } @@ -260,11 +277,26 @@ func (m *MockSiteInfoCommonService) GetSiteLogin(ctx context.Context) (*schema.S } // GetSiteLogin indicates an expected call of GetSiteLogin. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLogin", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLogin), ctx) } +// GetSiteMCP mocks base method. +func (m *MockSiteInfoCommonService) GetSiteMCP(ctx context.Context) (*schema.SiteMCPResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSiteMCP", ctx) + ret0, _ := ret[0].(*schema.SiteMCPResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSiteMCP indicates an expected call of GetSiteMCP. +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteMCP(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteMCP", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteMCP), ctx) +} + // GetSitePolicies mocks base method. func (m *MockSiteInfoCommonService) GetSitePolicies(ctx context.Context) (*schema.SitePoliciesResp, error) { m.ctrl.T.Helper() @@ -275,7 +307,7 @@ func (m *MockSiteInfoCommonService) GetSitePolicies(ctx context.Context) (*schem } // GetSitePolicies indicates an expected call of GetSitePolicies. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSitePolicies(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSitePolicies(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSitePolicies", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSitePolicies), ctx) } @@ -290,7 +322,7 @@ func (m *MockSiteInfoCommonService) GetSiteQuestion(ctx context.Context) (*schem } // GetSiteQuestion indicates an expected call of GetSiteQuestion. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteQuestion(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteQuestion(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteQuestion", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteQuestion), ctx) } @@ -305,7 +337,7 @@ func (m *MockSiteInfoCommonService) GetSiteSecurity(ctx context.Context) (*schem } // GetSiteSecurity indicates an expected call of GetSiteSecurity. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteSecurity(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteSecurity(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteSecurity", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteSecurity), ctx) } @@ -320,7 +352,7 @@ func (m *MockSiteInfoCommonService) GetSiteSeo(ctx context.Context) (*schema.Sit } // GetSiteSeo indicates an expected call of GetSiteSeo. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteSeo(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteSeo(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteSeo", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteSeo), ctx) } @@ -335,7 +367,7 @@ func (m *MockSiteInfoCommonService) GetSiteTag(ctx context.Context) (*schema.Sit } // GetSiteTag indicates an expected call of GetSiteTag. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteTag(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteTag(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteTag", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteTag), ctx) } @@ -350,7 +382,7 @@ func (m *MockSiteInfoCommonService) GetSiteTheme(ctx context.Context) (*schema.S } // GetSiteTheme indicates an expected call of GetSiteTheme. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteTheme(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteTheme(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteTheme", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteTheme), ctx) } @@ -365,7 +397,7 @@ func (m *MockSiteInfoCommonService) GetSiteUsers(ctx context.Context) (*schema.S } // GetSiteUsers indicates an expected call of GetSiteUsers. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsers(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsers(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteUsers", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteUsers), ctx) } @@ -380,7 +412,7 @@ func (m *MockSiteInfoCommonService) GetSiteUsersSettings(ctx context.Context) (* } // GetSiteUsersSettings indicates an expected call of GetSiteUsersSettings. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsersSettings(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsersSettings(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteUsersSettings", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteUsersSettings), ctx) } @@ -395,7 +427,7 @@ func (m *MockSiteInfoCommonService) GetSiteWrite(ctx context.Context) (*schema.S } // GetSiteWrite indicates an expected call of GetSiteWrite. -func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteWrite(ctx interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteWrite(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteWrite", reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteWrite), ctx) } @@ -409,7 +441,7 @@ func (m *MockSiteInfoCommonService) IsBrandingFileUsed(ctx context.Context, file } // IsBrandingFileUsed indicates an expected call of IsBrandingFileUsed. -func (mr *MockSiteInfoCommonServiceMockRecorder) IsBrandingFileUsed(ctx, filePath interface{}) *gomock.Call { +func (mr *MockSiteInfoCommonServiceMockRecorder) IsBrandingFileUsed(ctx, filePath any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsBrandingFileUsed", reflect.TypeOf((*MockSiteInfoCommonService)(nil).IsBrandingFileUsed), ctx, filePath) } diff --git a/ui/src/components/TabNav/index.tsx b/ui/src/components/TabNav/index.tsx index 482cd0cf0..6b1b434df 100644 --- a/ui/src/components/TabNav/index.tsx +++ b/ui/src/components/TabNav/index.tsx @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + import { FC } from 'react'; import { Nav } from 'react-bootstrap'; import { NavLink, useLocation } from 'react-router-dom'; diff --git a/ui/src/pages/Admin/AiAssistant/components/Action/index.tsx b/ui/src/pages/Admin/AiAssistant/components/Action/index.tsx index c9702ea68..75b8661a3 100644 --- a/ui/src/pages/Admin/AiAssistant/components/Action/index.tsx +++ b/ui/src/pages/Admin/AiAssistant/components/Action/index.tsx @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ + import { Dropdown } from 'react-bootstrap'; import { useTranslation } from 'react-i18next'; diff --git a/ui/src/pages/AiAssistant/components/ConversationList/index.tsx b/ui/src/pages/AiAssistant/components/ConversationList/index.tsx index 4dbc61297..1ddb96259 100644 --- a/ui/src/pages/AiAssistant/components/ConversationList/index.tsx +++ b/ui/src/pages/AiAssistant/components/ConversationList/index.tsx @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ + import { FC, memo } from 'react'; import { Card, ListGroup } from 'react-bootstrap'; import { Link } from 'react-router-dom'; diff --git a/ui/src/pages/Search/components/AiCard/index.tsx b/ui/src/pages/Search/components/AiCard/index.tsx index 9e7d8f944..2da5cb919 100644 --- a/ui/src/pages/Search/components/AiCard/index.tsx +++ b/ui/src/pages/Search/components/AiCard/index.tsx @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + import { useState, useEffect } from 'react'; import { Card, Spinner } from 'react-bootstrap'; import { useSearchParams, Link } from 'react-router-dom'; diff --git a/ui/src/utils/requestAi.ts b/ui/src/utils/requestAi.ts index 444bbe6dc..df2d1ee7a 100644 --- a/ui/src/utils/requestAi.ts +++ b/ui/src/utils/requestAi.ts @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + import { Modal } from '@/components'; import { loggedUserInfoStore, toastStore, errorCodeStore } from '@/stores'; import { LOGGED_TOKEN_STORAGE_KEY } from '@/common/constants'; From cc1567ac4ba4a13b972e9c0b7f28e8320c3bd7ca Mon Sep 17 00:00:00 2001 From: shuai Date: Mon, 26 Jan 2026 14:25:25 +0800 Subject: [PATCH 85/92] fix: Fix incorrect default value when the input type is number in SchemeForm. --- ui/src/components/SchemaForm/components/Input.tsx | 6 +++++- ui/src/pages/Admin/QaSettings/index.tsx | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/src/components/SchemaForm/components/Input.tsx b/ui/src/components/SchemaForm/components/Input.tsx index a1838151b..2f062b616 100644 --- a/ui/src/components/SchemaForm/components/Input.tsx +++ b/ui/src/components/SchemaForm/components/Input.tsx @@ -73,12 +73,16 @@ const Index: FC = ({ } }; + // For number type, use ?? to preserve 0 value; for other types, use || for backward compatibility + const inputValue = + type === 'number' ? (fieldObject?.value ?? '') : fieldObject?.value || ''; + return ( { type: 'number', title: t('min_tags.label'), description: t('min_tags.text'), + default: 0, }, min_content: { type: 'number', @@ -124,6 +125,7 @@ const QaSettings = () => { formMeta.min_tags.value = res.min_tags; formMeta.min_content.value = res.min_content; formMeta.restrict_answer.value = res.restrict_answer; + console.log('res', res, formMeta); setFormData(formMeta); } }); From ef54781b77bf7010dae6f4dd3a56520919b1e43a Mon Sep 17 00:00:00 2001 From: shuai Date: Mon, 26 Jan 2026 14:29:20 +0800 Subject: [PATCH 86/92] fix: mcp menu moved to ai assistant --- ui/src/common/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/common/constants.ts b/ui/src/common/constants.ts index 2e10f1494..862072817 100644 --- a/ui/src/common/constants.ts +++ b/ui/src/common/constants.ts @@ -108,6 +108,7 @@ export const ADMIN_NAV_MENUS = [ children: [ { name: 'ai_settings', path: 'ai-settings' }, { name: 'ai_assistant', path: 'ai-assistant' }, + { name: 'mcp' }, ], }, { @@ -144,7 +145,6 @@ export const ADMIN_NAV_MENUS = [ { name: 'seo' }, { name: 'smtp' }, { name: 'apikeys' }, - { name: 'mcp' }, ], }, { From b83d0214c70126bbb6c97db38e9c239480eb2df7 Mon Sep 17 00:00:00 2001 From: ferhat elmas Date: Fri, 23 Jan 2026 21:43:40 +0100 Subject: [PATCH 87/92] feat(ci): add lint action related to #1432 Signed-off-by: ferhat elmas --- .github/workflows/lint.yml | 62 ++++++++++++++++++++++++++++ cmd/wire_gen.go | 48 ++++++++++----------- go.mod | 2 +- internal/base/translator/provider.go | 4 +- script/check-asf-header.sh | 2 +- 5 files changed, 90 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/lint.yml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 000000000..53463b39b --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,62 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +name: Lint + +on: + push: + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.number || github.run_id }} + cancel-in-progress: true + +jobs: + lint: + name: Lint (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 15 + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.23" + cache: true + + - name: Run go mod tidy + run: go mod tidy + + - name: Run golangci-lint + run: make lint + + - name: Check for uncommitted changes + shell: bash + run: | + if [ -n "$(git status --porcelain)" ]; then + echo "::error::Uncommitted changes detected" + git status + git diff + exit 1 + fi diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index 22a70f29d..5b9990213 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -172,29 +172,29 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, tagRepo := tag.NewTagRepo(dataData, uniqueIDRepo) revisionRepo := revision.NewRevisionRepo(dataData, uniqueIDRepo) revisionService := revision_common.NewRevisionService(revisionRepo, userRepo) - v := activityqueue.NewService() - tagCommonService := tag_common2.NewTagCommonService(tagCommonRepo, tagRelRepo, tagRepo, revisionService, siteInfoCommonService, v) + service := activityqueue.NewService() + tagCommonService := tag_common2.NewTagCommonService(tagCommonRepo, tagRelRepo, tagRepo, revisionService, siteInfoCommonService, service) collectionRepo := collection.NewCollectionRepo(dataData, uniqueIDRepo) collectionCommon := collectioncommon.NewCollectionCommon(collectionRepo) answerCommon := answercommon.NewAnswerCommon(answerRepo) metaRepo := meta.NewMetaRepo(dataData) metaCommonService := metacommon.NewMetaCommonService(metaRepo) - questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaCommonService, configService, v, revisionRepo, siteInfoCommonService, dataData) - v2 := eventqueue.NewService() + questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaCommonService, configService, service, revisionRepo, siteInfoCommonService, dataData) + eventqueueService := eventqueue.NewService() fileRecordRepo := file_record.NewFileRecordRepo(dataData) fileRecordService := file_record2.NewFileRecordService(fileRecordRepo, revisionRepo, serviceConf, siteInfoCommonService, userCommon) - userService := content.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo, userNotificationConfigService, questionCommon, v2, fileRecordService) + userService := content.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo, userNotificationConfigService, questionCommon, eventqueueService, fileRecordService) captchaRepo := captcha.NewCaptchaRepo(dataData) captchaService := action.NewCaptchaService(captchaRepo) userController := controller.NewUserController(authService, userService, captchaService, emailService, siteInfoCommonService, userNotificationConfigService) commentRepo := comment.NewCommentRepo(dataData, uniqueIDRepo) commentCommonRepo := comment.NewCommentCommonRepo(dataData, uniqueIDRepo) objService := object_info.NewObjService(answerRepo, questionRepo, commentCommonRepo, tagCommonRepo, tagCommonService) - v3 := noticequeue.NewService() - v4 := noticequeue.NewExternalService() + noticequeueService := noticequeue.NewService() + externalService := noticequeue.NewExternalService() reviewRepo := review.NewReviewRepo(dataData) - reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, v4, tagCommonService, questionCommon, v3, siteInfoCommonService, commentCommonRepo) - commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, v3, v4, v, v2, reviewService) + reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, externalService, tagCommonService, questionCommon, noticequeueService, siteInfoCommonService, commentCommonRepo) + commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, noticequeueService, externalService, service, eventqueueService, reviewService) rolePowerRelRepo := role.NewRolePowerRelRepo(dataData) rolePowerRelService := role2.NewRolePowerRelService(rolePowerRelRepo, userRoleRelService) rankService := rank2.NewRankService(userCommon, userRankRepo, objService, userRoleRelService, rolePowerRelService, configService) @@ -202,17 +202,17 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, rateLimitMiddleware := middleware.NewRateLimitMiddleware(limitRepo) commentController := controller.NewCommentController(commentService, rankService, captchaService, rateLimitMiddleware) reportRepo := report.NewReportRepo(dataData, uniqueIDRepo) - tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, v) - answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, v3) + tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, service) + answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, noticequeueService) answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, configService) - externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, v4, userExternalLoginRepo, siteInfoCommonService) - questionService := content.NewQuestionService(activityRepo, questionRepo, answerRepo, tagCommonService, tagService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, v3, v4, v, siteInfoCommonService, externalNotificationService, reviewService, configService, v2, reviewRepo) - answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, v3, v4, v, reviewService, v2) + externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, externalService, userExternalLoginRepo, siteInfoCommonService) + questionService := content.NewQuestionService(activityRepo, questionRepo, answerRepo, tagCommonService, tagService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, noticequeueService, externalService, service, siteInfoCommonService, externalNotificationService, reviewService, configService, eventqueueService, reviewRepo) + answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, noticequeueService, externalService, service, reviewService, eventqueueService) reportHandle := report_handle.NewReportHandle(questionService, answerService, commentService) - reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, v2) + reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, eventqueueService) reportController := controller.NewReportController(reportService, rankService, captchaService) - contentVoteRepo := activity.NewVoteRepo(dataData, activityRepo, userRankRepo, v3) - voteService := content.NewVoteService(contentVoteRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService, v2) + contentVoteRepo := activity.NewVoteRepo(dataData, activityRepo, userRankRepo, noticequeueService) + voteService := content.NewVoteService(contentVoteRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService, eventqueueService) voteController := controller.NewVoteController(voteService, rankService, captchaService) tagController := controller.NewTagController(tagService, tagCommonService, rankService) followFollowRepo := activity.NewFollowRepo(dataData, uniqueIDRepo, activityRepo) @@ -228,7 +228,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, searchService := content.NewSearchService(searchParser, searchRepo) searchController := controller.NewSearchController(searchService, captchaService) reviewActivityRepo := activity.NewReviewActivityRepo(dataData, activityRepo, userRankRepo, configService) - contentRevisionService := content.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService, v3, v, reportRepo, reviewService, reviewActivityRepo) + contentRevisionService := content.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService, noticequeueService, service, reportRepo, reviewService, reviewActivityRepo) revisionController := controller.NewRevisionController(contentRevisionService, rankService) rankController := controller.NewRankController(rankService) userAdminRepo := user.NewUserAdminRepo(dataData, authRepo) @@ -244,7 +244,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, siteInfoService := siteinfo.NewSiteInfoService(siteInfoRepo, siteInfoCommonService, emailService, tagCommonService, configService, questionCommon, fileRecordService) siteInfoController := controller_admin.NewSiteInfoController(siteInfoService) controllerSiteInfoController := controller.NewSiteInfoController(siteInfoCommonService) - notificationCommon := notificationcommon.NewNotificationCommon(dataData, notificationRepo, userCommon, activityRepo, followRepo, objService, v3, userExternalLoginRepo, siteInfoCommonService) + notificationCommon := notificationcommon.NewNotificationCommon(dataData, notificationRepo, userCommon, activityRepo, followRepo, objService, noticequeueService, userExternalLoginRepo, siteInfoCommonService) badgeRepo := badge.NewBadgeRepo(dataData, uniqueIDRepo) notificationService := notification.NewNotificationService(dataData, notificationRepo, notificationCommon, revisionService, userRepo, reportRepo, reviewService, badgeRepo) notificationController := controller.NewNotificationController(notificationService, rankService) @@ -253,7 +253,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, uploaderService := uploader.NewUploaderService(serviceConf, siteInfoCommonService, fileRecordService) uploadController := controller.NewUploadController(uploaderService) activityActivityRepo := activity.NewActivityRepo(dataData, configService) - activityCommon := activity_common2.NewActivityCommon(activityRepo, v) + activityCommon := activity_common2.NewActivityCommon(activityRepo, service) commentCommonService := comment_common.NewCommentCommonService(commentCommonRepo) activityService := activity2.NewActivityService(activityActivityRepo, userCommon, activityCommon, tagCommonService, objService, commentCommonService, revisionService, metaCommonService, configService) activityController := controller.NewActivityController(activityService) @@ -265,12 +265,12 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, permissionController := controller.NewPermissionController(rankService) userPluginController := controller.NewUserPluginController(pluginCommonService) reviewController := controller.NewReviewController(reviewService, rankService, captchaService) - metaService := meta2.NewMetaService(metaCommonService, userCommon, answerRepo, questionRepo, v2) + metaService := meta2.NewMetaService(metaCommonService, userCommon, answerRepo, questionRepo, eventqueueService) metaController := controller.NewMetaController(metaService) badgeGroupRepo := badge_group.NewBadgeGroupRepo(dataData, uniqueIDRepo) eventRuleRepo := badge.NewEventRuleRepo(dataData) - badgeAwardService := badge2.NewBadgeAwardService(badgeAwardRepo, badgeRepo, userCommon, objService, v3) - badgeEventService := badge2.NewBadgeEventService(dataData, v2, badgeRepo, eventRuleRepo, badgeAwardService) + badgeAwardService := badge2.NewBadgeAwardService(badgeAwardRepo, badgeRepo, userCommon, objService, noticequeueService) + badgeEventService := badge2.NewBadgeEventService(dataData, eventqueueService, badgeRepo, eventRuleRepo, badgeAwardService) badgeService := badge2.NewBadgeService(badgeRepo, badgeGroupRepo, badgeAwardRepo, badgeEventService, siteInfoCommonService) badgeController := controller.NewBadgeController(badgeService, badgeAwardService) controller_adminBadgeController := controller_admin.NewBadgeController(badgeService) @@ -281,7 +281,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, avatarMiddleware := middleware.NewAvatarMiddleware(serviceConf, uploaderService) shortIDMiddleware := middleware.NewShortIDMiddleware(siteInfoCommonService) templateRenderController := templaterender.NewTemplateRenderController(questionService, userService, tagService, answerService, commentService, siteInfoCommonService, questionRepo) - templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService, v2, userService, questionService) + templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService, eventqueueService, userService, questionService) templateRouter := router.NewTemplateRouter(templateController, templateRenderController, siteInfoController, authUserMiddleware) connectorController := controller.NewConnectorController(siteInfoCommonService, emailService, userExternalLoginService) userCenterLoginService := user_external_login2.NewUserCenterLoginService(userRepo, userCommon, userExternalLoginRepo, userActiveActivityRepo, siteInfoCommonService) diff --git a/go.mod b/go.mod index 52d64c738..d24302954 100644 --- a/go.mod +++ b/go.mod @@ -37,6 +37,7 @@ require ( github.com/grokify/html-strip-tags-go v0.1.0 github.com/jinzhu/copier v0.4.0 github.com/jinzhu/now v1.1.5 + github.com/joho/godotenv v1.5.1 github.com/lib/pq v1.10.9 github.com/microcosm-cc/bluemonday v1.0.27 github.com/mozillazg/go-pinyin v0.20.0 @@ -117,7 +118,6 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/joho/godotenv v1.5.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect diff --git a/internal/base/translator/provider.go b/internal/base/translator/provider.go index 1a465b1e8..982dbd038 100644 --- a/internal/base/translator/provider.go +++ b/internal/base/translator/provider.go @@ -242,7 +242,7 @@ func inspectTranslatorNode(node any, path []string, isRoot bool) error { return nil case []any: for idx, child := range data { - nextPath := append(path, fmt.Sprintf("[%d]", idx)) + nextPath := append(path, fmt.Sprintf("[%d]", idx)) //nolint: gocritic if err := inspectTranslatorNode(child, nextPath, false); err != nil { return err } @@ -250,7 +250,7 @@ func inspectTranslatorNode(node any, path []string, isRoot bool) error { return nil case []map[string]any: for idx, child := range data { - nextPath := append(path, fmt.Sprintf("[%d]", idx)) + nextPath := append(path, fmt.Sprintf("[%d]", idx)) //nolint: gocritic if err := inspectTranslatorNode(child, nextPath, false); err != nil { return err } diff --git a/script/check-asf-header.sh b/script/check-asf-header.sh index 808efa108..05e523140 100755 --- a/script/check-asf-header.sh +++ b/script/check-asf-header.sh @@ -26,6 +26,6 @@ else exit 1 fi -$CONTAINER_RUNTIME run -it --rm -v "$(pwd)":/github/workspace ghcr.io/korandoru/hawkeye-native format +$CONTAINER_RUNTIME run --rm -v "$(pwd)":/github/workspace ghcr.io/korandoru/hawkeye-native format gofmt -w -l . From 9ea13af8606976a447e6f3b416c325627ee4fa79 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Tue, 27 Jan 2026 17:38:47 +0800 Subject: [PATCH 88/92] feat(revision): enhance revision management with object status handling --- internal/controller/revision_controller.go | 2 ++ internal/router/answer_api_router.go | 4 +--- internal/schema/revision_schema.go | 2 ++ internal/schema/simple_obj_info_schema.go | 3 +++ internal/service/content/revision_service.go | 17 +++++++++++++++++ internal/service/object_info/object_info.go | 12 +++++++----- 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/internal/controller/revision_controller.go b/internal/controller/revision_controller.go index 13bee19c4..57574375a 100644 --- a/internal/controller/revision_controller.go +++ b/internal/controller/revision_controller.go @@ -69,6 +69,8 @@ func (rc *RevisionController) GetRevisionList(ctx *gin.Context) { objectID = uid.DeShortID(objectID) req := &schema.GetRevisionListReq{ ObjectID: objectID, + IsAdmin: middleware.GetUserIsAdminModerator(ctx), + UserID: middleware.GetLoginUserIDFromContext(ctx), } resp, err := rc.revisionListService.GetRevisionList(ctx, req) diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go index fc53ec455..c642b2a13 100644 --- a/internal/router/answer_api_router.go +++ b/internal/router/answer_api_router.go @@ -188,9 +188,6 @@ func (a *AnswerAPIRouter) RegisterUnAuthAnswerAPIRouter(r *gin.RouterGroup) { r.GET("/personal/comment/page", a.commentController.GetCommentPersonalWithPage) r.GET("/comment", a.commentController.GetComment) - // revision - r.GET("/revisions", a.revisionController.GetRevisionList) - // tag r.GET("/tags/page", a.tagController.GetTagWithPage) r.GET("/tags/following", a.tagController.GetFollowingTags) @@ -224,6 +221,7 @@ func (a *AnswerAPIRouter) RegisterAuthUserWithAnyStatusAnswerAPIRouter(r *gin.Ro func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) { // revisions + r.GET("/revisions", a.revisionController.GetRevisionList) r.GET("/revisions/unreviewed", a.revisionController.GetUnreviewedRevisionList) r.PUT("/revisions/audit", a.revisionController.RevisionAudit) r.GET("/revisions/edit/check", a.revisionController.CheckCanUpdateRevision) diff --git a/internal/schema/revision_schema.go b/internal/schema/revision_schema.go index 6f3246e51..dad067f4e 100644 --- a/internal/schema/revision_schema.go +++ b/internal/schema/revision_schema.go @@ -45,6 +45,8 @@ type AddRevisionDTO struct { type GetRevisionListReq struct { // object id ObjectID string `validate:"required" comment:"object_id" form:"object_id"` + IsAdmin bool `json:"-"` + UserID string `json:"-"` } const RevisionAuditApprove = "approve" diff --git a/internal/schema/simple_obj_info_schema.go b/internal/schema/simple_obj_info_schema.go index a9bcf3b19..21a03ae22 100644 --- a/internal/schema/simple_obj_info_schema.go +++ b/internal/schema/simple_obj_info_schema.go @@ -35,6 +35,7 @@ type SimpleObjectInfo struct { CommentID string `json:"comment_id"` CommentStatus int `json:"comment_status"` TagID string `json:"tag_id"` + TagStatus int `json:"tag_status"` ObjectType string `json:"object_type"` Title string `json:"title"` Content string `json:"content"` @@ -49,6 +50,8 @@ func (s *SimpleObjectInfo) IsDeleted() bool { return s.AnswerStatus == entity.AnswerStatusDeleted case constant.CommentObjectType: return s.CommentStatus == entity.CommentStatusDeleted + case constant.TagObjectType: + return s.TagStatus == entity.TagStatusDeleted } return false } diff --git a/internal/service/content/revision_service.go b/internal/service/content/revision_service.go index 13ec65b7d..66e6181f9 100644 --- a/internal/service/content/revision_service.go +++ b/internal/service/content/revision_service.go @@ -388,6 +388,23 @@ func (rs *RevisionService) GetRevisionList(ctx context.Context, req *schema.GetR ) resp = []schema.GetRevisionResp{} + objInfo, infoErr := rs.objectInfoService.GetInfo(ctx, req.ObjectID) + if infoErr != nil { + return nil, infoErr + } + if !req.IsAdmin && objInfo.IsDeleted() && objInfo.ObjectCreatorUserID != req.UserID { + switch objInfo.ObjectType { + case constant.QuestionObjectType: + return nil, errors.NotFound(reason.QuestionNotFound) + case constant.AnswerObjectType: + return nil, errors.NotFound(reason.AnswerNotFound) + case constant.TagObjectType: + return nil, errors.NotFound(reason.TagNotFound) + default: + return nil, errors.NotFound(reason.ObjectNotFound) + } + } + _ = copier.Copy(&rev, req) revs, err = rs.revisionRepo.GetRevisionList(ctx, &rev) diff --git a/internal/service/object_info/object_info.go b/internal/service/object_info/object_info.go index 5ef438ff3..6380b8809 100644 --- a/internal/service/object_info/object_info.go +++ b/internal/service/object_info/object_info.go @@ -277,11 +277,13 @@ func (os *ObjService) GetInfo(ctx context.Context, objectID string) (objInfo *sc break } objInfo = &schema.SimpleObjectInfo{ - ObjectID: tagInfo.ID, - TagID: tagInfo.ID, - ObjectType: objectType, - Title: tagInfo.SlugName, - Content: tagInfo.ParsedText, // todo trim + ObjectID: tagInfo.ID, + ObjectCreatorUserID: tagInfo.UserID, + TagID: tagInfo.ID, + TagStatus: tagInfo.Status, + ObjectType: objectType, + Title: tagInfo.SlugName, + Content: tagInfo.ParsedText, // todo trim } } if objInfo == nil { From 8b61cad0143bf2978e75a0e02c7ca1c0de3bc309 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Tue, 27 Jan 2026 17:49:29 +0800 Subject: [PATCH 89/92] fix(lint): resolve the lint issue --- internal/base/constant/site_type.go | 13 ++++++------- internal/controller/ai_controller.go | 8 ++++---- internal/migrations/v30.go | 4 ++-- internal/schema/siteinfo_schema.go | 9 +++------ internal/service/siteinfo/siteinfo_service.go | 1 - 5 files changed, 15 insertions(+), 20 deletions(-) diff --git a/internal/base/constant/site_type.go b/internal/base/constant/site_type.go index 20917f12a..ff015ae69 100644 --- a/internal/base/constant/site_type.go +++ b/internal/base/constant/site_type.go @@ -20,14 +20,13 @@ package constant const ( - SiteTypeGeneral = "general" - // Deprecated: split SiteTypeInterfaceSettings and SiteTypeUsersSettings for better clarity + // SiteTypeLegal\SiteTypeLegal\SiteTypeWrite The following items will no longer be used. + SiteTypeLegal = "legal" SiteTypeInterface = "interface" - SiteTypeBranding = "branding" - // Deprecated: use SiteTypeAdvanced, SiteTypeQuestions, and SiteTypeTags instead - SiteTypeWrite = "write" - // Deprecated: use SiteTypePolicies and SiteTypeSecurity instead - SiteTypeLegal = "legal" + SiteTypeWrite = "write" + + SiteTypeGeneral = "general" + SiteTypeBranding = "branding" SiteTypeSeo = "seo" SiteTypeLogin = "login" SiteTypeCustomCssHTML = "css-html" diff --git a/internal/controller/ai_controller.go b/internal/controller/ai_controller.go index 85db78a93..e020ed30e 100644 --- a/internal/controller/ai_controller.go +++ b/internal/controller/ai_controller.go @@ -613,7 +613,7 @@ func (c *AIController) executeToolCalls(ctx *gin.Context, _ http.ResponseWriter, for _, toolCall := range validToolCalls { if toolCall.Function.Name != "" { - var args map[string]interface{} + var args map[string]any if err := json.Unmarshal([]byte(toolCall.Function.Arguments), &args); err != nil { log.Errorf("Failed to parse tool arguments for %s: %v, arguments: %s", toolCall.Function.Name, err, toolCall.Function.Arguments) errorResult := fmt.Sprintf("Error parsing tool arguments: %v", err) @@ -677,14 +677,14 @@ func (c *AIController) getMCPTools() []openai.Tool { // convertMCPToolToOpenAI func (c *AIController) convertMCPToolToOpenAI(mcpTool mcp.Tool) openai.Tool { - properties := make(map[string]interface{}) + properties := make(map[string]any) required := make([]string, 0) maps.Copy(properties, mcpTool.InputSchema.Properties) required = append(required, mcpTool.InputSchema.Required...) - parameters := map[string]interface{}{ + parameters := map[string]any{ "type": "object", "properties": properties, } @@ -704,7 +704,7 @@ func (c *AIController) convertMCPToolToOpenAI(mcpTool mcp.Tool) openai.Tool { } // callMCPTool -func (c *AIController) callMCPTool(ctx context.Context, toolName string, arguments map[string]interface{}) (string, error) { +func (c *AIController) callMCPTool(ctx context.Context, toolName string, arguments map[string]any) (string, error) { request := mcp.CallToolRequest{ Request: mcp.Request{}, Params: struct { diff --git a/internal/migrations/v30.go b/internal/migrations/v30.go index aa2f48b36..a2dca77e9 100644 --- a/internal/migrations/v30.go +++ b/internal/migrations/v30.go @@ -369,7 +369,7 @@ func splitLegalMenu(ctx context.Context, x *xorm.Engine) error { // save login settings if existsLogin { - loginContent, err := json.Marshal(siteLogin) + loginContent, _ := json.Marshal(siteLogin) _, err = x.Context(ctx).ID(siteInfoLogin.ID).Update(&entity.SiteInfo{ Type: constant.SiteTypeLogin, Content: string(loginContent), @@ -382,7 +382,7 @@ func splitLegalMenu(ctx context.Context, x *xorm.Engine) error { // save general settings if existGeneral { - generalContent, err := json.Marshal(siteGeneral) + generalContent, _ := json.Marshal(siteGeneral) _, err = x.Context(ctx).ID(siteInfoGeneral.ID).Update(&entity.SiteInfo{ Type: constant.SiteTypeGeneral, Content: string(generalContent), diff --git a/internal/schema/siteinfo_schema.go b/internal/schema/siteinfo_schema.go index a72a8460e..bdf2308d3 100644 --- a/internal/schema/siteinfo_schema.go +++ b/internal/schema/siteinfo_schema.go @@ -89,8 +89,7 @@ type SiteBrandingReq struct { Favicon string `validate:"omitempty,gt=0,lte=512" form:"favicon" json:"favicon"` } -// SiteWriteReq site write request -// Deprecated: use SiteQuestionsReq, SiteAdvancedReq and SiteTagsReq instead +// SiteWriteReq site write request use SiteQuestionsReq, SiteAdvancedReq and SiteTagsReq instead type SiteWriteReq struct { MinimumContent int `validate:"omitempty,gte=0,lte=65535" json:"min_content"` RestrictAnswer bool `validate:"omitempty" json:"restrict_answer"` @@ -159,8 +158,7 @@ type SiteWriteTag struct { DisplayName string `json:"display_name"` } -// SiteLegalReq site branding request -// Deprecated: use SitePoliciesReq and SiteSecurityReq instead +// SiteLegalReq site branding request use SitePoliciesReq and SiteSecurityReq instead type SiteLegalReq struct { TermsOfServiceOriginalText string `json:"terms_of_service_original_text"` TermsOfServiceParsedText string `json:"terms_of_service_parsed_text"` @@ -351,8 +349,7 @@ type SiteQuestionsResp SiteQuestionsReq type SiteAdvancedResp SiteAdvancedReq type SiteTagsResp SiteTagsReq -// SiteLegalResp site write response -// Deprecated: use SitePoliciesResp and SiteSecurityResp instead +// SiteLegalResp site write response use SitePoliciesResp and SiteSecurityResp instead type SiteLegalResp SiteLegalReq // SiteLegalSimpleResp site write response diff --git a/internal/service/siteinfo/siteinfo_service.go b/internal/service/siteinfo/siteinfo_service.go index 6cdb8ae5a..1e25cbaa4 100644 --- a/internal/service/siteinfo/siteinfo_service.go +++ b/internal/service/siteinfo/siteinfo_service.go @@ -112,7 +112,6 @@ func (s *SiteInfoService) GetSiteUsers(ctx context.Context) (resp *schema.SiteUs // GetSiteTag get site info write func (s *SiteInfoService) GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error) { - resp = &schema.SiteTagsResp{} resp, err = s.siteInfoCommonService.GetSiteTag(ctx) if err != nil { log.Error(err) From a5edc4fc013fa30b2281d1b63539c4f9cc85d6e5 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Wed, 28 Jan 2026 11:15:40 +0800 Subject: [PATCH 90/92] feat: add advanced site settings and related API endpoints --- docs/docs.go | 1008 ++++++++++++++++++++++++------------ docs/swagger.json | 1008 ++++++++++++++++++++++++------------ docs/swagger.yaml | 510 ++++++++++++------ internal/migrations/v32.go | 116 ----- 4 files changed, 1702 insertions(+), 940 deletions(-) delete mode 100644 internal/migrations/v32.go diff --git a/docs/docs.go b/docs/docs.go index 9c984d26c..57a23d432 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1393,6 +1393,77 @@ const docTemplate = `{ } } }, + "/answer/admin/api/siteinfo/advanced": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site advanced setting", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site advanced setting", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteAdvancedResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site advanced info", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site advanced info", + "parameters": [ + { + "description": "advanced settings", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteAdvancedReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/branding": { "get": { "security": [ @@ -1633,7 +1704,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteInterfaceResp" + "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" } } } @@ -1677,21 +1748,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/legal": { + "/answer/admin/api/siteinfo/login": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "Set the legal information for the site", + "description": "get site info login config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "Set the legal information for the site", + "summary": "get site info login config", "responses": { "200": { "description": "OK", @@ -1704,7 +1775,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteLegalResp" + "$ref": "#/definitions/schema.SiteLoginResp" } } } @@ -1719,22 +1790,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site legal info", + "description": "update site login", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site legal info", + "summary": "update site login", "parameters": [ { - "description": "write info", + "description": "login info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteLegalReq" + "$ref": "#/definitions/schema.SiteLoginReq" } } ], @@ -1748,21 +1819,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/login": { + "/answer/admin/api/siteinfo/polices": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site info login config", + "description": "Get the policies information for the site", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site info login config", + "summary": "Get the policies information for the site", "responses": { "200": { "description": "OK", @@ -1775,7 +1846,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteLoginResp" + "$ref": "#/definitions/schema.SitePoliciesResp" } } } @@ -1790,22 +1861,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site login", + "description": "update site policies configuration", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site login", + "summary": "update site policies configuration", "parameters": [ { - "description": "login info", + "description": "write info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteLoginReq" + "$ref": "#/definitions/schema.SitePoliciesReq" } } ], @@ -1819,21 +1890,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/seo": { + "/answer/admin/api/siteinfo/question": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site seo information", + "description": "get site questions setting", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site seo information", + "summary": "get site questions setting", "responses": { "200": { "description": "OK", @@ -1846,7 +1917,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteSeoResp" + "$ref": "#/definitions/schema.SiteQuestionsResp" } } } @@ -1861,22 +1932,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site seo information", + "description": "update site question settings", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site seo information", + "summary": "update site question settings", "parameters": [ { - "description": "seo", + "description": "questions settings", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteSeoReq" + "$ref": "#/definitions/schema.SiteQuestionsReq" } } ], @@ -1890,21 +1961,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/theme": { + "/answer/admin/api/siteinfo/security": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site info theme config", + "description": "Get the security information for the site", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site info theme config", + "summary": "Get the security information for the site", "responses": { "200": { "description": "OK", @@ -1917,7 +1988,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteThemeResp" + "$ref": "#/definitions/schema.SiteSecurityResp" } } } @@ -1932,22 +2003,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site custom css html config", + "description": "update site security configuration", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site custom css html config", + "summary": "update site security configuration", "parameters": [ { - "description": "login info", + "description": "write info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteThemeReq" + "$ref": "#/definitions/schema.SiteSecurityReq" } } ], @@ -1961,21 +2032,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/users": { + "/answer/admin/api/siteinfo/seo": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site user config", + "description": "get site seo information", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site user config", + "summary": "get site seo information", "responses": { "200": { "description": "OK", @@ -1988,7 +2059,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteUsersResp" + "$ref": "#/definitions/schema.SiteSeoResp" } } } @@ -2003,22 +2074,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site info config about users", + "description": "update site seo information", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site info config about users", + "summary": "update site seo information", "parameters": [ { - "description": "users info", + "description": "seo", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteUsersReq" + "$ref": "#/definitions/schema.SiteSeoReq" } } ], @@ -2032,21 +2103,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/siteinfo/write": { + "/answer/admin/api/siteinfo/tag": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site interface", + "description": "get site tags setting", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site interface", + "summary": "get site tags setting", "responses": { "200": { "description": "OK", @@ -2059,7 +2130,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteWriteResp" + "$ref": "#/definitions/schema.SiteTagsResp" } } } @@ -2074,22 +2145,22 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "update site write info", + "description": "update site tag settings", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site write info", + "summary": "update site tag settings", "parameters": [ { - "description": "write info", + "description": "tags settings", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteWriteReq" + "$ref": "#/definitions/schema.SiteTagsReq" } } ], @@ -2103,57 +2174,64 @@ const docTemplate = `{ } } }, - "/answer/admin/api/theme/options": { + "/answer/admin/api/siteinfo/theme": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "Get theme options", + "description": "get site info theme config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "Get theme options", + "summary": "get site info theme config", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/handler.RespBody" + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteThemeResp" + } + } + } + ] } } } - } - }, - "/answer/admin/api/user": { - "post": { + }, + "put": { "security": [ { "ApiKeyAuth": [] } ], - "description": "add user", - "consumes": [ - "application/json" - ], + "description": "update site custom css html config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "add user", + "summary": "update site custom css html config", "parameters": [ { - "description": "user", + "description": "login info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.AddUserReq" + "$ref": "#/definitions/schema.SiteThemeReq" } } ], @@ -2167,30 +2245,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/user/activation": { + "/answer/admin/api/siteinfo/users": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get user activation", + "description": "get site user config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get user activation", - "parameters": [ - { - "type": "string", - "description": "user id", - "name": "user_id", - "in": "query", - "required": true - } - ], + "summary": "get site user config", "responses": { "200": { "description": "OK", @@ -2203,7 +2272,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.GetUserActivationResp" + "$ref": "#/definitions/schema.SiteUsersResp" } } } @@ -2211,34 +2280,29 @@ const docTemplate = `{ } } } - } - }, - "/answer/admin/api/user/password": { + }, "put": { "security": [ { "ApiKeyAuth": [] } ], - "description": "update user password", - "consumes": [ - "application/json" - ], + "description": "update site info config about users", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update user password", + "summary": "update site info config about users", "parameters": [ { - "description": "user", + "description": "users info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.UpdateUserPasswordReq" + "$ref": "#/definitions/schema.SiteUsersReq" } } ], @@ -2252,71 +2316,64 @@ const docTemplate = `{ } } }, - "/answer/admin/api/user/profile": { - "put": { + "/answer/admin/api/siteinfo/users-settings": { + "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "edit user profile", - "consumes": [ - "application/json" - ], + "description": "get site interface", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "edit user profile", - "parameters": [ - { - "description": "user", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/schema.EditUserProfileReq" - } - } - ], + "summary": "get site interface", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/handler.RespBody" + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteUsersSettingsResp" + } + } + } + ] } } } - } - }, - "/answer/admin/api/user/role": { + }, "put": { "security": [ { "ApiKeyAuth": [] } ], - "description": "update user role", - "consumes": [ - "application/json" - ], + "description": "update site info users settings", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update user role", + "summary": "update site info users settings", "parameters": [ { - "description": "user", + "description": "general", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.UpdateUserRoleReq" + "$ref": "#/definitions/schema.SiteUsersSettingsReq" } } ], @@ -2330,35 +2387,21 @@ const docTemplate = `{ } } }, - "/answer/admin/api/user/status": { - "put": { + "/answer/admin/api/theme/options": { + "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "update user", - "consumes": [ - "application/json" - ], + "description": "Get theme options", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update user", - "parameters": [ - { - "description": "user", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/schema.UpdateUserStatusReq" - } - } - ], + "summary": "Get theme options", "responses": { "200": { "description": "OK", @@ -2369,7 +2412,248 @@ const docTemplate = `{ } } }, - "/answer/admin/api/users": { + "/answer/admin/api/user": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "add user", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "add user", + "parameters": [ + { + "description": "user", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AddUserReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/user/activation": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get user activation", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get user activation", + "parameters": [ + { + "type": "string", + "description": "user id", + "name": "user_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.GetUserActivationResp" + } + } + } + ] + } + } + } + } + }, + "/answer/admin/api/user/password": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update user password", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update user password", + "parameters": [ + { + "description": "user", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.UpdateUserPasswordReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/user/profile": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "edit user profile", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "edit user profile", + "parameters": [ + { + "description": "user", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.EditUserProfileReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/user/role": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update user role", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update user role", + "parameters": [ + { + "description": "user", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.UpdateUserRoleReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/user/status": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update user", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update user", + "parameters": [ + { + "description": "user", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.UpdateUserStatusReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/users": { "post": { "security": [ { @@ -11480,19 +11764,71 @@ const docTemplate = `{ } } }, - "schema.SiteBrandingReq": { + "schema.SiteAdvancedReq": { "type": "object", "properties": { - "favicon": { - "type": "string", - "maxLength": 512 - }, - "logo": { - "type": "string", - "maxLength": 512 + "authorized_attachment_extensions": { + "type": "array", + "items": { + "type": "string" + } }, - "mobile_logo": { - "type": "string", + "authorized_image_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "max_attachment_size": { + "type": "integer" + }, + "max_image_megapixel": { + "type": "integer" + }, + "max_image_size": { + "type": "integer" + } + } + }, + "schema.SiteAdvancedResp": { + "type": "object", + "properties": { + "authorized_attachment_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "authorized_image_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "max_attachment_size": { + "type": "integer" + }, + "max_image_megapixel": { + "type": "integer" + }, + "max_image_size": { + "type": "integer" + } + } + }, + "schema.SiteBrandingReq": { + "type": "object", + "properties": { + "favicon": { + "type": "string", + "maxLength": 512 + }, + "logo": { + "type": "string", + "maxLength": 512 + }, + "mobile_logo": { + "type": "string", "maxLength": 512 }, "square_icon": { @@ -11580,9 +11916,6 @@ const docTemplate = `{ "site_url" ], "properties": { - "check_update": { - "type": "boolean" - }, "contact_email": { "type": "string", "maxLength": 512 @@ -11613,9 +11946,6 @@ const docTemplate = `{ "site_url" ], "properties": { - "check_update": { - "type": "boolean" - }, "contact_email": { "type": "string", "maxLength": 512 @@ -11654,7 +11984,7 @@ const docTemplate = `{ "$ref": "#/definitions/schema.SiteGeneralResp" }, "interface": { - "$ref": "#/definitions/schema.SiteInterfaceResp" + "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { "$ref": "#/definitions/schema.SiteLoginResp" @@ -11665,21 +11995,33 @@ const docTemplate = `{ "revision": { "type": "string" }, + "site_advanced": { + "$ref": "#/definitions/schema.SiteAdvancedResp" + }, "site_legal": { "$ref": "#/definitions/schema.SiteLegalSimpleResp" }, + "site_questions": { + "$ref": "#/definitions/schema.SiteQuestionsResp" + }, + "site_security": { + "$ref": "#/definitions/schema.SiteSecurityResp" + }, "site_seo": { "$ref": "#/definitions/schema.SiteSeoResp" }, + "site_tags": { + "$ref": "#/definitions/schema.SiteTagsResp" + }, "site_users": { "$ref": "#/definitions/schema.SiteUsersResp" }, - "site_write": { - "$ref": "#/definitions/schema.SiteWriteResp" - }, "theme": { "$ref": "#/definitions/schema.SiteThemeResp" }, + "users_settings": { + "$ref": "#/definitions/schema.SiteUsersSettingsResp" + }, "version": { "type": "string" } @@ -11688,21 +12030,10 @@ const docTemplate = `{ "schema.SiteInterfaceReq": { "type": "object", "required": [ - "default_avatar", "language", "time_zone" ], "properties": { - "default_avatar": { - "type": "string", - "enum": [ - "system", - "gravatar" - ] - }, - "gravatar_base_url": { - "type": "string" - }, "language": { "type": "string", "maxLength": 128 @@ -11713,24 +12044,13 @@ const docTemplate = `{ } } }, - "schema.SiteInterfaceResp": { + "schema.SiteInterfaceSettingsResp": { "type": "object", "required": [ - "default_avatar", "language", "time_zone" ], "properties": { - "default_avatar": { - "type": "string", - "enum": [ - "system", - "gravatar" - ] - }, - "gravatar_base_url": { - "type": "string" - }, "language": { "type": "string", "maxLength": 128 @@ -11741,60 +12061,6 @@ const docTemplate = `{ } } }, - "schema.SiteLegalReq": { - "type": "object", - "required": [ - "external_content_display" - ], - "properties": { - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "privacy_policy_original_text": { - "type": "string" - }, - "privacy_policy_parsed_text": { - "type": "string" - }, - "terms_of_service_original_text": { - "type": "string" - }, - "terms_of_service_parsed_text": { - "type": "string" - } - } - }, - "schema.SiteLegalResp": { - "type": "object", - "required": [ - "external_content_display" - ], - "properties": { - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "privacy_policy_original_text": { - "type": "string" - }, - "privacy_policy_parsed_text": { - "type": "string" - }, - "terms_of_service_original_text": { - "type": "string" - }, - "terms_of_service_parsed_text": { - "type": "string" - } - } - }, "schema.SiteLegalSimpleResp": { "type": "object", "required": [ @@ -11827,9 +12093,6 @@ const docTemplate = `{ }, "allow_password_login": { "type": "boolean" - }, - "login_required": { - "type": "boolean" } } }, @@ -11850,9 +12113,6 @@ const docTemplate = `{ }, "allow_password_login": { "type": "boolean" - }, - "login_required": { - "type": "boolean" } } }, @@ -11881,6 +12141,118 @@ const docTemplate = `{ } } }, + "schema.SitePoliciesReq": { + "type": "object", + "properties": { + "privacy_policy_original_text": { + "type": "string" + }, + "privacy_policy_parsed_text": { + "type": "string" + }, + "terms_of_service_original_text": { + "type": "string" + }, + "terms_of_service_parsed_text": { + "type": "string" + } + } + }, + "schema.SitePoliciesResp": { + "type": "object", + "properties": { + "privacy_policy_original_text": { + "type": "string" + }, + "privacy_policy_parsed_text": { + "type": "string" + }, + "terms_of_service_original_text": { + "type": "string" + }, + "terms_of_service_parsed_text": { + "type": "string" + } + } + }, + "schema.SiteQuestionsReq": { + "type": "object", + "properties": { + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, + "restrict_answer": { + "type": "boolean" + } + } + }, + "schema.SiteQuestionsResp": { + "type": "object", + "properties": { + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, + "restrict_answer": { + "type": "boolean" + } + } + }, + "schema.SiteSecurityReq": { + "type": "object", + "required": [ + "external_content_display" + ], + "properties": { + "check_update": { + "type": "boolean" + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "login_required": { + "type": "boolean" + } + } + }, + "schema.SiteSecurityResp": { + "type": "object", + "required": [ + "external_content_display" + ], + "properties": { + "check_update": { + "type": "boolean" + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "login_required": { + "type": "boolean" + } + } + }, "schema.SiteSeoReq": { "type": "object", "required": [ @@ -11915,6 +12287,46 @@ const docTemplate = `{ } } }, + "schema.SiteTagsReq": { + "type": "object", + "properties": { + "recommend_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + }, + "required_tag": { + "type": "boolean" + }, + "reserved_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + } + } + }, + "schema.SiteTagsResp": { + "type": "object", + "properties": { + "recommend_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + }, + "required_tag": { + "type": "boolean" + }, + "reserved_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + } + } + }, "schema.SiteThemeReq": { "type": "object", "required": [ @@ -12038,111 +12450,39 @@ const docTemplate = `{ } } }, - "schema.SiteWriteReq": { + "schema.SiteUsersSettingsReq": { "type": "object", + "required": [ + "default_avatar" + ], "properties": { - "authorized_attachment_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "authorized_image_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "max_attachment_size": { - "type": "integer" - }, - "max_image_megapixel": { - "type": "integer" - }, - "max_image_size": { - "type": "integer" - }, - "min_content": { - "type": "integer", - "maximum": 65535, - "minimum": 0 - }, - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, - "recommend_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "required_tag": { - "type": "boolean" - }, - "reserved_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } + "default_avatar": { + "type": "string", + "enum": [ + "system", + "gravatar" + ] }, - "restrict_answer": { - "type": "boolean" + "gravatar_base_url": { + "type": "string" } } }, - "schema.SiteWriteResp": { + "schema.SiteUsersSettingsResp": { "type": "object", + "required": [ + "default_avatar" + ], "properties": { - "authorized_attachment_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "authorized_image_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "max_attachment_size": { - "type": "integer" - }, - "max_image_megapixel": { - "type": "integer" - }, - "max_image_size": { - "type": "integer" - }, - "min_content": { - "type": "integer", - "maximum": 65535, - "minimum": 0 - }, - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, - "recommend_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "required_tag": { - "type": "boolean" - }, - "reserved_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } + "default_avatar": { + "type": "string", + "enum": [ + "system", + "gravatar" + ] }, - "restrict_answer": { - "type": "boolean" + "gravatar_base_url": { + "type": "string" } } }, diff --git a/docs/swagger.json b/docs/swagger.json index 67148ea44..dac2b38fd 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1366,6 +1366,77 @@ } } }, + "/answer/admin/api/siteinfo/advanced": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get site advanced setting", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get site advanced setting", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteAdvancedResp" + } + } + } + ] + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update site advanced info", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update site advanced info", + "parameters": [ + { + "description": "advanced settings", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.SiteAdvancedReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, "/answer/admin/api/siteinfo/branding": { "get": { "security": [ @@ -1606,7 +1677,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteInterfaceResp" + "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" } } } @@ -1650,21 +1721,21 @@ } } }, - "/answer/admin/api/siteinfo/legal": { + "/answer/admin/api/siteinfo/login": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "Set the legal information for the site", + "description": "get site info login config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "Set the legal information for the site", + "summary": "get site info login config", "responses": { "200": { "description": "OK", @@ -1677,7 +1748,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteLegalResp" + "$ref": "#/definitions/schema.SiteLoginResp" } } } @@ -1692,22 +1763,22 @@ "ApiKeyAuth": [] } ], - "description": "update site legal info", + "description": "update site login", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site legal info", + "summary": "update site login", "parameters": [ { - "description": "write info", + "description": "login info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteLegalReq" + "$ref": "#/definitions/schema.SiteLoginReq" } } ], @@ -1721,21 +1792,21 @@ } } }, - "/answer/admin/api/siteinfo/login": { + "/answer/admin/api/siteinfo/polices": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site info login config", + "description": "Get the policies information for the site", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site info login config", + "summary": "Get the policies information for the site", "responses": { "200": { "description": "OK", @@ -1748,7 +1819,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteLoginResp" + "$ref": "#/definitions/schema.SitePoliciesResp" } } } @@ -1763,22 +1834,22 @@ "ApiKeyAuth": [] } ], - "description": "update site login", + "description": "update site policies configuration", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site login", + "summary": "update site policies configuration", "parameters": [ { - "description": "login info", + "description": "write info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteLoginReq" + "$ref": "#/definitions/schema.SitePoliciesReq" } } ], @@ -1792,21 +1863,21 @@ } } }, - "/answer/admin/api/siteinfo/seo": { + "/answer/admin/api/siteinfo/question": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site seo information", + "description": "get site questions setting", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site seo information", + "summary": "get site questions setting", "responses": { "200": { "description": "OK", @@ -1819,7 +1890,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteSeoResp" + "$ref": "#/definitions/schema.SiteQuestionsResp" } } } @@ -1834,22 +1905,22 @@ "ApiKeyAuth": [] } ], - "description": "update site seo information", + "description": "update site question settings", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site seo information", + "summary": "update site question settings", "parameters": [ { - "description": "seo", + "description": "questions settings", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteSeoReq" + "$ref": "#/definitions/schema.SiteQuestionsReq" } } ], @@ -1863,21 +1934,21 @@ } } }, - "/answer/admin/api/siteinfo/theme": { + "/answer/admin/api/siteinfo/security": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site info theme config", + "description": "Get the security information for the site", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site info theme config", + "summary": "Get the security information for the site", "responses": { "200": { "description": "OK", @@ -1890,7 +1961,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteThemeResp" + "$ref": "#/definitions/schema.SiteSecurityResp" } } } @@ -1905,22 +1976,22 @@ "ApiKeyAuth": [] } ], - "description": "update site custom css html config", + "description": "update site security configuration", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site custom css html config", + "summary": "update site security configuration", "parameters": [ { - "description": "login info", + "description": "write info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteThemeReq" + "$ref": "#/definitions/schema.SiteSecurityReq" } } ], @@ -1934,21 +2005,21 @@ } } }, - "/answer/admin/api/siteinfo/users": { + "/answer/admin/api/siteinfo/seo": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site user config", + "description": "get site seo information", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site user config", + "summary": "get site seo information", "responses": { "200": { "description": "OK", @@ -1961,7 +2032,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteUsersResp" + "$ref": "#/definitions/schema.SiteSeoResp" } } } @@ -1976,22 +2047,22 @@ "ApiKeyAuth": [] } ], - "description": "update site info config about users", + "description": "update site seo information", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site info config about users", + "summary": "update site seo information", "parameters": [ { - "description": "users info", + "description": "seo", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteUsersReq" + "$ref": "#/definitions/schema.SiteSeoReq" } } ], @@ -2005,21 +2076,21 @@ } } }, - "/answer/admin/api/siteinfo/write": { + "/answer/admin/api/siteinfo/tag": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get site interface", + "description": "get site tags setting", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get site interface", + "summary": "get site tags setting", "responses": { "200": { "description": "OK", @@ -2032,7 +2103,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.SiteWriteResp" + "$ref": "#/definitions/schema.SiteTagsResp" } } } @@ -2047,22 +2118,22 @@ "ApiKeyAuth": [] } ], - "description": "update site write info", + "description": "update site tag settings", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update site write info", + "summary": "update site tag settings", "parameters": [ { - "description": "write info", + "description": "tags settings", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.SiteWriteReq" + "$ref": "#/definitions/schema.SiteTagsReq" } } ], @@ -2076,57 +2147,64 @@ } } }, - "/answer/admin/api/theme/options": { + "/answer/admin/api/siteinfo/theme": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "Get theme options", + "description": "get site info theme config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "Get theme options", + "summary": "get site info theme config", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/handler.RespBody" + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteThemeResp" + } + } + } + ] } } } - } - }, - "/answer/admin/api/user": { - "post": { + }, + "put": { "security": [ { "ApiKeyAuth": [] } ], - "description": "add user", - "consumes": [ - "application/json" - ], + "description": "update site custom css html config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "add user", + "summary": "update site custom css html config", "parameters": [ { - "description": "user", + "description": "login info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.AddUserReq" + "$ref": "#/definitions/schema.SiteThemeReq" } } ], @@ -2140,30 +2218,21 @@ } } }, - "/answer/admin/api/user/activation": { + "/answer/admin/api/siteinfo/users": { "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "get user activation", + "description": "get site user config", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "get user activation", - "parameters": [ - { - "type": "string", - "description": "user id", - "name": "user_id", - "in": "query", - "required": true - } - ], + "summary": "get site user config", "responses": { "200": { "description": "OK", @@ -2176,7 +2245,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/definitions/schema.GetUserActivationResp" + "$ref": "#/definitions/schema.SiteUsersResp" } } } @@ -2184,34 +2253,29 @@ } } } - } - }, - "/answer/admin/api/user/password": { + }, "put": { "security": [ { "ApiKeyAuth": [] } ], - "description": "update user password", - "consumes": [ - "application/json" - ], + "description": "update site info config about users", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update user password", + "summary": "update site info config about users", "parameters": [ { - "description": "user", + "description": "users info", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.UpdateUserPasswordReq" + "$ref": "#/definitions/schema.SiteUsersReq" } } ], @@ -2225,71 +2289,64 @@ } } }, - "/answer/admin/api/user/profile": { - "put": { + "/answer/admin/api/siteinfo/users-settings": { + "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "edit user profile", - "consumes": [ - "application/json" - ], + "description": "get site interface", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "edit user profile", - "parameters": [ - { - "description": "user", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/schema.EditUserProfileReq" - } - } - ], + "summary": "get site interface", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/handler.RespBody" + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.SiteUsersSettingsResp" + } + } + } + ] } } } - } - }, - "/answer/admin/api/user/role": { + }, "put": { "security": [ { "ApiKeyAuth": [] } ], - "description": "update user role", - "consumes": [ - "application/json" - ], + "description": "update site info users settings", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update user role", + "summary": "update site info users settings", "parameters": [ { - "description": "user", + "description": "general", "name": "data", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/schema.UpdateUserRoleReq" + "$ref": "#/definitions/schema.SiteUsersSettingsReq" } } ], @@ -2303,35 +2360,21 @@ } } }, - "/answer/admin/api/user/status": { - "put": { + "/answer/admin/api/theme/options": { + "get": { "security": [ { "ApiKeyAuth": [] } ], - "description": "update user", - "consumes": [ - "application/json" - ], + "description": "Get theme options", "produces": [ "application/json" ], "tags": [ "admin" ], - "summary": "update user", - "parameters": [ - { - "description": "user", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/schema.UpdateUserStatusReq" - } - } - ], + "summary": "Get theme options", "responses": { "200": { "description": "OK", @@ -2342,7 +2385,248 @@ } } }, - "/answer/admin/api/users": { + "/answer/admin/api/user": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "add user", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "add user", + "parameters": [ + { + "description": "user", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AddUserReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/user/activation": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "get user activation", + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "get user activation", + "parameters": [ + { + "type": "string", + "description": "user id", + "name": "user_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/handler.RespBody" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/schema.GetUserActivationResp" + } + } + } + ] + } + } + } + } + }, + "/answer/admin/api/user/password": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update user password", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update user password", + "parameters": [ + { + "description": "user", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.UpdateUserPasswordReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/user/profile": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "edit user profile", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "edit user profile", + "parameters": [ + { + "description": "user", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.EditUserProfileReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/user/role": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update user role", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update user role", + "parameters": [ + { + "description": "user", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.UpdateUserRoleReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/user/status": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "update user", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "update user", + "parameters": [ + { + "description": "user", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.UpdateUserStatusReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + } + }, + "/answer/admin/api/users": { "post": { "security": [ { @@ -11453,19 +11737,71 @@ } } }, - "schema.SiteBrandingReq": { + "schema.SiteAdvancedReq": { "type": "object", "properties": { - "favicon": { - "type": "string", - "maxLength": 512 - }, - "logo": { - "type": "string", - "maxLength": 512 + "authorized_attachment_extensions": { + "type": "array", + "items": { + "type": "string" + } }, - "mobile_logo": { - "type": "string", + "authorized_image_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "max_attachment_size": { + "type": "integer" + }, + "max_image_megapixel": { + "type": "integer" + }, + "max_image_size": { + "type": "integer" + } + } + }, + "schema.SiteAdvancedResp": { + "type": "object", + "properties": { + "authorized_attachment_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "authorized_image_extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "max_attachment_size": { + "type": "integer" + }, + "max_image_megapixel": { + "type": "integer" + }, + "max_image_size": { + "type": "integer" + } + } + }, + "schema.SiteBrandingReq": { + "type": "object", + "properties": { + "favicon": { + "type": "string", + "maxLength": 512 + }, + "logo": { + "type": "string", + "maxLength": 512 + }, + "mobile_logo": { + "type": "string", "maxLength": 512 }, "square_icon": { @@ -11553,9 +11889,6 @@ "site_url" ], "properties": { - "check_update": { - "type": "boolean" - }, "contact_email": { "type": "string", "maxLength": 512 @@ -11586,9 +11919,6 @@ "site_url" ], "properties": { - "check_update": { - "type": "boolean" - }, "contact_email": { "type": "string", "maxLength": 512 @@ -11627,7 +11957,7 @@ "$ref": "#/definitions/schema.SiteGeneralResp" }, "interface": { - "$ref": "#/definitions/schema.SiteInterfaceResp" + "$ref": "#/definitions/schema.SiteInterfaceSettingsResp" }, "login": { "$ref": "#/definitions/schema.SiteLoginResp" @@ -11638,21 +11968,33 @@ "revision": { "type": "string" }, + "site_advanced": { + "$ref": "#/definitions/schema.SiteAdvancedResp" + }, "site_legal": { "$ref": "#/definitions/schema.SiteLegalSimpleResp" }, + "site_questions": { + "$ref": "#/definitions/schema.SiteQuestionsResp" + }, + "site_security": { + "$ref": "#/definitions/schema.SiteSecurityResp" + }, "site_seo": { "$ref": "#/definitions/schema.SiteSeoResp" }, + "site_tags": { + "$ref": "#/definitions/schema.SiteTagsResp" + }, "site_users": { "$ref": "#/definitions/schema.SiteUsersResp" }, - "site_write": { - "$ref": "#/definitions/schema.SiteWriteResp" - }, "theme": { "$ref": "#/definitions/schema.SiteThemeResp" }, + "users_settings": { + "$ref": "#/definitions/schema.SiteUsersSettingsResp" + }, "version": { "type": "string" } @@ -11661,21 +12003,10 @@ "schema.SiteInterfaceReq": { "type": "object", "required": [ - "default_avatar", "language", "time_zone" ], "properties": { - "default_avatar": { - "type": "string", - "enum": [ - "system", - "gravatar" - ] - }, - "gravatar_base_url": { - "type": "string" - }, "language": { "type": "string", "maxLength": 128 @@ -11686,24 +12017,13 @@ } } }, - "schema.SiteInterfaceResp": { + "schema.SiteInterfaceSettingsResp": { "type": "object", "required": [ - "default_avatar", "language", "time_zone" ], "properties": { - "default_avatar": { - "type": "string", - "enum": [ - "system", - "gravatar" - ] - }, - "gravatar_base_url": { - "type": "string" - }, "language": { "type": "string", "maxLength": 128 @@ -11714,60 +12034,6 @@ } } }, - "schema.SiteLegalReq": { - "type": "object", - "required": [ - "external_content_display" - ], - "properties": { - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "privacy_policy_original_text": { - "type": "string" - }, - "privacy_policy_parsed_text": { - "type": "string" - }, - "terms_of_service_original_text": { - "type": "string" - }, - "terms_of_service_parsed_text": { - "type": "string" - } - } - }, - "schema.SiteLegalResp": { - "type": "object", - "required": [ - "external_content_display" - ], - "properties": { - "external_content_display": { - "type": "string", - "enum": [ - "always_display", - "ask_before_display" - ] - }, - "privacy_policy_original_text": { - "type": "string" - }, - "privacy_policy_parsed_text": { - "type": "string" - }, - "terms_of_service_original_text": { - "type": "string" - }, - "terms_of_service_parsed_text": { - "type": "string" - } - } - }, "schema.SiteLegalSimpleResp": { "type": "object", "required": [ @@ -11800,9 +12066,6 @@ }, "allow_password_login": { "type": "boolean" - }, - "login_required": { - "type": "boolean" } } }, @@ -11823,9 +12086,6 @@ }, "allow_password_login": { "type": "boolean" - }, - "login_required": { - "type": "boolean" } } }, @@ -11854,6 +12114,118 @@ } } }, + "schema.SitePoliciesReq": { + "type": "object", + "properties": { + "privacy_policy_original_text": { + "type": "string" + }, + "privacy_policy_parsed_text": { + "type": "string" + }, + "terms_of_service_original_text": { + "type": "string" + }, + "terms_of_service_parsed_text": { + "type": "string" + } + } + }, + "schema.SitePoliciesResp": { + "type": "object", + "properties": { + "privacy_policy_original_text": { + "type": "string" + }, + "privacy_policy_parsed_text": { + "type": "string" + }, + "terms_of_service_original_text": { + "type": "string" + }, + "terms_of_service_parsed_text": { + "type": "string" + } + } + }, + "schema.SiteQuestionsReq": { + "type": "object", + "properties": { + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, + "restrict_answer": { + "type": "boolean" + } + } + }, + "schema.SiteQuestionsResp": { + "type": "object", + "properties": { + "min_content": { + "type": "integer", + "maximum": 65535, + "minimum": 0 + }, + "min_tags": { + "type": "integer", + "maximum": 5, + "minimum": 0 + }, + "restrict_answer": { + "type": "boolean" + } + } + }, + "schema.SiteSecurityReq": { + "type": "object", + "required": [ + "external_content_display" + ], + "properties": { + "check_update": { + "type": "boolean" + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "login_required": { + "type": "boolean" + } + } + }, + "schema.SiteSecurityResp": { + "type": "object", + "required": [ + "external_content_display" + ], + "properties": { + "check_update": { + "type": "boolean" + }, + "external_content_display": { + "type": "string", + "enum": [ + "always_display", + "ask_before_display" + ] + }, + "login_required": { + "type": "boolean" + } + } + }, "schema.SiteSeoReq": { "type": "object", "required": [ @@ -11888,6 +12260,46 @@ } } }, + "schema.SiteTagsReq": { + "type": "object", + "properties": { + "recommend_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + }, + "required_tag": { + "type": "boolean" + }, + "reserved_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + } + } + }, + "schema.SiteTagsResp": { + "type": "object", + "properties": { + "recommend_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + }, + "required_tag": { + "type": "boolean" + }, + "reserved_tags": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.SiteWriteTag" + } + } + } + }, "schema.SiteThemeReq": { "type": "object", "required": [ @@ -12011,111 +12423,39 @@ } } }, - "schema.SiteWriteReq": { + "schema.SiteUsersSettingsReq": { "type": "object", + "required": [ + "default_avatar" + ], "properties": { - "authorized_attachment_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "authorized_image_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "max_attachment_size": { - "type": "integer" - }, - "max_image_megapixel": { - "type": "integer" - }, - "max_image_size": { - "type": "integer" - }, - "min_content": { - "type": "integer", - "maximum": 65535, - "minimum": 0 - }, - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, - "recommend_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "required_tag": { - "type": "boolean" - }, - "reserved_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } + "default_avatar": { + "type": "string", + "enum": [ + "system", + "gravatar" + ] }, - "restrict_answer": { - "type": "boolean" + "gravatar_base_url": { + "type": "string" } } }, - "schema.SiteWriteResp": { + "schema.SiteUsersSettingsResp": { "type": "object", + "required": [ + "default_avatar" + ], "properties": { - "authorized_attachment_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "authorized_image_extensions": { - "type": "array", - "items": { - "type": "string" - } - }, - "max_attachment_size": { - "type": "integer" - }, - "max_image_megapixel": { - "type": "integer" - }, - "max_image_size": { - "type": "integer" - }, - "min_content": { - "type": "integer", - "maximum": 65535, - "minimum": 0 - }, - "min_tags": { - "type": "integer", - "maximum": 5, - "minimum": 0 - }, - "recommend_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } - }, - "required_tag": { - "type": "boolean" - }, - "reserved_tags": { - "type": "array", - "items": { - "$ref": "#/definitions/schema.SiteWriteTag" - } + "default_avatar": { + "type": "string", + "enum": [ + "system", + "gravatar" + ] }, - "restrict_answer": { - "type": "boolean" + "gravatar_base_url": { + "type": "string" } } }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 03e3508be..7a7adb681 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2285,6 +2285,40 @@ definitions: prompt_config: $ref: '#/definitions/schema.AIPromptConfig' type: object + schema.SiteAdvancedReq: + properties: + authorized_attachment_extensions: + items: + type: string + type: array + authorized_image_extensions: + items: + type: string + type: array + max_attachment_size: + type: integer + max_image_megapixel: + type: integer + max_image_size: + type: integer + type: object + schema.SiteAdvancedResp: + properties: + authorized_attachment_extensions: + items: + type: string + type: array + authorized_image_extensions: + items: + type: string + type: array + max_attachment_size: + type: integer + max_image_megapixel: + type: integer + max_image_size: + type: integer + type: object schema.SiteBrandingReq: properties: favicon: @@ -2353,8 +2387,6 @@ definitions: type: object schema.SiteGeneralReq: properties: - check_update: - type: boolean contact_email: maxLength: 512 type: string @@ -2377,8 +2409,6 @@ definitions: type: object schema.SiteGeneralResp: properties: - check_update: - type: boolean contact_email: maxLength: 512 type: string @@ -2410,35 +2440,36 @@ definitions: general: $ref: '#/definitions/schema.SiteGeneralResp' interface: - $ref: '#/definitions/schema.SiteInterfaceResp' + $ref: '#/definitions/schema.SiteInterfaceSettingsResp' login: $ref: '#/definitions/schema.SiteLoginResp' mcp_enabled: type: boolean revision: type: string + site_advanced: + $ref: '#/definitions/schema.SiteAdvancedResp' site_legal: $ref: '#/definitions/schema.SiteLegalSimpleResp' + site_questions: + $ref: '#/definitions/schema.SiteQuestionsResp' + site_security: + $ref: '#/definitions/schema.SiteSecurityResp' site_seo: $ref: '#/definitions/schema.SiteSeoResp' + site_tags: + $ref: '#/definitions/schema.SiteTagsResp' site_users: $ref: '#/definitions/schema.SiteUsersResp' - site_write: - $ref: '#/definitions/schema.SiteWriteResp' theme: $ref: '#/definitions/schema.SiteThemeResp' + users_settings: + $ref: '#/definitions/schema.SiteUsersSettingsResp' version: type: string type: object schema.SiteInterfaceReq: properties: - default_avatar: - enum: - - system - - gravatar - type: string - gravatar_base_url: - type: string language: maxLength: 128 type: string @@ -2446,19 +2477,11 @@ definitions: maxLength: 128 type: string required: - - default_avatar - language - time_zone type: object - schema.SiteInterfaceResp: + schema.SiteInterfaceSettingsResp: properties: - default_avatar: - enum: - - system - - gravatar - type: string - gravatar_base_url: - type: string language: maxLength: 128 type: string @@ -2466,46 +2489,9 @@ definitions: maxLength: 128 type: string required: - - default_avatar - language - time_zone type: object - schema.SiteLegalReq: - properties: - external_content_display: - enum: - - always_display - - ask_before_display - type: string - privacy_policy_original_text: - type: string - privacy_policy_parsed_text: - type: string - terms_of_service_original_text: - type: string - terms_of_service_parsed_text: - type: string - required: - - external_content_display - type: object - schema.SiteLegalResp: - properties: - external_content_display: - enum: - - always_display - - ask_before_display - type: string - privacy_policy_original_text: - type: string - privacy_policy_parsed_text: - type: string - terms_of_service_original_text: - type: string - terms_of_service_parsed_text: - type: string - required: - - external_content_display - type: object schema.SiteLegalSimpleResp: properties: external_content_display: @@ -2528,8 +2514,6 @@ definitions: type: boolean allow_password_login: type: boolean - login_required: - type: boolean type: object schema.SiteLoginResp: properties: @@ -2543,8 +2527,6 @@ definitions: type: boolean allow_password_login: type: boolean - login_required: - type: boolean type: object schema.SiteMCPReq: properties: @@ -2562,6 +2544,82 @@ definitions: url: type: string type: object + schema.SitePoliciesReq: + properties: + privacy_policy_original_text: + type: string + privacy_policy_parsed_text: + type: string + terms_of_service_original_text: + type: string + terms_of_service_parsed_text: + type: string + type: object + schema.SitePoliciesResp: + properties: + privacy_policy_original_text: + type: string + privacy_policy_parsed_text: + type: string + terms_of_service_original_text: + type: string + terms_of_service_parsed_text: + type: string + type: object + schema.SiteQuestionsReq: + properties: + min_content: + maximum: 65535 + minimum: 0 + type: integer + min_tags: + maximum: 5 + minimum: 0 + type: integer + restrict_answer: + type: boolean + type: object + schema.SiteQuestionsResp: + properties: + min_content: + maximum: 65535 + minimum: 0 + type: integer + min_tags: + maximum: 5 + minimum: 0 + type: integer + restrict_answer: + type: boolean + type: object + schema.SiteSecurityReq: + properties: + check_update: + type: boolean + external_content_display: + enum: + - always_display + - ask_before_display + type: string + login_required: + type: boolean + required: + - external_content_display + type: object + schema.SiteSecurityResp: + properties: + check_update: + type: boolean + external_content_display: + enum: + - always_display + - ask_before_display + type: string + login_required: + type: boolean + required: + - external_content_display + type: object schema.SiteSeoReq: properties: permalink: @@ -2586,6 +2644,32 @@ definitions: - permalink - robots type: object + schema.SiteTagsReq: + properties: + recommend_tags: + items: + $ref: '#/definitions/schema.SiteWriteTag' + type: array + required_tag: + type: boolean + reserved_tags: + items: + $ref: '#/definitions/schema.SiteWriteTag' + type: array + type: object + schema.SiteTagsResp: + properties: + recommend_tags: + items: + $ref: '#/definitions/schema.SiteWriteTag' + type: array + required_tag: + type: boolean + reserved_tags: + items: + $ref: '#/definitions/schema.SiteWriteTag' + type: array + type: object schema.SiteThemeReq: properties: color_scheme: @@ -2669,79 +2753,29 @@ definitions: required: - default_avatar type: object - schema.SiteWriteReq: + schema.SiteUsersSettingsReq: properties: - authorized_attachment_extensions: - items: - type: string - type: array - authorized_image_extensions: - items: - type: string - type: array - max_attachment_size: - type: integer - max_image_megapixel: - type: integer - max_image_size: - type: integer - min_content: - maximum: 65535 - minimum: 0 - type: integer - min_tags: - maximum: 5 - minimum: 0 - type: integer - recommend_tags: - items: - $ref: '#/definitions/schema.SiteWriteTag' - type: array - required_tag: - type: boolean - reserved_tags: - items: - $ref: '#/definitions/schema.SiteWriteTag' - type: array - restrict_answer: - type: boolean + default_avatar: + enum: + - system + - gravatar + type: string + gravatar_base_url: + type: string + required: + - default_avatar type: object - schema.SiteWriteResp: + schema.SiteUsersSettingsResp: properties: - authorized_attachment_extensions: - items: - type: string - type: array - authorized_image_extensions: - items: - type: string - type: array - max_attachment_size: - type: integer - max_image_megapixel: - type: integer - max_image_size: - type: integer - min_content: - maximum: 65535 - minimum: 0 - type: integer - min_tags: - maximum: 5 - minimum: 0 - type: integer - recommend_tags: - items: - $ref: '#/definitions/schema.SiteWriteTag' - type: array - required_tag: - type: boolean - reserved_tags: - items: - $ref: '#/definitions/schema.SiteWriteTag' - type: array - restrict_answer: - type: boolean + default_avatar: + enum: + - system + - gravatar + type: string + gravatar_base_url: + type: string + required: + - default_avatar type: object schema.SiteWriteTag: properties: @@ -4253,6 +4287,47 @@ paths: summary: update smtp config tags: - admin + /answer/admin/api/siteinfo/advanced: + get: + description: get site advanced setting + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteAdvancedResp' + type: object + security: + - ApiKeyAuth: [] + summary: get site advanced setting + tags: + - admin + put: + description: update site advanced info + parameters: + - description: advanced settings + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteAdvancedReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update site advanced info + tags: + - admin /answer/admin/api/siteinfo/branding: get: description: get site interface @@ -4389,7 +4464,7 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteInterfaceResp' + $ref: '#/definitions/schema.SiteInterfaceSettingsResp' type: object security: - ApiKeyAuth: [] @@ -4417,9 +4492,50 @@ paths: summary: update site info interface tags: - admin - /answer/admin/api/siteinfo/legal: + /answer/admin/api/siteinfo/login: + get: + description: get site info login config + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteLoginResp' + type: object + security: + - ApiKeyAuth: [] + summary: get site info login config + tags: + - admin + put: + description: update site login + parameters: + - description: login info + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteLoginReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update site login + tags: + - admin + /answer/admin/api/siteinfo/polices: get: - description: Set the legal information for the site + description: Get the policies information for the site produces: - application/json responses: @@ -4430,22 +4546,22 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteLegalResp' + $ref: '#/definitions/schema.SitePoliciesResp' type: object security: - ApiKeyAuth: [] - summary: Set the legal information for the site + summary: Get the policies information for the site tags: - admin put: - description: update site legal info + description: update site policies configuration parameters: - description: write info in: body name: data required: true schema: - $ref: '#/definitions/schema.SiteLegalReq' + $ref: '#/definitions/schema.SitePoliciesReq' produces: - application/json responses: @@ -4455,12 +4571,12 @@ paths: $ref: '#/definitions/handler.RespBody' security: - ApiKeyAuth: [] - summary: update site legal info + summary: update site policies configuration tags: - admin - /answer/admin/api/siteinfo/login: + /answer/admin/api/siteinfo/question: get: - description: get site info login config + description: get site questions setting produces: - application/json responses: @@ -4471,22 +4587,22 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteLoginResp' + $ref: '#/definitions/schema.SiteQuestionsResp' type: object security: - ApiKeyAuth: [] - summary: get site info login config + summary: get site questions setting tags: - admin put: - description: update site login + description: update site question settings parameters: - - description: login info + - description: questions settings in: body name: data required: true schema: - $ref: '#/definitions/schema.SiteLoginReq' + $ref: '#/definitions/schema.SiteQuestionsReq' produces: - application/json responses: @@ -4496,7 +4612,48 @@ paths: $ref: '#/definitions/handler.RespBody' security: - ApiKeyAuth: [] - summary: update site login + summary: update site question settings + tags: + - admin + /answer/admin/api/siteinfo/security: + get: + description: Get the security information for the site + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteSecurityResp' + type: object + security: + - ApiKeyAuth: [] + summary: Get the security information for the site + tags: + - admin + put: + description: update site security configuration + parameters: + - description: write info + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteSecurityReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update site security configuration tags: - admin /answer/admin/api/siteinfo/seo: @@ -4540,6 +4697,47 @@ paths: summary: update site seo information tags: - admin + /answer/admin/api/siteinfo/tag: + get: + description: get site tags setting + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/handler.RespBody' + - properties: + data: + $ref: '#/definitions/schema.SiteTagsResp' + type: object + security: + - ApiKeyAuth: [] + summary: get site tags setting + tags: + - admin + put: + description: update site tag settings + parameters: + - description: tags settings + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.SiteTagsReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + security: + - ApiKeyAuth: [] + summary: update site tag settings + tags: + - admin /answer/admin/api/siteinfo/theme: get: description: get site info theme config @@ -4622,7 +4820,7 @@ paths: summary: update site info config about users tags: - admin - /answer/admin/api/siteinfo/write: + /answer/admin/api/siteinfo/users-settings: get: description: get site interface produces: @@ -4635,7 +4833,7 @@ paths: - $ref: '#/definitions/handler.RespBody' - properties: data: - $ref: '#/definitions/schema.SiteWriteResp' + $ref: '#/definitions/schema.SiteUsersSettingsResp' type: object security: - ApiKeyAuth: [] @@ -4643,14 +4841,14 @@ paths: tags: - admin put: - description: update site write info + description: update site info users settings parameters: - - description: write info + - description: general in: body name: data required: true schema: - $ref: '#/definitions/schema.SiteWriteReq' + $ref: '#/definitions/schema.SiteUsersSettingsReq' produces: - application/json responses: @@ -4660,7 +4858,7 @@ paths: $ref: '#/definitions/handler.RespBody' security: - ApiKeyAuth: [] - summary: update site write info + summary: update site info users settings tags: - admin /answer/admin/api/theme/options: diff --git a/internal/migrations/v32.go b/internal/migrations/v32.go deleted file mode 100644 index 89b970475..000000000 --- a/internal/migrations/v32.go +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package migrations - -import ( - "context" - "encoding/json" - "fmt" - - "github.com/apache/answer/internal/base/constant" - "github.com/apache/answer/internal/entity" - "github.com/apache/answer/internal/schema" - "github.com/segmentfault/pacman/log" - "xorm.io/xorm" -) - -func aiFeat(ctx context.Context, x *xorm.Engine) error { - if err := addAIConversationTables(ctx, x); err != nil { - return fmt.Errorf("add ai conversation tables failed: %w", err) - } - if err := addAPIKey(ctx, x); err != nil { - return fmt.Errorf("add api key failed: %w", err) - } - log.Info("AI feature migration completed successfully") - return nil -} - -func addAIConversationTables(ctx context.Context, x *xorm.Engine) error { - if err := x.Context(ctx).Sync(new(entity.AIConversation)); err != nil { - return fmt.Errorf("sync ai_conversation table failed: %w", err) - } - - if err := x.Context(ctx).Sync(new(entity.AIConversationRecord)); err != nil { - return fmt.Errorf("sync ai_conversation_record table failed: %w", err) - } - - return nil -} - -func addAPIKey(ctx context.Context, x *xorm.Engine) error { - err := x.Context(ctx).Sync(new(entity.APIKey)) - if err != nil { - return err - } - - defaultConfigTable := []*entity.Config{ - {ID: 10000, Key: "ai_config.provider", Value: `[{"default_api_host":"https://api.openai.com","display_name":"OpenAI","name":"openai"},{"default_api_host":"https://generativelanguage.googleapis.com","display_name":"Gemini","name":"gemini"},{"default_api_host":"https://api.anthropic.com","display_name":"Anthropic","name":"anthropic"}]`}, - } - for _, c := range defaultConfigTable { - exist, err := x.Context(ctx).Get(&entity.Config{Key: c.Key}) - if err != nil { - return fmt.Errorf("get config failed: %w", err) - } - if exist { - continue - } - if _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil { - log.Errorf("insert %+v config failed: %s", c, err) - return fmt.Errorf("add config failed: %w", err) - } - } - - aiSiteInfo := &entity.SiteInfo{ - Type: constant.SiteTypeAI, - } - exist, err := x.Context(ctx).Get(aiSiteInfo) - if err != nil { - return fmt.Errorf("get config failed: %w", err) - } - if exist { - content := &schema.SiteAIReq{} - _ = json.Unmarshal([]byte(aiSiteInfo.Content), content) - content.PromptConfig = &schema.AIPromptConfig{ - ZhCN: constant.DefaultAIPromptConfigZhCN, - EnUS: constant.DefaultAIPromptConfigEnUS, - } - data, _ := json.Marshal(content) - aiSiteInfo.Content = string(data) - _, err = x.Context(ctx).ID(aiSiteInfo.ID).Cols("content").Update(aiSiteInfo) - if err != nil { - return fmt.Errorf("update site info failed: %w", err) - } - } else { - content := &schema.SiteAIReq{ - PromptConfig: &schema.AIPromptConfig{ - ZhCN: constant.DefaultAIPromptConfigZhCN, - EnUS: constant.DefaultAIPromptConfigEnUS, - }, - } - data, _ := json.Marshal(content) - aiSiteInfo.Content = string(data) - aiSiteInfo.Type = constant.SiteTypeAI - if _, err = x.Context(ctx).Insert(aiSiteInfo); err != nil { - return fmt.Errorf("insert site info failed: %w", err) - } - log.Infof("insert site info %+v", aiSiteInfo) - } - return nil -} From 4fd96675f356de5932948c40f658e47370b80394 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Wed, 28 Jan 2026 12:11:28 +0800 Subject: [PATCH 91/92] fix: improve Brotli compression handling and validate user input in vote status --- internal/base/server/http.go | 8 +++++++- internal/repo/activity_common/vote.go | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/internal/base/server/http.go b/internal/base/server/http.go index 512f3da21..050e31923 100644 --- a/internal/base/server/http.go +++ b/internal/base/server/http.go @@ -23,6 +23,7 @@ import ( "html/template" "io/fs" "os" + "strings" brotli "github.com/anargu/gin-brotli" "github.com/apache/answer/internal/base/middleware" @@ -51,7 +52,12 @@ func NewHTTPServer(debug bool, gin.SetMode(gin.ReleaseMode) } r := gin.New() - r.Use(brotli.Brotli(brotli.DefaultCompression), middleware.ExtractAndSetAcceptLanguage, shortIDMiddleware.SetShortIDFlag()) + r.Use(func(ctx *gin.Context) { + if strings.Contains(ctx.Request.URL.Path, "/chat/completions") { + return + } + brotli.Brotli(brotli.DefaultCompression)(ctx) + }, middleware.ExtractAndSetAcceptLanguage, shortIDMiddleware.SetShortIDFlag()) r.GET("/healthz", func(ctx *gin.Context) { ctx.String(200, "OK") }) templatePath := os.Getenv("ANSWER_TEMPLATE_PATH") diff --git a/internal/repo/activity_common/vote.go b/internal/repo/activity_common/vote.go index 506578424..8ec834231 100644 --- a/internal/repo/activity_common/vote.go +++ b/internal/repo/activity_common/vote.go @@ -47,7 +47,13 @@ func NewVoteRepo(data *data.Data, activityRepo activity_common.ActivityRepo) act } func (vr *VoteRepo) GetVoteStatus(ctx context.Context, objectID, userID string) (status string) { + if len(userID) == 0 { + return "" + } objectID = uid.DeShortID(objectID) + if len(objectID) == 0 || objectID == "0" { + return "" + } for _, action := range []string{"vote_up", "vote_down"} { activityType, _, _, err := vr.activityRepo.GetActivityTypeByObjID(ctx, objectID, action) if err != nil { From 34c1e8a38a4ea6bcd140508afb71bcd373757bff Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Wed, 28 Jan 2026 15:45:39 +0800 Subject: [PATCH 92/92] docs(Makefile): upgrade version to 2.0.0 --- Makefile | 3 +-- README.md | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 14d52503f..4944edbee 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ .PHONY: build clean ui -VERSION=1.7.1 -BIN=answer +VERSION=2.0.0 DIR_SRC=./cmd/answer DOCKER_CMD=docker diff --git a/README.md b/README.md index 6e96c516a..b9ffc2d85 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ To learn more about the project, visit [answer.apache.org](https://answer.apache ### Running with docker ```bash -docker run -d -p 9080:80 -v answer-data:/data --name answer apache/answer:1.7.1 +docker run -d -p 9080:80 -v answer-data:/data --name answer apache/answer:2.0.0 ``` For more information, see [Installation](https://answer.apache.org/docs/installation).