Compare commits

...
Sign in to create a new pull request.

8 commits

Author SHA1 Message Date
GitHub Action
ef2640b5fc Update OpenAPI documentation 2025-07-05 22:20:01 +00:00
majora2007
76fd7ab4ce Bump versions by dotnet-bump-version. 2025-07-05 22:18:52 +00:00
Joe Milazzo
08c52b4281
No More Sort Prefixes (#3895) 2025-07-05 15:18:11 -07:00
GitHub Action
9eadf956fb Update OpenAPI documentation 2025-07-05 19:53:05 +00:00
Joe Milazzo
eab3d7a207
v0.8.7 - Comic Metadata Downloading, Reading Profiles, Browse by Genre and More (#3888) 2025-07-05 12:51:19 -07:00
Weblate (bot)
1389eb6320
[skip ci] Weblate Changes (#3893)
Co-authored-by: Dark77 <Dark77@pobox.sk>
Co-authored-by: Gregory.Open <gregory.open@proton.me>
Co-authored-by: Mateusz <mateuszvx8.96@gmail.com>
Co-authored-by: 안세훈 <on9686@gmail.com>
2025-07-05 12:30:06 -07:00
Weblate (bot)
8deb96cf48
[skip ci] Weblate Changes (#3885)
Co-authored-by: Gregory.Open <gregory.open@proton.me>
2025-07-02 15:38:26 -07:00
Weblate (bot)
ff17908400
[skip ci] Weblate Changes (#3883)
Co-authored-by: Duarte Silva <smallflake@protonmail.com>
Co-authored-by: Gregory.Open <gregory.open@proton.me>
Co-authored-by: Havokdan <havokdan@yahoo.com.br>
Co-authored-by: lin49931104 <a82122794@gmail.com>
2025-06-30 05:20:19 -07:00
28 changed files with 4714 additions and 97 deletions

View file

@ -28,7 +28,7 @@ body:
label: Kavita Version Number - If you don't see your version number listed, please update Kavita and see if your issue still persists.
multiple: false
options:
- 0.8.6.2 - Stable
- 0.8.7 - Stable
- Nightly Testing Branch
validations:
required: true

View file

@ -0,0 +1,178 @@
using API.Helpers;
using Xunit;
namespace API.Tests.Helpers;
public class BookSortTitlePrefixHelperTests
{
[Theory]
[InlineData("The Avengers", "Avengers")]
[InlineData("A Game of Thrones", "Game of Thrones")]
[InlineData("An American Tragedy", "American Tragedy")]
public void TestEnglishPrefixes(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("El Quijote", "Quijote")]
[InlineData("La Casa de Papel", "Casa de Papel")]
[InlineData("Los Miserables", "Miserables")]
[InlineData("Las Vegas", "Vegas")]
[InlineData("Un Mundo Feliz", "Mundo Feliz")]
[InlineData("Una Historia", "Historia")]
public void TestSpanishPrefixes(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("Le Petit Prince", "Petit Prince")]
[InlineData("La Belle et la Bête", "Belle et la Bête")]
[InlineData("Les Misérables", "Misérables")]
[InlineData("Un Amour de Swann", "Amour de Swann")]
[InlineData("Une Vie", "Vie")]
[InlineData("Des Souris et des Hommes", "Souris et des Hommes")]
public void TestFrenchPrefixes(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("Der Herr der Ringe", "Herr der Ringe")]
[InlineData("Die Verwandlung", "Verwandlung")]
[InlineData("Das Kapital", "Kapital")]
[InlineData("Ein Sommernachtstraum", "Sommernachtstraum")]
[InlineData("Eine Geschichte", "Geschichte")]
public void TestGermanPrefixes(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("Il Nome della Rosa", "Nome della Rosa")]
[InlineData("La Divina Commedia", "Divina Commedia")]
[InlineData("Lo Hobbit", "Hobbit")]
[InlineData("Gli Ultimi", "Ultimi")]
[InlineData("Le Città Invisibili", "Città Invisibili")]
[InlineData("Un Giorno", "Giorno")]
[InlineData("Una Notte", "Notte")]
public void TestItalianPrefixes(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("O Alquimista", "Alquimista")]
[InlineData("A Moreninha", "Moreninha")]
[InlineData("Os Lusíadas", "Lusíadas")]
[InlineData("As Meninas", "Meninas")]
[InlineData("Um Defeito de Cor", "Defeito de Cor")]
[InlineData("Uma História", "História")]
public void TestPortuguesePrefixes(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("", "")] // Empty string returns empty
[InlineData("Book", "Book")] // Single word, no change
[InlineData("Avengers", "Avengers")] // No prefix, no change
public void TestNoPrefixCases(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("The", "The")] // Just a prefix word alone
[InlineData("A", "A")] // Just single letter prefix alone
[InlineData("Le", "Le")] // French prefix alone
public void TestPrefixWordAlone(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("THE AVENGERS", "AVENGERS")] // All caps
[InlineData("the avengers", "avengers")] // All lowercase
[InlineData("The AVENGERS", "AVENGERS")] // Mixed case
[InlineData("tHe AvEnGeRs", "AvEnGeRs")] // Random case
public void TestCaseInsensitivity(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("Then Came You", "Then Came You")] // "The" + "n" = not a prefix
[InlineData("And Then There Were None", "And Then There Were None")] // "An" + "d" = not a prefix
[InlineData("Elsewhere", "Elsewhere")] // "El" + "sewhere" = not a prefix (no space)
[InlineData("Lesson Plans", "Lesson Plans")] // "Les" + "son" = not a prefix (no space)
[InlineData("Theory of Everything", "Theory of Everything")] // "The" + "ory" = not a prefix
public void TestFalsePositivePrefixes(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("The ", "The ")] // Prefix with only space after - returns original
[InlineData("La ", "La ")] // Same for other languages
[InlineData("El ", "El ")] // Same for Spanish
public void TestPrefixWithOnlySpaceAfter(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("The Multiple Spaces", " Multiple Spaces")] // Doesn't trim extra spaces from remainder
[InlineData("Le Petit Prince", " Petit Prince")] // Leading space preserved in remainder
public void TestSpaceHandling(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("The The Matrix", "The Matrix")] // Removes first "The", leaves second
[InlineData("A A Clockwork Orange", "A Clockwork Orange")] // Removes first "A", leaves second
[InlineData("El El Cid", "El Cid")] // Spanish version
public void TestRepeatedPrefixes(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("L'Étranger", "L'Étranger")] // French contraction - no space, no change
[InlineData("D'Artagnan", "D'Artagnan")] // Contraction - no space, no change
[InlineData("The-Matrix", "The-Matrix")] // Hyphen instead of space - no change
[InlineData("The.Avengers", "The.Avengers")] // Period instead of space - no change
public void TestNonSpaceSeparators(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("三国演义", "三国演义")] // Chinese - no processing due to CJK detection
[InlineData("한국어", "한국어")] // Korean - not in CJK range, would be processed normally
public void TestCjkLanguages(string inputString, string expected)
{
// NOTE: These don't do anything, I am waiting for user input on if these are needed
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("नमस्ते दुनिया", "नमस्ते दुनिया")] // Hindi - not CJK, processed normally
[InlineData("مرحبا بالعالم", "مرحبا بالعالم")] // Arabic - not CJK, processed normally
[InlineData("שלום עולם", "שלום עולם")] // Hebrew - not CJK, processed normally
public void TestNonLatinNonCjkScripts(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
[Theory]
[InlineData("в мире", "мире")] // Russian "в" (in) - should be removed
[InlineData("на столе", "столе")] // Russian "на" (on) - should be removed
[InlineData("с друзьями", "друзьями")] // Russian "с" (with) - should be removed
public void TestRussianPrefixes(string inputString, string expected)
{
Assert.Equal(expected, BookSortTitlePrefixHelper.GetSortTitle(inputString));
}
}

View file

@ -972,4 +972,27 @@ public class ScannerServiceTests : AbstractDbTest
Assert.Contains(postLib.Series, x => x.Name == "Immoral Guild");
Assert.Contains(postLib.Series, x => x.Name == "Futoku No Guild");
}
[Fact]
public async Task ScanLibrary_SortName_NoPrefix()
{
const string testcase = "Series with Prefix - Book.json";
var library = await _scannerHelper.GenerateScannerData(testcase);
library.RemovePrefixForSortName = true;
UnitOfWork.LibraryRepository.Update(library);
await UnitOfWork.CommitAsync();
var scanner = _scannerHelper.CreateServices();
await scanner.ScanLibrary(library.Id);
var postLib = await UnitOfWork.LibraryRepository.GetLibraryForIdAsync(library.Id, LibraryIncludes.Series);
Assert.NotNull(postLib);
Assert.Equal(1, postLib.Series.Count);
Assert.Equal("The Avengers", postLib.Series.First().Name);
Assert.Equal("Avengers", postLib.Series.First().SortName);
}
}

View file

@ -0,0 +1,3 @@
[
"The Avengers/The Avengers vol 1.pdf"
]

View file

@ -624,6 +624,8 @@ public class LibraryController : BaseApiController
library.AllowScrobbling = dto.AllowScrobbling;
library.AllowMetadataMatching = dto.AllowMetadataMatching;
library.EnableMetadata = dto.EnableMetadata;
library.RemovePrefixForSortName = dto.RemovePrefixForSortName;
library.LibraryFileTypes = dto.FileGroupTypes
.Select(t => new LibraryFileTypeGroup() {FileTypeGroup = t, LibraryId = library.Id})
.Distinct()

View file

@ -70,4 +70,8 @@ public sealed record LibraryDto
/// Allow Kavita to read metadata (ComicInfo.xml, Epub, PDF)
/// </summary>
public bool EnableMetadata { get; set; } = true;
/// <summary>
/// Should Kavita remove sort articles "The" for the sort name
/// </summary>
public bool RemovePrefixForSortName { get; set; } = false;
}

View file

@ -30,6 +30,8 @@ public sealed record UpdateLibraryDto
public bool AllowMetadataMatching { get; init; }
[Required]
public bool EnableMetadata { get; init; }
[Required]
public bool RemovePrefixForSortName { get; init; }
/// <summary>
/// What types of files to allow the scanner to pickup
/// </summary>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace API.Data.Migrations
{
/// <inheritdoc />
public partial class LibraryRemoveSortPrefix : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "RemovePrefixForSortName",
table: "Library",
type: "INTEGER",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "RemovePrefixForSortName",
table: "Library");
}
}
}

View file

@ -1341,6 +1341,9 @@ namespace API.Data.Migrations
b.Property<string>("PrimaryColor")
.HasColumnType("TEXT");
b.Property<bool>("RemovePrefixForSortName")
.HasColumnType("INTEGER");
b.Property<string>("SecondaryColor")
.HasColumnType("TEXT");

View file

@ -52,6 +52,10 @@ public class Library : IEntityDate, IHasCoverImage
/// Should Kavita read metadata files from the library
/// </summary>
public bool EnableMetadata { get; set; } = true;
/// <summary>
/// Should Kavita remove sort articles "The" for the sort name
/// </summary>
public bool RemovePrefixForSortName { get; set; } = false;
public DateTime Created { get; set; }

View file

