{data.book.title} — libnovel
{#if data.book.cover} {/if}
{#if data.book.cover} {data.book.title} {/if}

{data.book.title}

{#if !data.inLib} not in library {/if}
{#if data.book.author}

{data.book.author}

{/if}
{#if data.book.status} {data.book.status} {/if} {#each genres as genre} {genre} {/each}
{#if data.book.summary}

{data.book.summary}

{#if data.book.summary.length > 220} {/if}
{/if}
{#if data.lastChapter} Continue ch.{data.lastChapter} {/if} {#if chapterList.length > 0} {data.inLib ? 'Start from ch.1' : 'Preview ch.1'} {/if} {#if data.inLib} {/if}

Chapters {#if chapterList.length > 0} ({chapterList.length}) {/if}

{#if totalPages > 1}
{page * pageSize + 1}–{Math.min((page + 1) * pageSize, chapterList.length)} of {chapterList.length}
{/if}
{#if pollingChapters}
Indexing chapter list…
{#each Array(8) as _}
{/each}
{:else if chapterList.length === 0}

No chapters available yet.

{:else}
{#each visibleChapters as chapter} {@const isCurrent = data.lastChapter === chapter.number} {@const chapterUrl = data.inLib ? `/books/${data.book.slug}/chapters/${chapter.number}` : `/books/${data.book.slug}/chapters/${chapter.number}?preview=1&chapter_url=${encodeURIComponent((chapter as { url?: string }).url ?? '')}&title=${encodeURIComponent(chapter.title ?? '')}`}
{chapter.number} {chapter.title || `Chapter ${chapter.number}`} {#if (chapter as { date_label?: string }).date_label} · {(chapter as { date_label?: string }).date_label} {/if} {#if isCurrent} reading {/if} {#if data.isAdmin && data.book.source_url && data.inLib} {/if}
{/each}
{/if} {#if data.isAdmin && data.book.source_url}
{#if adminOpen}
{#if scrapeResult} {scrapeResult === 'queued' ? 'Queued.' : scrapeResult === 'busy' ? 'Scraper busy.' : 'Error.'} {/if}
{#if rangeResult} {rangeResult === 'queued' ? 'Range scrape queued.' : rangeResult === 'busy' ? 'Scraper busy.' : 'Error queuing.'} {/if}
{/if}
{/if}