@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace API.Helpers;
/// <summary>
/// Responsible for parsing book titles "The man on the street" and removing the prefix -> "man on the street".
/// </summary>
/// <remarks>This code is performance sensitive</remarks>
public static class BookSortTitlePrefixHelper
{
private static readonly Dictionary<string, byte> PrefixLookup;
private static readonly Dictionary<char, List<string>> PrefixesByFirstChar;
static BookSortTitlePrefixHelper()
{
var prefixes = new[]
{
// English
"the", "a", "an",
// Spanish
"el", "la", "los", "las", "un", "una", "unos", "unas",
// French
"le", "la", "les", "un", "une", "des",
// German
"der", "die", "das", "den", "dem", "ein", "eine", "einen", "einer",
// Italian
"il", "lo", "la", "gli", "le", "un", "uno", "una",
// Portuguese
"o", "a", "os", "as", "um", "uma", "uns", "umas",
// Russian (transliterated common ones)
"в", "на", "с", "к", "от", "для",
};
// Build lookup structures
PrefixLookup = new Dictionary<string, byte>(prefixes.Length, StringComparer.OrdinalIgnoreCase);
PrefixesByFirstChar = new Dictionary<char, List<string>>();
foreach (var prefix in prefixes)
{
PrefixLookup[prefix] = 1;
var firstChar = char.ToLowerInvariant(prefix[0]);
if (!PrefixesByFirstChar.TryGetValue(firstChar, out var list))
{
list = [];
PrefixesByFirstChar[firstChar] = list;
}
list.Add(prefix);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlySpan<char> GetSortTitle(ReadOnlySpan<char> title)
{
if (title.IsEmpty) return title;
// Fast detection of script type by first character
var firstChar = title[0];
// CJK Unicode ranges - no processing needed for most cases
if ((firstChar >= 0x4E00 && firstChar <= 0x9FFF) || // CJK Unified
(firstChar >= 0x3040 && firstChar <= 0x309F) || // Hiragana
(firstChar >= 0x30A0 && firstChar <= 0x30FF)) // Katakana
{
return title;
}
var firstSpaceIndex = title.IndexOf(' ');
if (firstSpaceIndex <= 0) return title;
var potentialPrefix = title.Slice(0, firstSpaceIndex);
// Fast path: check if first character could match any prefix
firstChar = char.ToLowerInvariant(potentialPrefix[0]);
if (!PrefixesByFirstChar.ContainsKey(firstChar))
return title;
// Only do the expensive lookup if first character matches
if (PrefixLookup.ContainsKey(potentialPrefix.ToString()))
{
var remainder = title.Slice(firstSpaceIndex + 1);
return remainder.IsEmpty ? title : remainder;
}
return title;
}
/// <summary>
/// Removes the sort prefix
/// </summary>
/// <param name="title"></param>
/// <returns></returns>
public static string GetSortTitle(string title)
{
var result = GetSortTitle(title.AsSpan());
return result.ToString();
}
}

View file

@ -207,5 +207,7 @@
"sidenav-stream-only-delete-smart-filter": "Seuls les flux de filtres intelligents peuvent être supprimés de la SideNav",
"dashboard-stream-only-delete-smart-filter": "Seuls les flux de filtres intelligents peuvent être supprimés du tableau de bord",
"smart-filter-name-required": "Nom du filtre intelligent requis",
"smart-filter-system-name": "Vous ne pouvez pas utiliser le nom d'un flux fourni par le système"
"smart-filter-system-name": "Vous ne pouvez pas utiliser le nom d'un flux fourni par le système",
"aliases-have-overlap": "Un ou plusieurs alias se chevauchent avec d'autres personnes et ne peuvent pas être mis à jour",
"generated-reading-profile-name": "Généré à partir de {0}"
}

View file

@ -1,5 +1,5 @@
{
"disabled-account": "Váš účet je zakázaný. Kontaktujte správcu servera.",
"disabled-account": "Váš účet je deaktivovaný. Kontaktujte správcu servera.",
"register-user": "Niečo sa pokazilo pri registrácii užívateľa",
"confirm-email": "Najprv musíte potvrdiť svoj e-mail",
"locked-out": "Boli ste zamknutí z dôvodu veľkého počtu neúspešných pokusov o prihlásenie. Počkajte 10 minút.",
@ -88,5 +88,126 @@
"generic-device-create": "Pri vytváraní zariadenia sa vyskytla chyba",
"series-doesnt-exist": "Séria neexistuje",
"volume-doesnt-exist": "Zväzok neexistuje",
"library-name-exists": "Názov knižnice už existuje. Prosím, vyberte si pre daný server jedinečný názov."
"library-name-exists": "Názov knižnice už existuje. Prosím, vyberte si pre daný server jedinečný názov.",
"cache-file-find": "Nepodarilo sa nájsť obrázok vo vyrovnávacej pamäti. Znova načítajte a skúste to znova.",
"name-required": "Názov nemôže byť prázdny",
"valid-number": "Musí to byť platné číslo strany",
"duplicate-bookmark": "Duplicitný záznam záložky už existuje",
"reading-list-permission": "Nemáte povolenia na tento zoznam na čítanie alebo zoznam neexistuje",
"reading-list-position": "Nepodarilo sa aktualizovať pozíciu",
"reading-list-updated": "Aktualizované",
"reading-list-item-delete": "Položku(y) sa nepodarilo odstrániť",
"reading-list-deleted": "Zoznam na čítanie bol odstránený",
"generic-reading-list-delete": "Pri odstraňovaní zoznamu na čítanie sa vyskytol problém",
"generic-reading-list-update": "Pri aktualizácii zoznamu na čítanie sa vyskytol problém",
"generic-reading-list-create": "Pri vytváraní zoznamu na čítanie sa vyskytol problém",
"reading-list-doesnt-exist": "Zoznam na čítanie neexistuje",
"series-restricted": "Používateľ nemá prístup k tejto sérii",
"generic-scrobble-hold": "Pri pauznutí funkcie sa vyskytla chyba",
"libraries-restricted": "Používateľ nemá prístup k žiadnym knižniciam",
"no-series": "Nepodarilo sa získať sériu pre knižnicu",
"no-series-collection": "Nepodarilo sa získať sériu pre kolekciu",
"generic-series-delete": "Pri odstraňovaní série sa vyskytol problém",
"generic-series-update": "Pri aktualizácii série sa vyskytla chyba",
"series-updated": "Úspešne aktualizované",
"update-metadata-fail": "Nepodarilo sa aktualizovať metadáta",
"age-restriction-not-applicable": "Bez obmedzenia",
"generic-relationship": "Pri aktualizácii vzťahov sa vyskytol problém",
"job-already-running": "Úloha už beží",
"encode-as-warning": "Nedá sa konvertovať do formátu PNG. Pre obaly použite možnosť Obnoviť obaly. Záložky a favicony sa nedajú spätne zakódovať.",
"ip-address-invalid": "IP adresa „{0}“ je neplatná",
"bookmark-dir-permissions": "Adresár záložiek nemá správne povolenia pre použitie v aplikácii Kavita",
"total-backups": "Celkový počet záloh musí byť medzi 1 a 30",
"total-logs": "Celkový počet protokolov musí byť medzi 1 a 30",
"stats-permission-denied": "Nemáte oprávnenie zobraziť si štatistiky iného používateľa",
"url-not-valid": "URL nevracia platný obrázok alebo vyžaduje autorizáciu",
"url-required": "Na použitie musíte zadať URL adresu",
"generic-cover-series-save": "Obrázok obálky sa nepodarilo uložiť do série",
"generic-cover-collection-save": "Obrázok obálky sa nepodarilo uložiť do kolekcie",
"generic-cover-reading-list-save": "Obrázok obálky sa nepodarilo uložiť do zoznamu na čítanie",
"generic-cover-chapter-save": "Obrázok obálky sa nepodarilo uložiť do kapitoly",
"generic-cover-library-save": "Obrázok obálky sa nepodarilo uložiť do knižnice",
"generic-cover-person-save": "Obrázok obálky sa nepodarilo uložiť k tejto osobe",
"generic-cover-volume-save": "Obrázok obálky sa nepodarilo uložiť do zväzku",
"access-denied": "Nemáte prístup",
"reset-chapter-lock": "Nepodarilo sa resetovať zámok obalu pre kapitolu",
"generic-user-delete": "Používateľa sa nepodarilo odstrániť",
"generic-user-pref": "Pri ukladaní predvolieb sa vyskytol problém",
"opds-disabled": "OPDS nie je na tomto serveri povolený",
"on-deck": "Pokračovať v čítaní",
"browse-on-deck": "Prehliadať pokračovanie v čítaní",
"recently-added": "Nedávno pridané",
"want-to-read": "Chcem čítať",
"browse-want-to-read": "Prehliadať Chcem si prečítať",
"browse-recently-added": "Prehliadať nedávno pridané",
"reading-lists": "Zoznamy na čítanie",
"browse-reading-lists": "Prehliadať podľa zoznamov na čítanie",
"libraries": "Všetky knižnice",
"browse-libraries": "Prehliadať podľa knižníc",
"collections": "Všetky kolekcie",
"browse-collections": "Prehliadať podľa kolekcií",
"more-in-genre": "Viac v žánri {0}",
"browse-more-in-genre": "Prezrite si viac v {0}",
"recently-updated": "Nedávno aktualizované",
"browse-recently-updated": "Prehliadať nedávno aktualizované",
"smart-filters": "Inteligentné filtre",
"external-sources": "Externé zdroje",
"browse-external-sources": "Prehliadať externé zdroje",
"browse-smart-filters": "Prehliadať podľa inteligentných filtrov",
"reading-list-restricted": "Zoznam na čítanie neexistuje alebo k nemu nemáte prístup",
"query-required": "Musíte zadať parameter dopytu",
"search": "Hľadať",
"search-description": "Vyhľadávanie sérií, zbierok alebo zoznamov na čítanie",
"favicon-doesnt-exist": "Favicon neexistuje",
"smart-filter-doesnt-exist": "Inteligentný filter neexistuje",
"smart-filter-already-in-use": "Existuje existujúci stream s týmto inteligentným filtrom",
"dashboard-stream-doesnt-exist": "Stream dashboardu neexistuje",
"sidenav-stream-doesnt-exist": "SideNav Stream neexistuje",
"external-source-already-exists": "Externý zdroj už existuje",
"external-source-required": "Vyžaduje sa kľúč API a Host",
"external-source-doesnt-exist": "Externý zdroj neexistuje",
"external-source-already-in-use": "S týmto externým zdrojom existuje stream",
"sidenav-stream-only-delete-smart-filter": "Z bočného panela SideNav je možné odstrániť iba streamy inteligentných filtrov",
"dashboard-stream-only-delete-smart-filter": "Z ovládacieho panela je možné odstrániť iba streamy inteligentných filtrov",
"smart-filter-name-required": "Názov inteligentného filtra je povinný",
"smart-filter-system-name": "Nemôžete použiť názov streamu poskytnutého systémom",
"not-authenticated": "Používateľ nie je overený",
"unable-to-register-k+": "Licenciu sa nepodarilo zaregistrovať z dôvodu chyby. Kontaktujte podporu Kavita+",
"unable-to-reset-k+": "Licenciu Kavita+ sa nepodarilo resetovať z dôvodu chyby. Kontaktujte podporu Kavita+",
"anilist-cred-expired": "Prihlasovacie údaje AniList vypršali alebo chýbajú",
"scrobble-bad-payload": "Nesprávne údaje od poskytovateľa Scrobblovania",
"theme-doesnt-exist": "Súbor témy chýba alebo je neplatný",
"bad-copy-files-for-download": "Súbory sa nepodarilo skopírovať do dočasného adresára na stiahnutie archívu.",
"generic-create-temp-archive": "Pri vytváraní dočasného archívu sa vyskytla chyba",
"epub-malformed": "Súbor je nesprávne naformátovaný! Nedá sa prečítať.",
"epub-html-missing": "Zodpovedajúci súbor HTML pre túto stránku sa nenašiel",
"collection-tag-title-required": "Názov kolekcie nemôže byť prázdny",
"reading-list-title-required": "Názov zoznamu na čítanie nemôže byť prázdny",
"collection-tag-duplicate": "Kolekcia s týmto názvom už existuje",
"device-duplicate": "Zariadenie s týmto názvom už existuje",
"device-not-created": "Toto zariadenie ešte neexistuje. Najprv ho vytvorte",
"send-to-permission": "Nie je možné odoslať súbory iné ako EPUB alebo PDF na zariadenia, pretože nie sú podporované na Kindle",
"progress-must-exist": "Pokrok musí byť u používateľa k dispozícii",
"reading-list-name-exists": "Zoznam na prečítanie s týmto menom už existuje",
"user-no-access-library-from-series": "Používateľ nemá prístup do knižnice, do ktorej táto séria patrí",
"series-restricted-age-restriction": "Používateľ si nemôže pozrieť túto sériu z dôvodu vekového obmedzenia",
"kavitaplus-restricted": "Toto je obmedzené iba na Kavita+",
"aliases-have-overlap": "Jeden alebo viacero aliasov sa prekrýva s inými osobami, nie je možné ich aktualizovať",
"volume-num": "Zväzok {0}",
"book-num": "Kniha {0}",
"issue-num": "Problém {0}{1}",
"chapter-num": "Kapitola {0}",
"check-updates": "Skontrolovať aktualizácie",
"license-check": "Kontrola licencie",
"process-scrobbling-events": "Udalosti procesu scrobblovania",
"report-stats": "Štatistiky hlásení",
"check-scrobbling-tokens": "Skontrolujte Tokeny Scrobblingu",
"cleanup": "Čistenie",
"process-processed-scrobbling-events": "Spracovať udalosti scrobblovania",
"remove-from-want-to-read": "Upratanie listu Chcem si prečítať",
"scan-libraries": "Skenovanie knižníc",
"kavita+-data-refresh": "Obnovenie údajov Kavita+",
"backup": "Záloha",
"update-yearly-stats": "Aktualizovať ročné štatistiky",
"generated-reading-profile-name": "Vygenerované z {0}"
}

View file

@ -126,13 +126,17 @@ public class ProcessSeries : IProcessSeries
series.Format = firstParsedInfo.Format;
}
var removePrefix = library.RemovePrefixForSortName;
var sortName = removePrefix ? BookSortTitlePrefixHelper.GetSortTitle(series.Name) : series.Name;
if (string.IsNullOrEmpty(series.SortName))
{
series.SortName = series.Name;
series.SortName = sortName;
}
if (!series.SortNameLocked)
{
series.SortName = series.Name;
series.SortName = sortName;
if (!string.IsNullOrEmpty(firstParsedInfo.SeriesSort))
{
series.SortName = firstParsedInfo.SeriesSort;

View file

@ -3,7 +3,7 @@
<TargetFramework>net9.0</TargetFramework>
<Company>kavitareader.com</Company>
<Product>Kavita</Product>
<AssemblyVersion>0.8.6.20</AssemblyVersion>
<AssemblyVersion>0.8.7.1</AssemblyVersion>
<NeutralLanguage>en</NeutralLanguage>
<TieredPGO>true</TieredPGO>
</PropertyGroup>

View file

@ -32,6 +32,7 @@ export interface Library {
allowScrobbling: boolean;
allowMetadataMatching: boolean;
enableMetadata: boolean;
removePrefixForSortName: boolean;
collapseSeriesRelationships: boolean;
libraryFileTypes: Array<FileTypeGroup>;
excludePatterns: Array<string>;

View file

@ -127,6 +127,16 @@
</app-setting-item>
</div>
<div class="row g-0 mt-4 mb-4">
<app-setting-switch [title]="t('remove-prefix-for-sortname-label')" [subtitle]="t('remove-prefix-for-sortname-tooltip')">
<ng-template #switch>
<div class="form-check form-switch float-end">
<input type="checkbox" id="remove-prefix-for-sortname" role="switch" formControlName="removePrefixForSortName" class="form-check-input">
</div>
</ng-template>
</app-setting-switch>
</div>
<div class="row g-0 mt-4 mb-4">
<app-setting-switch [title]="t('enable-metadata-label')" [subtitle]="t('enable-metadata-tooltip')">
<ng-template #switch>

View file

@ -115,6 +115,7 @@ export class LibrarySettingsModalComponent implements OnInit {
allowMetadataMatching: new FormControl<boolean>(true, { nonNullable: true, validators: [] }),
collapseSeriesRelationships: new FormControl<boolean>(false, { nonNullable: true, validators: [] }),
enableMetadata: new FormControl<boolean>(true, { nonNullable: true, validators: [] }), // required validator doesn't check value, just if true
removePrefixForSortName: new FormControl<boolean>(false, { nonNullable: true, validators: [] }),
});
selectedFolders: string[] = [];
@ -273,7 +274,8 @@ export class LibrarySettingsModalComponent implements OnInit {
this.libraryForm.get('allowScrobbling')?.setValue(this.IsKavitaPlusEligible ? this.library.allowScrobbling : false);
this.libraryForm.get('allowMetadataMatching')?.setValue(this.IsMetadataDownloadEligible ? this.library.allowMetadataMatching : false);
this.libraryForm.get('excludePatterns')?.setValue(this.excludePatterns ? this.library.excludePatterns : false);
this.libraryForm.get('enableMetadata')?.setValue(this.library.enableMetadata, true);
this.libraryForm.get('enableMetadata')?.setValue(this.library.enableMetadata);
this.libraryForm.get('removePrefixForSortName')?.setValue(this.library.removePrefixForSortName);
this.selectedFolders = this.library.folders;
this.madeChanges = false;

View file

@ -1131,6 +1131,8 @@
"include-in-search-tooltip": "Should series and any derived information (genres, people, files) from the library be included in search results.",
"enable-metadata-label": "Enable Metadata (ComicInfo/Epub/PDF)",
"enable-metadata-tooltip": "Allow Kavita to read metadata files which override filename parsing.",
"remove-prefix-for-sortname-label": "Remove common prefixes for Sort Name",
"remove-prefix-for-sortname-tooltip": "Kavita will remove common prefixes like 'The', 'A', 'An' from titles for sort name. Does not override set metadata.",
"force-scan": "Force Scan",
"force-scan-tooltip": "This will force a scan on the library, treating like a fresh scan",
"reset": "{{common.reset}}",

View file

@ -50,7 +50,9 @@
"special": "{{entity-title.special}}",
"token-expired": "Votre jeton AniList a expiré! Les événements de scrobbling ne seront pas pris en compte tant que vous n'aurez pas renouvelé votre compte sur la page Comptes.",
"scrobbling-disabled": "Le suivi de lecture est désactivé dans les paramètres de votre compte.",
"generate-scrobble-events": "Rattraper les Événements"
"generate-scrobble-events": "Rattraper les Événements",
"select-all-label": "Sélectionner tout",
"delete-selected-label": "Supprimer la sélection"
},
"scrobble-event-type-pipe": {
"chapter-read": "Progression de la lecture",
@ -83,7 +85,7 @@
},
"user-preferences": {
"title": "Tableau de bord Utilisateur",
"pref-description": "Voici les paramètres globaux liés à votre compte.",
"pref-description": "Voici les paramètres globaux liés à votre compte. Les paramètres du lecteur se trouvent dans les profils de lecture.",
"account-tab": "{{tabs.account-tab}}",
"preferences-tab": "{{tabs.preferences-tab}}",
"theme-tab": "{{tabs.theme-tab}}",
@ -629,7 +631,10 @@
"incognito-mode-label": "Navigation privée",
"next": "Suivant",
"previous": "Précédent",
"go-to-page-prompt": "Il y a {{totalPages}} pages. À quelle page voulez-vous aller ?"
"go-to-page-prompt": "Il y a {{totalPages}} pages. À quelle page voulez-vous aller ?",
"go-to-first-page": "Aller à la première page",
"go-to-section": "Aller à la section",
"go-to-section-prompt": "Il y a {{totalSections}} sections au total. Dans quelle section voulez-vous aller?"
},
"personal-table-of-contents": {
"no-data": "Rien n'a encore été mis en marque-page",
@ -655,7 +660,7 @@
"success": "Succès !"
},
"confirm-reset-password": {
"title": "Réinitialisation du mot de passe",
"title": "Réinitialiser le mot de passe",
"description": "Saisir un nouveau mot de passe",
"password-label": "{{common.password}}",
"required-field": "{{validation.required-field}}",
@ -677,7 +682,7 @@
"series-detail": {
"page-settings-title": "Paramètres des pages",
"close": "{{common.close}}",
"layout-mode-label": "{{user-preferences.layout-mode-book-label}}",
"layout-mode-label": "{{manage-reading-profiles.layout-mode-book-label}}",
"layout-mode-option-card": "Carte",
"layout-mode-option-list": "Liste",
"continue-from": "Continuer {{title}}",
@ -728,7 +733,7 @@
"more-alt": "Plus",
"time-left-alt": "Temps restant",
"time-to-read-alt": "{{sort-field-pipe.time-to-read}}",
"scrobbling-tooltip": "{{settings.scrobbling}}: {{value}}",
"scrobbling-tooltip": "{{settings.scrobbling}} : {{value}}",
"publication-status-title": "Publication",
"publication-status-tooltip": "État de la publication",
"on": "{{reader-settings.on}}",
@ -764,7 +769,8 @@
"entry-label": "Voir les détails",
"kavita-tooltip": "Votre évaluation + évaluation globale",
"kavita-rating-title": "Votre évaluation",
"close": "{{common.close}}"
"close": "{{common.close}}",
"critic": "{{review-card.critic}}"
},
"badge-expander": {
"more-items": "et {{count}} de plus"
@ -800,7 +806,8 @@
"more": "Plus",
"customize": "{{settings.customize}}",
"edit": "{{common.edit}}",
"cancel-edit": "Fermer la réorganisation"
"cancel-edit": "Fermer la réorganisation",
"browse-people": "Parcourir les personnes"
},
"library-settings-modal": {
"close": "{{common.close}}",
@ -853,7 +860,9 @@
"exclude-patterns-tooltip": "Configurez un ensemble de modèles (syntaxe Global) que Kavita fera correspondre lors du scan des répertoires et exclura des résultats du scanner.",
"help": "{{common.help}}",
"allow-metadata-matching-label": "Permettre la correspondance des métadonnées",
"allow-metadata-matching-tooltip": "Kavita doit-il télécharger les métadonnées des séries de cette bibliothèque? Cela ne se produira que si le serveur dispose d'un abonnement actif à Kavita+."
"allow-metadata-matching-tooltip": "Kavita doit-il télécharger les métadonnées des séries de cette bibliothèque? Cela ne se produira que si le serveur dispose d'un abonnement actif à Kavita+.",
"enable-metadata-label": "Activer les métadonnées (ComicInfo/Epub/PDF)",
"enable-metadata-tooltip": "Permet à Kavita de lire les fichiers de métadonnées. Ceux-ci remplacent l'analyse des noms de fichiers."
},
"file-type-group-pipe": {
"archive": "Archive",
@ -863,30 +872,30 @@
},
"reader-settings": {
"general-settings-title": "Réglages généraux",
"font-family-label": "{{user-preferences.font-family-label}}",
"font-size-label": "{{user-preferences.font-size-book-label}}",
"line-spacing-label": "{{user-preferences.line-height-book-label}}",
"margin-label": "{{user-preferences.margin-book-label}}",
"font-family-label": "{{manage-reading-profiles.font-family-label}}",
"font-size-label": "{{manage-reading-profiles.font-size-book-label}}",
"line-spacing-label": "{{manage-reading-profiles.line-height-book-label}}",
"margin-label": "{{manage-reading-profiles.margin-book-label}}",
"reset-to-defaults": "Réinitialiser les paramètres par défaut",
"reader-settings-title": "Paramètres de lecture",
"reading-direction-label": "{{user-preferences.reading-direction-book-label}}",
"reading-direction-label": "{{manage-reading-profiles.reading-direction-book-label}}",
"right-to-left": "De droite à gauche",
"left-to-right": "De gauche à droite",
"horizontal": "Horizontal",
"vertical": "Vertical",
"writing-style-label": "{{user-preferences.writing-style-label}}",
"writing-style-label": "{{manage-reading-profiles.writing-style-label}}",
"writing-style-tooltip": "Change la direction du texte. L'horizontale est de gauche à droite, la verticale de haut en bas.",
"tap-to-paginate-label": "Appuyez sur Pagination",
"tap-to-paginate-tooltip": "Cliquez sur les bords de l'écran pour paginer",
"on": "Activé",
"off": "Désactivé",
"immersive-mode-label": "{{user-preferences.immersive-mode-label}}",
"immersive-mode-label": "{{manage-reading-profiles.immersive-mode-label}}",
"immersive-mode-tooltip": "Cela masquera le menu après un clic sur le document en lecture et activera le toucher pour lister les pages",
"fullscreen-label": "Plein écran",
"fullscreen-tooltip": "Mettre le lecteur en plein écran",
"exit": "Sortir",
"enter": "Entrer",
"layout-mode-label": "{{user-preferences.layout-mode-book-label}}",
"layout-mode-label": "{{manage-reading-profiles.layout-mode-book-label}}",
"layout-mode-tooltip": "Défilement: met en miroir le fichier epub (généralement une longue page défilante par chapitre).<br/>1 colonne: crée une seule page virtuelle à la fois.<br/>2 colonnes: crée deux pages virtuelles à la fois disposées côte à côte.",
"layout-mode-option-scroll": "Faire défiler",
"layout-mode-option-1col": "1 Colonne",
@ -895,7 +904,15 @@
"theme-dark": "Sombre",
"theme-black": "Noir",
"theme-white": "Blanc",
"theme-paper": "Papier"
"theme-paper": "Papier",
"update-parent": "Enregistrer dans {{name}}",
"loading": "chargement",
"create-new": "Nouveau profil à partir d'un profil implicite",
"create-new-tooltip": "Créez un nouveau profil gérable à partir de votre profil implicite actuel",
"reading-profile-updated": "Profil de lecture mis à jour",
"reading-profile-promoted": "Profil de lecture promu",
"line-spacing-min-label": "1x",
"line-spacing-max-label": "2.5x"
},
"table-of-contents": {
"no-data": "Ce livre n'a pas de table des matières définie dans les métadonnées ou dans un fichier toc"
@ -1336,7 +1353,8 @@
"admin-email-history": "Historique des e-mails",
"admin-matched-metadata": "Métadonnées correspondantes",
"admin-manage-tokens": "Gérer les jetons utilisateur",
"admin-metadata": "Gérer les métadonnées"
"admin-metadata": "Gérer les métadonnées",
"reading-profiles": "Profils de lecture"
},
"collection-detail": {
"no-data": "Il n'y a pas d'éléments. Essayez d'ajouter une série.",
@ -1460,7 +1478,10 @@
"logout": "Déconnexion",
"all-filters": "Filtres intelligents",
"nav-link-header": "Options de navigation",
"close": "{{common.close}}"
"close": "{{common.close}}",
"person-aka-status": "Correspond à un alias",
"browse-genres": "Parcourir les genres",
"browse-tags": "Parcourir les étiquettes"
},
"promoted-icon": {
"promoted": "{{common.promoted}}"
@ -1592,9 +1613,9 @@
"height": "Hauteur",
"width": "Largeur",
"width-override-label": "Remplacement de la largeur",
"off": "Désactivé",
"off": "{{reader-settings.off}}",
"original": "Original",
"auto-close-menu-label": "{{user-preferences.auto-close-menu-label}}",
"auto-close-menu-label": "{{manage-reading-profiles.auto-close-menu-label}}",
"swipe-enabled-label": "Balayage activé",
"enable-comic-book-label": "Imiter le comportement de la bande dessinée",
"brightness-label": "Luminosité",
@ -1606,7 +1627,13 @@
"no-next-chapter": "Pas de prochain chapitre",
"no-prev-chapter": "Pas de chapitre précédent",
"emulate-comic-book-label": "{{manage-reading-profiles.emulate-comic-book-label}}",
"series-progress": "Progression de la série : {{percentage}}"
"series-progress": "Progression de la série : {{percentage}}",
"update-parent": "{{reader-settings.update-parent}}",
"loading": "{{reader-settings.loading}}",
"create-new": "{{reader-settings.create-new}}",
"create-new-tooltip": "{{reader-settings.create-new-tooltip}}",
"reading-profile-updated": "Profil de lecture mis à jour",
"reading-profile-promoted": "Profil de lecture promu"
},
"metadata-filter": {
"filter-title": "{{common.filter}}",
@ -1663,7 +1690,10 @@
"release-year": "Année de sortie",
"read-progress": "Dernière lecture",
"average-rating": "Note moyenne",
"random": "Aléatoire"
"random": "Aléatoire",
"person-name": "Nom",
"person-series-count": "Nombre de séries",
"person-chapter-count": "Nombre de chapitres"
},
"edit-series-modal": {
"title": "{{seriesName}} Détails",
@ -1800,8 +1830,8 @@
"cover-image-tab": "{{tabs.cover-tab}}",
"tasks-tab": "{{tabs.tasks-tab}}",
"info-tab": "{{tabs.info-tab}}",
"pages-label": "{{edit-chapter-modal.pages-count}}",
"words-label": "{{edit-chapter-modal.length-title}}",
"pages-label": "{{edit-chapter-modal.pages-label}}",
"words-label": "{{edit-chapter-modal.words-label}}",
"pages-count": "{{edit-chapter-modal.pages-count}}",
"words-count": "{{edit-chapter-modal.words-count}}",
"reading-time-label": "{{edit-chapter-modal.reading-time-label}}",
@ -2022,7 +2052,7 @@
"reading-lists": "{{side-nav.reading-lists}}",
"bookmarks": "{{side-nav.bookmarks}}",
"all-series": "{{side-nav.all-series}}",
"browse-authors": "{{side-nav.browse-authors}}"
"browse-authors": "{{side-nav.browse-people}}"
},
"filter-field-pipe": {
"age-rating": "{{metadata-fields.age-rating-title}}",
@ -2141,7 +2171,7 @@
"load-prev-chapter": "Précédent(e) {{entity}} chargé(e)",
"account-registration-complete": "Enregistrement du compte terminé",
"account-migration-complete": "Migration des comptes terminée",
"password-reset": "Réinitialisation du mot de passe",
"password-reset": "Réinitialiser le mot de passe",
"password-updated": "Le mot de passe a été mis à jour",
"forced-scan-queued": "Une recherche forcée a été lancée pour {{name}}",
"library-created": "Bibliothèque créée avec succès. Un scan a été lancé.",
@ -2196,7 +2226,12 @@
"bulk-delete-libraries": "Êtes vous sûr de vouloir supprimer {{count}} bibliothèque(s)?",
"webtoon-override": "Passage en mode Webtoon en raison d'images représentant un webtoon.",
"match-success": "Séries avec la bonne correspondance",
"scrobble-gen-init": "Mise en attente d'une tâche pour générer des événements de scrobble à partir de l'historique de lecture et des évaluations, en les synchronisant avec les services connectés."
"scrobble-gen-init": "Mise en attente d'une tâche pour générer des événements de scrobble à partir de l'historique de lecture et des évaluations, en les synchronisant avec les services connectés.",
"series-added-want-to-read": "Série ajoutée à la liste \"A lire\"",
"confirm-delete-multiple-volumes": "Êtes-vous sûr de vouloir supprimer les {{count}} volumes? Cela ne modifiera pas les fichiers sur le disque.",
"series-bound-to-reading-profile": "Série liée au Profil de lecture {{nom}}",
"library-bound-to-reading-profile": "Bibliothèque liée au Profil de lecture {{nom}}",
"external-match-rate-error": "Kavita a pris trop de temps en cherchant {{seriesName}}. Réessayez dans 5 minutes."
},
"read-time-pipe": {
"less-than-hour": "<1 Heure",
@ -2269,7 +2304,16 @@
"copy-settings": "Copier les paramètres depuis",
"match-tooltip": "Associer les séries manuellement avec Kavita+",
"match": "Correspondance",
"reorder": "Réorganiser"
"reorder": "Réorganiser",
"reading-profiles": "Profils de lecture",
"set-reading-profile": "Définir le profil de lecture",
"set-reading-profile-tooltip": "Lier un profil de lecture à cette bibliothèque",
"clear-reading-profile": "Effacer le Profil de lecture",
"clear-reading-profile-tooltip": "Efface le Profil de lecture pour cette bibliothèque",
"cleared-profile": "Profil de lecture effacé",
"rename": "Renommer",
"rename-tooltip": "Renommer le filtre intelligent",
"merge": "Fusionner"
},
"preferences": {
"left-to-right": "De gauche à droite",
@ -2388,14 +2432,16 @@
"volume-nums": "Volumes",
"author-count": "{{num}} Auteurs",
"chapter-count": "{{num}} chapitres",
"no-data": "Aucune donnée"
"no-data": "Aucune donnée",
"issue-count": "{{num}} Numéros"
},
"confirm": {
"alert": "Alerte",
"confirm": "Confirmer",
"ok": "Ok",
"cancel": "{{common.cancel}}",
"info": "Info"
"info": "Info",
"prompt": "Question"
},
"person-detail": {
"all-roles": "Roles",
@ -2403,7 +2449,9 @@
"known-for-title": "Connu pour",
"individual-role-title": "En tant que {{role}}",
"browse-person-title": "Toutes les œuvres de {{name}}",
"anilist-url": "{{edit-person-modal.anilist-tooltip}}"
"anilist-url": "{{edit-person-modal.anilist-tooltip}}",
"aka-title": "Également connu sous le nom de ",
"no-info": "Aucune information sur cette personne"
},
"edit-person-modal": {
"save": "{{common.save}}",
@ -2426,7 +2474,11 @@
"required-field": "{{validations.required-field}}",
"cover-image-description": "{{edit-series-modal.cover-image-description}}",
"cover-image-description-extra": "Vous pouvez également télécharger une couverture à partir de CoversDB, si elle est disponible.",
"download-coversdb": "Télécharger à partir de CoversDB"
"download-coversdb": "Télécharger à partir de CoversDB",
"aliases-tab": "Alias",
"aliases-label": "Modifier les alias",
"alias-overlap": "Cet alias pointe déjà vers une autre personne ou est le nom de cette personne, envisagez de les fusionner.",
"aliases-tooltip": "Lorsqu'une série est étiquetée avec l'alias d'une personne, cette personne est attribuée plutôt que d'en créer une nouvelle. Lorsque vous supprimez un alias, vous devez rescanner la série pour que la modification soit prise en compte."
},
"changelog-update-item": {
"added": "Ajouté",
@ -2447,7 +2499,7 @@
"description": "Sélectionnez une correspondance pour recâbler les métadonnées de Kavita+ et régénérer les événements de scrobbling. L'option Ne pas faire correspondre peut être utilisée pour empêcher Kavita de faire correspondre les métadonnées et le scrobbler.",
"close": "{{common.close}}",
"save": "{{common.save}}",
"query-tooltip": "Entrez le nom de la série, l'URL AniList/MyAnimeList. Les URL utiliseront une recherche directe.",
"query-tooltip": "Entrez le nom de la série, l'URL AniList/MyAnimeList/ComicBookRoundup. Les URL utiliseront une recherche directe.",
"dont-match-tooltip": "Exclure cette série de la correspondance et du scrobbling",
"dont-match-label": "Ne pas correspondre",
"search": "Recherche",
@ -2492,7 +2544,9 @@
"library-name-header": "Bibliothèque",
"match-alt": "Correspondance {{seriesName}}",
"actions-header": "Actions",
"dont-match-status-label": "{{dont-match-label}}"
"dont-match-status-label": "{{dont-match-label}}",
"library-type": "Type de bibliothèque",
"matched-state-label": "État de correspondance"
},
"manage-metadata-settings": {
"enable-relations-label": "Relations",
@ -2538,14 +2592,21 @@
"enable-chapter-title-label": "Titre",
"enable-chapter-release-date-label": "Date de diffusion",
"enable-chapter-summary-tooltip": "{{manage-metadata-settings.summary-tooltip}}",
"enable-chapter-summary-label": "{{manage-metadata-settings.summary-label}}"
"enable-chapter-summary-label": "{{manage-metadata-settings.summary-label}}",
"enable-chapter-release-date-tooltip": "Permettre la saisie de la date de publication d'un chapitre ou d'un numéro",
"enable-chapter-publisher-label": "Éditeur",
"enable-chapter-publisher-tooltip": "Permettre la saisie de l'éditeur des chapitres ou des numéros",
"enable-chapter-cover-label": "Couverture du chapitre",
"chapter-header": "Champs du chapitre",
"enable-chapter-cover-tooltip": "Permettre de définir la couverture d'un chapitre ou d'un numéro"
},
"match-series-result-item": {
"chapter-count": "{{common.chapter-count}}",
"updating-metadata-status": "Mise à jour des métadonnées",
"volume-count": "{{server-stats.volume-count}}",
"releasing": "Sorties",
"details": "Voir la page"
"details": "Voir la page",
"issue-count": "{{common.issue-count}}"
},
"metadata-setting-field-pipe": {
"age-rating": "{{metadata-fields.age-rating-title}}",
@ -2556,7 +2617,12 @@
"summary": "{{filter-field-pipe.summary}}",
"publication-status": "{{edit-series-modal.publication-status-title}}",
"tags": "{{metadata-fields.tags-title}}",
"localized-name": "{{edit-series-modal.localized-name-label}}"
"localized-name": "{{edit-series-modal.localized-name-label}}",
"chapter-release-date": "Date de publication (Chapitre)",
"chapter-summary": "Résumé (Chapitre)",
"chapter-covers": "Couvertures (Chapitre)",
"chapter-publisher": "{{person-role-pipe.publisher}} (Chapitre)",
"chapter-title": "Titre (Chapitre)"
},
"email-history": {
"not-sent-tooltip": "Non envoyé",
@ -2597,5 +2663,155 @@
"review-label": "Avis",
"title": "Editer Avis",
"min-length": "L'avis doit faire au moins {{count}} caractères"
},
"browse-people": {
"title": "Parcourir les personnes",
"author-count": "{{num}} Personnes",
"cover-image-description": "{{edit-series-modal.cover-image-description}}",
"issue-count": "{{common.issue-count}}",
"series-count": "{{common.series-count}}",
"roles-label": "Rôles",
"sort-label": "Trier",
"name-label": "Nom",
"issue-count-label": "Nombre de numéros",
"series-count-label": "Nombre de séries"
},
"browse-genres": {
"title": "Parcourir les genres",
"genre-count": "{{num}} Genres",
"issue-count": "{{common.issue-count}}",
"series-count": "{{common.series-count}}"
},
"browse-tags": {
"title": "Parcourir les étiquettes",
"genre-count": "{{num}} Etiquettes",
"issue-count": "{{common.issue-count}}",
"series-count": "{{common.series-count}}"
},
"bulk-set-reading-profile-modal": {
"title": "Définir le profil de lecture",
"close": "{{common.close}}",
"filter-label": "{{common.filter}}",
"clear": "{{common.clear}}",
"no-data": "Aucune collection n'a encore été créée",
"loading": "{{common.loading}}",
"create": "{{common.create}}",
"bound": "Liaison"
},
"merge-person-modal": {
"title": "{{personName}}",
"close": "{{common.close}}",
"save": "{{common.save}}",
"src": "Fusionner une personne",
"merge-warning": "Si vous poursuivez, la personne sélectionnée sera supprimée. Le nom de la personne sélectionnée sera ajouté en tant qu'alias et tous ses rôles seront transférés.",
"alias-title": "Nouveaux alias",
"known-for-title": "Connu pour"
},
"browse-title-pipe": {
"publication-status": "{{value}} travaux",
"age-rating": "Noté {{value}}",
"user-rating": "{{value}} classement par étoiles",
"tag": "Étiquette {{value}}",
"translator": "Traduit par {{value}}",
"character": "Possède le caractère {{value}}",
"publisher": "Publié par {{value}}",
"editor": "Edité par {{value}}",
"artist": "Dessiné par {{value}}",
"letterer": "Lettré par {{value}}",
"colorist": "Coloré par {{value}}",
"inker": "Encré par {{value}}",
"penciller": "Crayonné par {{value}}",
"writer": "Ecrit par {{value}}",
"genre": "Genre {{value}}",
"library": "Au sein de la bibliothèque {{value}}",
"format": "Format de {{value}}",
"release-year": "Publié en {{value}}",
"imprint": "Empreinte de {{value}}",
"team": "Équipe {{value}}",
"location": "Localisation {{value}}"
},
"generic-filter-field-pipe": {
"person-role": "Rôle",
"person-name": "Nom",
"person-series-count": "Nombre de séries",
"person-chapter-count": "Nombre de chapitres"
},
"breakpoint-pipe": {
"never": "Jamais",
"mobile": "Mobile",
"tablet": "Tablette",
"desktop": "Bureau"
},
"manage-reading-profiles": {
"description": "Toutes vos séries ne peuvent pas être lues de la même manière, établissez des profils de lecture distincts par bibliothèque ou par série pour vous permettre de vous replonger dans vos séries aussi facilement que possible.",
"extra-tip": "Attribuez des profils de lecture via le menu d'action sur les séries et les bibliothèques, ou en vrac. Lorsque vous modifiez les paramètres d'une liseuse, un profil caché est créé pour mémoriser vos choix pour cette série (pas pour les pdf). Ce profil est supprimé lorsque vous attribuez l'un de vos propres profils de lecture à la série. Pour plus d'informations, consultez la page",
"profiles-title": "Vos profils de lecture",
"default-profile": "Défaut",
"add-tooltip": "Votre nouveau profil sera sauvegardé après avoir été modifié",
"make-default": "Défini comme valeur par défaut",
"no-selected": "Aucun profil sélectionné",
"confirm": "Êtes-vous sûr de vouloir supprimer le profil de lecture {{name}}?",
"selection-tip": "Sélectionnez un profil dans la liste ou créez-en un nouveau en haut à droite",
"image-reader-settings-title": "Lecteur d'images",
"reading-direction-label": "Sens de lecture",
"reading-direction-tooltip": "Sens dans lequel il faut cliquer pour passer à la page suivante. De droite à gauche signifie que vous cliquez sur le côté gauche de l'écran pour passer à la page suivante.",
"scaling-option-label": "Options de mise à l'échelle",
"scaling-option-tooltip": "Comment adapter l'image à votre écran.",
"page-splitting-label": "Fractionnement des pages",
"page-splitting-tooltip": "Comment diviser une image en pleine largeur (signifie que les images de gauche et de droite sont combinées)",
"reading-mode-label": "Mode lecture",
"reading-mode-tooltip": "Modifier le lecteur pour qu'il soit paginé verticalement, horizontalement ou qu'il ait un défilement infini",
"layout-mode-label": "Mode de présentation",
"layout-mode-tooltip": "Rendre une seule image à l'écran ou deux images côte à côte",
"background-color-label": "Couleur de fond",
"background-color-tooltip": "Couleur d'arrière-plan du lecteur d'images",
"auto-close-menu-label": "Menu de fermeture automatique",
"auto-close-menu-tooltip": "Le menu doit-il se fermer automatiquement",
"show-screen-hints-label": "Afficher les conseils à l'écran",
"show-screen-hints-tooltip": "Afficher une superposition pour aider à comprendre la zone et le sens de pagination",
"emulate-comic-book-label": "S'inspirer de la bande dessinée",
"emulate-comic-book-tooltip": "Applique un effet d'ombre pour imiter la lecture d'un livre",
"add": "{{common.add}}",
"wiki-title": "wiki",
"swipe-to-paginate-label": "Balayer pour paginer",
"swipe-to-paginate-tooltip": "Le balayage de l'écran doit-il déclencher l'affichage de la page suivante ou précédente",
"allow-auto-webtoon-reader-label": "Mode de lecture automatique des webtoons",
"allow-auto-webtoon-reader-tooltip": "Passez en mode \"Webtoon Reader\" si les pages ressemblent à un webtoon. Des faux positifs peuvent se produire.",
"width-override-label": "{{manga-reader.width-override-label}}",
"width-override-tooltip": "Remplacer la largeur des images dans le lecteur",
"disable-width-override-label": "Désactiver la surcharge de la largeur",
"reset": "{{common.reset}}",
"disable-width-override-tooltip": "Empêcher la surcharge de la largeur de prendre effet lorsque l'écran est plus petit ou égal au point de rupture configuré",
"book-reader-settings-title": "Lecteur de livres",
"tap-to-paginate-label": "Tapez pour paginer",
"tap-to-paginate-tooltip": "Les côtés de l'écran du lecteur de livres devraient-ils permettre d'appuyer dessus pour passer à la page précédente/suivante",
"immersive-mode-label": "Mode immersif",
"immersive-mode-tooltip": "Cela permet de masquer le menu derrière un clic sur le document de lecture et d'activer la fonction de pagination",
"reading-direction-book-label": "Sens de lecture",
"reading-direction-book-tooltip": "Sens dans lequel cliquer pour passer à la page suivante. De droite à gauche signifie que vous cliquez sur le côté gauche de l'écran pour passer à la page suivante.",
"font-family-label": "Famille de polices",
"font-family-tooltip": "Famille de polices à charger. Défaut chargera la police par défaut du livre",
"writing-style-label": "Style d'écriture",
"writing-style-tooltip": "Change la direction du texte. L'horizontale va de gauche à droite, la verticale va de haut en bas.",
"layout-mode-book-label": "Mode de présentation",
"layout-mode-book-tooltip": "Comment le contenu doit être présenté. Le défilement correspond à l'emballage du livre. 1 ou 2 colonnes s'adapte à la hauteur de l'appareil et contient 1 ou 2 colonnes de texte par page",
"color-theme-book-label": "Thème de couleur",
"color-theme-book-tooltip": "Quel thème de couleur appliquer au contenu et au menu du lecteur de livres",
"font-size-book-label": "Taille de la police",
"font-size-book-tooltip": "Pourcentage de l'échelle à appliquer à la police dans le livre",
"line-height-book-label": "Espacement des lignes",
"line-height-book-tooltip": "Quel est l'espacement entre les lignes du livre",
"margin-book-label": "Marge",
"margin-book-tooltip": "L'espacement de chaque côté de l'écran. Ce paramètre est remplacé par 0 sur les appareils mobiles, quel que soit ce paramètre.",
"pdf-reader-settings-title": "Lecteur PDF",
"pdf-scroll-mode-label": "Mode défilement",
"pdf-scroll-mode-tooltip": "Mode de défilement des pages. Vertical/Horizontal et Taper pour paginer (pas de défilement)",
"pdf-spread-mode-label": "Mode d'expansion",
"pdf-spread-mode-tooltip": "Comment les pages doivent être mises en page. Simple ou double (paire/impaire)",
"pdf-theme-label": "Thème",
"pdf-theme-tooltip": "Couleur du thème du lecteur",
"reading-profile-series-settings-title": "Série",
"reading-profile-library-settings-title": "Bibliothèque",
"delete": "{{common.delete}}"
}
}

View file

@ -50,7 +50,9 @@
"special": "{{entity-title.special}}",
"scrobbling-disabled": "계정 설정에서 스크로블링이 비활성화되어 있습니다.",
"generate-scrobble-events": "채우기 이벤트",
"token-expired": "AniList 토큰이 만료되었습니다! 계정 페이지에서 갱신하기 전까지는 Scrobbling 이벤트가 처리되지 않습니다."
"token-expired": "AniList 토큰이 만료되었습니다! 계정 페이지에서 갱신하기 전까지는 Scrobbling 이벤트가 처리되지 않습니다.",
"select-all-label": "모두 선택",
"delete-selected-label": "선택 취소"
},
"scrobble-event-type-pipe": {
"chapter-read": "읽기 진행률",
@ -858,7 +860,8 @@
"exclude-patterns-tooltip": "디렉터리를 스캔할 때 Kavita가 일치시킬 패턴 집합(Glob 구문)을 구성하고, 스캐너 결과에서 제외할 수 있도록 설정하세요.",
"help": "{{common.help}}",
"allow-metadata-matching-tooltip": "Kavita가 이 라이브러리 내의 시리즈에 대한 메타데이터를 다운로드해야 합니까? 이는 서버에 활성 Kavita+ 구독이 있는 경우에만 발생합니다.",
"allow-metadata-matching-label": "메타데이터 일치 허용"
"allow-metadata-matching-label": "메타데이터 일치 허용",
"enable-metadata-label": "메타데이터 활성화 (ComicInfo/Epub/PDF)"
},
"file-type-group-pipe": {
"archive": "아카이브",
@ -2210,7 +2213,8 @@
"webtoon-override": "웹툰을 나타내는 이미지가 있어 웹툰 모드로 전환합니다.",
"match-success": "시리즈가 올바르게 일치함",
"confirm-delete-multiple-volumes": "{{count}}개의 볼륨을 삭제하시겠습니까? 디스크의 파일은 수정되지 않습니다.",
"scrobble-gen-init": "과거 열람 이력 및 평가를 추적하는 이벤트를 생성하여 연결된 서비스와 동기화하는 기능을 작업 예정 목록에 추가하였습니다."
"scrobble-gen-init": "과거 열람 이력 및 평가를 추적하는 이벤트를 생성하여 연결된 서비스와 동기화하는 기능을 작업 예정 목록에 추가하였습니다.",
"series-added-want-to-read": "읽고 싶어요 목록에 추가된 시리즈"
},
"read-time-pipe": {
"less-than-hour": "<1시간",
@ -2285,7 +2289,10 @@
"match-tooltip": "Kavita+에서 시리즈를 수동으로 일치시키기",
"reorder": "정렬 변경",
"rename": "이름 변경",
"rename-tooltip": "스마트 필터 이름 변경"
"rename-tooltip": "스마트 필터 이름 변경",
"reading-profiles": "읽기 프로필",
"set-reading-profile": "읽기 프로필 설정",
"merge": "병합"
},
"preferences": {
"left-to-right": "왼쪽에서 오른쪽",
@ -2654,7 +2661,8 @@
"clear": "{{common.clear}}",
"filter-label": "{{common.filter}}",
"close": "{{common.close}}",
"create": "{{common.create}}"
"create": "{{common.create}}",
"title": "읽기 프로필 설정"
},
"manage-reading-profiles": {
"reset": "{{common.reset}}"

View file

@ -413,7 +413,7 @@
},
"relationship-pipe": {
"adaptation": "Adaptacja",
"alternative-setting": "Alternatywne miejsce akcji",
"alternative-setting": "Alternatywne uniwersum",
"alternative-version": "Alternatywna wersja",
"character": "Postać",
"contains": "Zawiera",
@ -421,18 +421,18 @@
"other": "Inne",
"prequel": "Prequel",
"sequel": "Sequel",
"side-story": "Opowieść poboczna",
"spin-off": "Spin Off",
"parent": "Rodzic",
"edition": "Edycja",
"annual": "Coroczny"
"side-story": "Historia poboczna",
"spin-off": "Spin-off",
"parent": "Główna historia",
"edition": "Wersja wydania",
"annual": "Wydanie roczne"
},
"publication-status-pipe": {
"ongoing": "W trakcie",
"hiatus": "Hiatus",
"completed": "Zakończono",
"hiatus": "Wstrzymano",
"completed": "Zakończono (kompletne)",
"cancelled": "Anulowano",
"ended": "Zakończono"
"ended": "Zakończono (niekompletne)"
},
"person-role-pipe": {
"artist": "Artysta",

View file

@ -85,7 +85,7 @@
},
"user-preferences": {
"title": "Painel do Utilizador",
"pref-description": "Estas definições globais estão ligadas à sua conta. As definições do Leitor estão nos Perfis de Leitura",
"pref-description": "Estas definições globais estão ligadas à sua conta. As definições do Leitor estão nos Perfis de Leitura.",
"account-tab": "{{tabs.account-tab}}",
"preferences-tab": "{{tabs.preferences-tab}}",
"theme-tab": "{{tabs.theme-tab}}",
@ -822,7 +822,7 @@
"library-name-unique": "O nome da biblioteca tem de ser único",
"last-scanned-label": "Último Scan:",
"type-label": "Tipo",
"type-tooltip": "O tipo de biblioteca indica como os nomes dos ficheiros são processados e se o UI mostra Capítulos (Manga) vs Números (BDs). Verifique o wiki para mais detalhes relativamente às diferenças entre os dois tipos de bibliotecas.",
"type-tooltip": "O tipo de biblioteca indica como os nomes dos ficheiros são processados e se o UI mostra Capítulos (Manga) vs Edições (BDs). Verifique o wiki para mais detalhes relativamente às diferenças entre os dois tipos de bibliotecas.",
"kavitaplus-eligible-label": "Kavita+ Elegível",
"kavitaplus-eligible-tooltip": "Suporta as funcionalidades de metadados do Kavita+ ou Scrobbling",
"folder-description": "Adicione pastas à sua biblioteca",
@ -907,7 +907,12 @@
"theme-paper": "Papel",
"update-parent": "Gravar para {{name}}",
"loading": "a carregar",
"create-new": "Novo perfil implícito"
"create-new": "Novo perfil implícito",
"create-new-tooltip": "Crie um novo perfil a partir do seu perfil implícito atual",
"reading-profile-updated": "Perfil de leitura atualizado",
"reading-profile-promoted": "Perfil de leitura promovido",
"line-spacing-min-label": "1x",
"line-spacing-max-label": "2.5x"
},
"table-of-contents": {
"no-data": "Este livro não tem um Indíce definido nos metadados ou um ficheiro toc"
@ -1348,7 +1353,8 @@
"admin-matched-metadata": "Metadados com Correspondência",
"admin-manage-tokens": "Gerir Tokens de Utilizador",
"scrobble-holds": "Pausas de Scrobble",
"admin-metadata": "Gerir Metadados"
"admin-metadata": "Gerir Metadados",
"reading-profiles": "Perfis de Leitura"
},
"collection-detail": {
"no-data": "Não existem itens. Tente adicionar uma série.",
@ -1472,7 +1478,10 @@
"logout": "Terminar Sessão",
"all-filters": "Filtros Inteligentes",
"nav-link-header": "Opções de Navegação",
"close": "{{common.close}}"
"close": "{{common.close}}",
"person-aka-status": "Corresponde um pseudónimo",
"browse-genres": "Explorar Géneros",
"browse-tags": "Explorar Etiquetas"
},
"promoted-icon": {
"promoted": "{{common.promoted}}"
@ -1618,7 +1627,13 @@
"no-next-chapter": "Não há Capítulo Seguinte",
"no-prev-chapter": "Não há Capítulo Anterior",
"emulate-comic-book-label": "{{manage-reading-profiles.emulate-comic-book-label}}",
"series-progress": "Progresso da Série: {{percentage}}"
"series-progress": "Progresso da Série: {{percentage}}",
"update-parent": "{{reader-settings.update-parent}}",
"loading": "{{reader-settings.loading}}",
"create-new": "{{reader-settings.create-new}}",
"create-new-tooltip": "{{reader-settings.create-new-tooltip}}",
"reading-profile-updated": "Perfil de leitura atualizado",
"reading-profile-promoted": "Perfil de leitura promovido"
},
"metadata-filter": {
"filter-title": "{{common.filter}}",
@ -1675,7 +1690,10 @@
"release-year": "Ano de Lançamento",
"read-progress": "Última Leitura",
"average-rating": "Classificação Média",
"random": "Aleatório"
"random": "Aleatório",
"person-name": "Nome",
"person-series-count": "Número de Séries",
"person-chapter-count": "Número de Capítulos"
},
"edit-series-modal": {
"title": "Detalhes de {{seriesName}}",
@ -2208,7 +2226,12 @@
"bulk-delete-libraries": "Tem a certeza que deseja eliminar {{count}} bibliotecas?",
"match-success": "Séries correspondidas com sucesso",
"webtoon-override": "O modo Webtoon vai ser usado porque as imagens representam um webtoon.",
"scrobble-gen-init": "Foi colocada uma tarefa em fila para gerar eventos de scrobble a partir do historial de leitura e classificações existentes, sincronizando-as com os serviços que estão configurados."
"scrobble-gen-init": "Foi colocada uma tarefa em fila para gerar eventos de scrobble a partir do historial de leitura e classificações existentes, sincronizando-as com os serviços que estão configurados.",
"series-added-want-to-read": "Série adicionada da lista Leituras Futuras",
"confirm-delete-multiple-volumes": "Tem a certeza que deseja apagar {{count}} volumes? Os ficheiros em disco não serão alterados.",
"series-bound-to-reading-profile": "Série vinculada ao Perfil de Leitura {{name}}",
"library-bound-to-reading-profile": "Biblioteca vinculada ao Perfil de Leitura {{name}}",
"external-match-rate-error": "O Kavita ficou sem taxa à procura de {{seriesName}}. Tente novamente em 5 minutos."
},
"read-time-pipe": {
"less-than-hour": "<1 Hora",
@ -2281,7 +2304,16 @@
"copy-settings": "Copiar Definições De",
"match": "Correspondência",
"match-tooltip": "Fazer a associação manual das Séries com o Kavita+",
"reorder": "Reordenar"
"reorder": "Reordenar",
"reading-profiles": "Perfis de Leitura",
"set-reading-profile": "Escolher Perfil de Leitura",
"set-reading-profile-tooltip": "Vincular um Perfil de Leitura a esta Biblioteca",
"clear-reading-profile": "Limpar Perfil de Leitura",
"clear-reading-profile-tooltip": "Limpar Perfil de Leitura para esta Biblioteca",
"cleared-profile": "Perfil de Leitura Limpo",
"rename": "Renomear",
"rename-tooltip": "Renomear o Filtro Inteligente",
"merge": "Juntar"
},
"preferences": {
"left-to-right": "Esquerda para Direita",
@ -2386,7 +2418,7 @@
"series-count": "{{num}} Séries",
"item-count": "{{num}} Itens",
"book-num": "Livro",
"issue-hash-num": "Número #",
"issue-hash-num": "Edição #",
"issue-num": "Número",
"chapter-num": "Capítulo",
"volume-num": "Volume",
@ -2395,19 +2427,21 @@
"issue-num-shorthand": "#{{num}}",
"volume-num-shorthand": "Vol {{num}}",
"book-nums": "Livros",
"issue-nums": "Números",
"issue-nums": "Edições",
"chapter-nums": "Capítulos",
"volume-nums": "Volumes",
"author-count": "{{num}} Autores",
"chapter-count": "{{num}} Capítulos",
"no-data": "Sem Dados"
"no-data": "Sem Dados",
"issue-count": "{{num}} Edições"
},
"confirm": {
"alert": "Alerta",
"confirm": "Confirmar",
"cancel": "{{common.cancel}}",
"info": "Informação",
"ok": "Ok"
"ok": "Ok",
"prompt": "Questão"
},
"person-detail": {
"all-roles": "Funções",
@ -2440,7 +2474,11 @@
"cover-image-description-extra": "Em alternativa pode descarregar uma capa a partir do CoversDB, se disponível.",
"anilist-tooltip": "https://anilist.co/staff/{AniListId}/",
"asin-tooltip": "https://www.amazon.com/stores/J.K.-Rowling/author/{ASIN}",
"download-coversdb": "Descarregar de CoversDB"
"download-coversdb": "Descarregar de CoversDB",
"aliases-tab": "Pseudónimos",
"aliases-label": "Editar pseudónimos",
"alias-overlap": "Este pseudónimo refere-se a outra pessoa ou é o nome desta pessoa, considere juntar as duas pessoas.",
"aliases-tooltip": "Quando uma série é etiquetada com o pseudónimo de uma pessoa, essa pessoa é associada à serie em vez de ser criada uma pessoa nova. Quando um pseudónimo for apagado, será necessário voltar a analisar a série para que essa alteração tenha efeito."
},
"changelog-update-item": {
"fixed": "Corrigido",
@ -2569,15 +2607,15 @@
"overrides-label": "Substituições",
"person-roles-label": "Papéis",
"enable-chapter-title-label": "Título",
"enable-chapter-title-tooltip": "Permitir que o Título do Capítulo/Número seja gravado",
"enable-chapter-title-tooltip": "Permitir que o Título do Capítulo/Edição seja gravado",
"enable-chapter-summary-label": "{{manage-metadata-settings.summary-label}}",
"enable-chapter-summary-tooltip": "{{manage-metadata-settings.summary-tooltip}}",
"enable-chapter-release-date-label": "Data de Lançamento",
"enable-chapter-release-date-tooltip": "Permitir que a Data de Lançamento do Capítulo/Número seja gravado",
"enable-chapter-release-date-tooltip": "Permitir que a Data de Lançamento do Capítulo/Edição seja gravado",
"enable-chapter-publisher-label": "Editora",
"enable-chapter-publisher-tooltip": "Permitir que a Editor do Capítulo/Número seja gravado",
"enable-chapter-publisher-tooltip": "Permitir que o Editor do Capítulo/Edição seja gravado",
"enable-chapter-cover-label": "Capa do Capítulo",
"enable-chapter-cover-tooltip": "Permitir que a Capa do Capítulo/Número seja definida",
"enable-chapter-cover-tooltip": "Permitir que a Capa do Capítulo/Editor seja definida",
"chapter-header": "Campos do Capítulo"
},
"metadata-setting-field-pipe": {
@ -2589,7 +2627,12 @@
"localized-name": "{{edit-series-modal.localized-name-label}}",
"publication-status": "{{edit-series-modal.publication-status-title}}",
"covers": "Capas",
"start-date": "{{manage-metadata-settings.enable-start-date-label}}"
"start-date": "{{manage-metadata-settings.enable-start-date-label}}",
"chapter-release-date": "Data de Lançamento (Capítulo)",
"chapter-summary": "Sumário (Capítulo)",
"chapter-covers": "Capas (Capítulo)",
"chapter-publisher": "{{person-role-pipe.publisher}} (Capítulo)",
"chapter-title": "Título (Capítulo)"
},
"role-localized-pipe": {
"admin": "Administrador",
@ -2609,7 +2652,76 @@
"critical": "Crítico"
},
"manage-reading-profiles": {
"reset": "{{common.reset}}"
"reset": "{{common.reset}}",
"description": "Nem todas as séries podem ser lidas da mesma maneira, defina perfis de leitura distintos por biblioteca ou séries para que o regresso às suas séries seja o mais simples possível.",
"extra-tip": "Atribua perfis de leitura a partir do menu de ações nas séries ou bibliotecas, ou em massa. Quando alterar definições num leitor, é criado um perfil escondido que memoriza as suas escolhas para essa série (não se aplica a pdfs). Este perfil é removido quando atribui o seu próprio perfil de leitura à série. Pode encontrar mais informação no",
"wiki-title": "wiki",
"profiles-title": "Os seus perfis de leitura",
"default-profile": "Por Defeito",
"add": "{{common.add}}",
"add-tooltip": "O seu novo perfil será gravado depois de lhe fazer qualquer alteração",
"make-default": "Definir por defeito",
"no-selected": "Nenhum perfil selecionado",
"confirm": "Tem a certeza que deseja eliminar o perfil de leitura {{name}}?",
"selection-tip": "Selecione um perfil da lista ou crie um novo à direita no topo",
"image-reader-settings-title": "Leitor de Imagens",
"reading-direction-label": "Direção de Leitura",
"reading-direction-tooltip": "Direção em que deve clicar para ir para a página seguinte. Direita para Esquerda significa que se clica no lado esquerdo do ecrã para ir para a página seguinte.",
"scaling-option-label": "Opções de Escala",
"scaling-option-tooltip": "Como a imagem é dimensionada no seu ecrã.",
"page-splitting-label": "Divisão de Páginas",
"page-splitting-tooltip": "Como dividir uma imagem que ocupa a largura toda (p.e., a imagem da esquerda e direita estão juntas)",
"reading-mode-label": "Modo de Leitura",
"reading-mode-tooltip": "Alterar o leitor para paginar verticalmente, horizontalmente ou para ter scroll infinito",
"layout-mode-label": "Modo de Layout",
"layout-mode-tooltip": "Mostrar apenas uma imagem no ecrã ou duas imagens lado a lado",
"background-color-label": "Cor de fundo",
"background-color-tooltip": "Cor de fundo do Leitor de Imagens",
"auto-close-menu-label": "Fechar Menu Automaticamente",
"auto-close-menu-tooltip": "Se o menu deve fechar automaticamente",
"show-screen-hints-label": "Mostrar Dicas no Ecrã",
"show-screen-hints-tooltip": "Mostrar dicas no ecrã que ajudam a compreender a área e direção de paginação",
"emulate-comic-book-label": "Emular livro de banda desenhada",
"emulate-comic-book-tooltip": "Aplica um efeito de sombra para emular a leitura a partir de um livro físico",
"swipe-to-paginate-label": "Deslizar para Paginar",
"swipe-to-paginate-tooltip": "Se o gesto de deslizar no ecrã causa que as páginas seguinte ou anterior sejam mostradas",
"allow-auto-webtoon-reader-label": "Modo Leitor Webtoon Automático",
"allow-auto-webtoon-reader-tooltip": "Muda para o modo Leitor Webtoon se as páginas indicam que é um webtoon. Podem acontecer falsos positivos.",
"width-override-label": "{{manga-reader.width-override-label}}",
"width-override-tooltip": "Substituir a largura das imagens no leitor",
"disable-width-override-label": "Desabilitar a substituição da largura",
"disable-width-override-tooltip": "Evitar que a substituição da largura tenha efeito quando o seu ecrã está configurado com o valor mínimo aceite",
"book-reader-settings-title": "Leitor de Livros",
"tap-to-paginate-label": "Tocar par Paginar",
"tap-to-paginate-tooltip": "Se as laterais do leitor de livros permitem que o toque mostre a página anterior/seguinte",
"immersive-mode-label": "Modo Imersivo",
"immersive-mode-tooltip": "Irá esconder o menu quando se clicar no documento e ligar o toque para paginar",
"reading-direction-book-label": "Direção de Leitura",
"reading-direction-book-tooltip": "Direção a clicar para ir para a página seguinte. Direita para Esquerda significa que se tem de clicar no lado esquerdo do ecrã para ir para a página seguinte.",
"font-family-label": "Família de Font",
"font-family-tooltip": "Família de fonts que vai ser carregada. Por defeito é carregada a font usada pelo livro",
"writing-style-label": "Estilo de Escrita",
"writing-style-tooltip": "Muda a direção do texto. A direção horizontal é da esquerda para direita, vertical é do topo para o fundo.",
"layout-mode-book-label": "Modo de Layout",
"layout-mode-book-tooltip": "Como o conteúdo deve ser disposto. O modo Scroll é como o livro define. O modo 1 ou 2 Colunas, ajusta-se à altura do dispositivo e tenta mostrar 1 ou 2 colunas de texto por página",
"color-theme-book-label": "Tema de Cores",
"color-theme-book-tooltip": "Que tema de cores deve ser aplicado ao conteúdo e menu do leitor de livros",
"font-size-book-label": "Tamanho da Font",
"font-size-book-tooltip": "Percentagem de dimensionamento que vai ser aplicado à font do livro",
"line-height-book-label": "Espaçamento entre Linhas",
"line-height-book-tooltip": "O espaçamento que existe entre linhas do livro",
"margin-book-label": "Margem",
"margin-book-tooltip": "Quando espaçamento existe de cada lado do ecrã. Esta opção será colocada a 0 em dispositivos móveis independentemente do valor que é aqui colocado.",
"pdf-reader-settings-title": "Leitor de PDF",
"pdf-scroll-mode-label": "Modo de Scroll",
"pdf-scroll-mode-tooltip": "Como é feito o scroll pelas páginas. Vertical/Horizontal e Tocar para Paginar (sem scroll)",
"pdf-spread-mode-label": "Modo de Layout",
"pdf-spread-mode-tooltip": "Como as páginas devem ser dispostas. Individual ou dupla (ímpar/par)",
"pdf-theme-label": "Tema",
"pdf-theme-tooltip": "O tema de cores do leitor",
"reading-profile-series-settings-title": "Séries",
"reading-profile-library-settings-title": "Biblioteca",
"delete": "{{common.delete}}"
},
"reviews": {
"user-reviews-local": "Criticas Locais",
@ -2647,5 +2759,59 @@
"genre-count": "{{num}} Etiquetas",
"issue-count": "{{common.issue-count}}",
"series-count": "{{common.series-count}}"
},
"bulk-set-reading-profile-modal": {
"title": "Definir perfil de leitura",
"close": "{{common.close}}",
"filter-label": "{{common.filter}}",
"clear": "{{common.clear}}",
"no-data": "Ainda não foram criadas coleções",
"loading": "{{common.loading}}",
"create": "{{common.create}}",
"bound": "Vinculado"
},
"merge-person-modal": {
"title": "{{personName}}",
"close": "{{common.close}}",
"save": "{{common.save}}",
"src": "Juntar Pessoa",
"merge-warning": "Se continuar, a pessoa selecionada será removida. O nome da pessoa selecionada será adicionada como pseudónimo e todas as suas funções serão transferidas.",
"alias-title": "Novos pseudónimos",
"known-for-title": "Conhecido por"
},
"browse-title-pipe": {
"publication-status": "{{value}} trabalhos",
"age-rating": "Avaliado com {{value}}",
"user-rating": "{{value}} classificação em estrelas",
"tag": "Tem Etiqueta {{value}}",
"translator": "Traduzido por {{value}}",
"character": "Tem o personagem {{value}}",
"publisher": "Publicado por {{value}}",
"editor": "Editado por {{value}}",
"artist": "Desenhado por {{value}}",
"letterer": "Com letras de {{value}}",
"colorist": "Colorido por {{value}}",
"inker": "Arte-finalizado por {{value}}",
"penciller": "Desenhado por {{value}}",
"writer": "Escrito por {{value}}",
"genre": "Tem o Género {{value}}",
"library": "Dentro da biblioteca {{value}}",
"format": "Formato de {{value}}",
"release-year": "Lançado em {{value}}",
"imprint": "Impressão de {{value}}",
"team": "Equipa {{value}}",
"location": "Na localização {{value}}"
},
"generic-filter-field-pipe": {
"person-role": "Função",
"person-name": "Nome",
"person-series-count": "Número de Séries",
"person-chapter-count": "Número de Capítulos"
},
"breakpoint-pipe": {
"never": "Nunca",
"mobile": "Móvel",
"tablet": "Tablet",
"desktop": "Desktop"
}
}

View file

@ -822,7 +822,7 @@
"library-name-unique": "O nome da biblioteca deve ser exclusivo",
"last-scanned-label": "Último Escaneamento:",
"type-label": "Tipo",
"type-tooltip": "O tipo de biblioteca determina como os nomes dos arquivos são analisados e se a IU mostra Capítulos (mangá) versus Números (quadrinhos). Verifique o wiki para obter mais detalhes sobre as diferenças entre os tipos de biblioteca.",
"type-tooltip": "O tipo de biblioteca determina como os nomes dos arquivos são analisados e se a IU mostra Capítulos (mangá) versus Edições (quadrinhos). Verifique o wiki para obter mais detalhes sobre as diferenças entre os tipos de biblioteca.",
"kavitaplus-eligible-label": "Kavita+ Elegível",
"kavitaplus-eligible-tooltip": "Kavita+ suporta as capacidades de metadados ou Scrobbling",
"folder-description": "Adicionar pastas à sua biblioteca",
@ -1153,7 +1153,7 @@
"log-label": "Dias de Registros",
"log-tooltip": "O número de registros a serem mantidos. O padrão é 30, o mínimo é 1 e o máximo é 30.",
"logging-level-label": "Nível de Registro",
"logging-level-tooltip": "Use a depuração para ajudar a identificar problemas. A depuração pode consumir muito espaço em disco.",
"logging-level-tooltip": "Use a depuração para identificar problemas. A depuração pode consumir muito espaço em disco.",
"cache-size-label": "Tamanho do Cache",
"cache-size-tooltip": "A quantidade de memória permitida para cache de APIs pesadas. O padrão é 75 MB.",
"on-deck-last-progress-label": "Última Leitura Na Estante (dias)",
@ -1545,7 +1545,7 @@
"import-description": "Para começar, importe um arquivo .cbl. O Kavita executará várias verificações antes de importar. Algumas etapas bloquearão o avanço devido a problemas com o arquivo.",
"validate-description": "Todos os arquivos foram validados para verificar se há alguma operação a ser feita na lista. Quaisquer listas que falharam não passarão para a próxima etapa. Corrija os arquivos CBL e tente novamente.",
"validate-warning": "Existem problemas com o CBL que impedirão uma importação. Corrija esses problemas e tente novamente.",
"validate-no-issue-description": "Nenhum problema encontrado com CBL, pressione próximo.",
"validate-no-issue-description": "Nenhum problema encontrado com CBL, pressione seguinte.",
"dry-run-description": "Esta é uma simulação e mostra o que acontecerá se você pressionar Avançar e executar a importação. Todas as falhas não serão importadas.",
"prev": "Anterior",
"import": "Importar",
@ -1761,7 +1761,7 @@
"chapter-title": "Capítulo",
"volume-num": "{{common.volume-num}}",
"highest-count-tooltip": "Número mais alto encontrado em todos os ComicInfo da Série",
"max-issue-tooltip": "Campo Máx. de Número ou Volume de todos ComicInfo nas Séries",
"max-issue-tooltip": "Campo Máx. de Edições ou Volume de todos ComicInfo nas Séries",
"force-refresh": "Forçar Atualização",
"force-refresh-tooltip": "Forçar a atualização de metadados externos do Kavita+",
"loose-leaf-volume": "Capítulos de Folhas Soltas",
@ -2193,7 +2193,7 @@
"confirm-library-delete": "Tem certeza de que deseja excluir a biblioteca {{name}}? Você não pode desfazer esta ação.",
"confirm-library-type-change": "Alterar o tipo de biblioteca acionará uma nova verificação com regras de análise diferentes e poderá levar à recriação de séries e, portanto, você poderá perder progresso e marcadores. Você deve fazer backup antes de fazer isso. Tem certeza de que deseja continuar?",
"confirm-download-size": "O {{entityType}} é {{size}}. Você tem certeza que quer continuar?",
"confirm-download-size-ios": "O iOS tem problemas para baixar arquivos maiores que 200 MB; esse download pode não ser concluído.",
"confirm-download-size-ios": "O iOS tem problemas para baixar arquivos maiores que 200 MB, esse download pode não ser concluído.",
"list-doesnt-exist": "Esta lista não existe",
"confirm-delete-smart-filter": "Tem certeza de que deseja excluir este Filtro Inteligente?",
"smart-filter-deleted": "Filtro Inteligente Excluído",
@ -2418,8 +2418,8 @@
"series-count": "{{num}} Séries",
"item-count": "{{num}} Itens",
"book-num": "Livro",
"issue-hash-num": "Número #",
"issue-num": "Número",
"issue-hash-num": "Edição #",
"issue-num": "Edição",
"chapter-num": "Capítulo",
"volume-num": "Volume",
"chapter-num-shorthand": "Cap. {{num}}",
@ -2608,15 +2608,15 @@
"overrides-label": "Substituir",
"enable-chapter-title-label": "Título",
"enable-chapter-publisher-label": "Editora",
"enable-chapter-publisher-tooltip": "Permitir que a Editora do Capítulo/Número seja salvo",
"enable-chapter-publisher-tooltip": "Permitir que a Editora do Capítulo/Edição seja salvo",
"enable-chapter-cover-label": "Capa do Capítulo",
"enable-chapter-cover-tooltip": "Permitir que a Capa do Capítulo/Número seja definida",
"enable-chapter-cover-tooltip": "Permitir que a Capa do Capítulo/Edição seja definida",
"chapter-header": "Campos de Capítulo",
"enable-chapter-title-tooltip": "Permitir que o Título do Capítulo/Número seja salvo",
"enable-chapter-title-tooltip": "Permitir que o Título do Capítulo/Edição seja salvo",
"enable-chapter-summary-label": "{{manage-metadata-settings.summary-label}}",
"enable-chapter-summary-tooltip": "{{manage-metadata-settings.summary-tooltip}}",
"enable-chapter-release-date-label": "Data de Lançamento",
"enable-chapter-release-date-tooltip": "Permitir que a Data de Lançamento do Capítulo/Número seja salvo"
"enable-chapter-release-date-tooltip": "Permitir que a Data de Lançamento do Capítulo/Edição seja salvo"
},
"metadata-setting-field-pipe": {
"publication-status": "{{edit-series-modal.publication-status-title}}",

View file

@ -789,7 +789,7 @@
},
"side-nav": {
"home": "Domov",
"want-to-read": "Chcem čítať",
"want-to-read": "Obľúbené",
"collections": "Zbierky",
"reading-lists": "Čítacie Zoznamy",
"bookmarks": "Záložky",
@ -2076,7 +2076,7 @@
"series-added-to-collection": "Séria bola pridaná do zbierky {{collectionName}}",
"no-series-collection-warning": "POZOR! Nie sú vybraté žiadne série, uložením sa zbierka odstráni. Ste si istý, že chcete pokračovať?",
"collection-updated": "Zbierka bola aktualizovaná",
"reading-list-deleted": "Zoznam na čítanie bol odstránený",
"reading-list-deleted": "Zoznam na čítanie bo zmazaný",
"reading-list-updated": "Zoznam na čítanie bol aktualizovaný",
"confirm-delete-reading-list": "Naozaj chcete vymazať zoznam na čítanie? Toto nie je možné vrátiť späť.",
"item-removed": "Položka bola odstránená",

View file

@ -14,7 +14,7 @@
"on-deck-title": "繼續閱讀",
"recently-updated-title": "最近更新系列",
"recently-added-title": "最近新增系列",
"more-in-genre-title": "{{genre}} 更多的內容分類"
"more-in-genre-title": "更多{{genre}}作品"
},
"edit-user": {
"edit": "{{common.edit}}",

View file

@ -2,12 +2,12 @@
"openapi": "3.0.4",
"info": {
"title": "Kavita",
"description": "Kavita provides a set of APIs that are authenticated by JWT. JWT token can be copied from local storage. Assume all fields of a payload are required. Built against v0.8.6.19",
"description": "Kavita provides a set of APIs that are authenticated by JWT. JWT token can be copied from local storage. Assume all fields of a payload are required. Built against v0.8.7.0",
"license": {
"name": "GPL-3.0",
"url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE"
},
"version": "0.8.6.19"
"version": "0.8.7.0"
},
"servers": [
{
@ -21371,6 +21371,10 @@
"type": "boolean",
"description": "Should Kavita read metadata files from the library"
},
"removePrefixForSortName": {
"type": "boolean",
"description": "Should Kavita remove sort articles \"The\" for the sort name"
},
"created": {
"type": "string",
"format": "date-time"
@ -21533,6 +21537,10 @@
"enableMetadata": {
"type": "boolean",
"description": "Allow Kavita to read metadata (ComicInfo.xml, Epub, PDF)"
},
"removePrefixForSortName": {
"type": "boolean",
"description": "Should Kavita remove sort articles \"The\" for the sort name"
}
},
"additionalProperties": false
@ -26438,6 +26446,7 @@
"manageCollections",
"manageReadingLists",
"name",
"removePrefixForSortName",
"type"
],
"type": "object",
@ -26492,6 +26501,9 @@
"enableMetadata": {
"type": "boolean"
},
"removePrefixForSortName": {
"type": "boolean"
},
"fileGroupTypes": {
"type": "array",
"items": {