# EpubReaderService

- File ID: file:q4k94a:epubreaderservice-cs
- Path: NexusReader.Infrastructure/Services/EpubReaderService.cs
- Role: service
- Layer: infrastructure

## Purpose

Service that locates an EPUB file for an ebook in the DB, reads and parses a chapter into content blocks (text segments and AI-trigger blocks) for the reader UI.

## Key Details

Implements a word-threshold-driven AI trigger insertion (WordThreshold=1000). Uses DB to resolve filesystem path; searches upward for wwwroot to handle dev/prod layouts; sanitizes HTML and extracts paragraph-like blocks; robust guard clauses and try/catch with logging.

## Symbols

- EpubReaderService: Service that locates an EPUB file for an ebook in the DB, reads and parses a chapter into content blocks (text segments and AI-trigger blocks) for the reader UI.
- EpubReaderService(): Constructor that injects the DB context factory and logger.
- GetEpubContentAsync(): Main runtime method: resolves the ebook file via DB, parses an EPUB, extracts chapter text into content blocks, inserts AI triggers based on word threshold, and returns a ReaderPageViewModel or a failure result.
- ResolvePath(): Resolves a web-relative storage path to an absolute filesystem path by searching up the app base directory for wwwroot (and a development src path).
- ExtractParagraphs(): Extracts paragraph-like blocks from HTML by selecting <p>, headings, lists, blockquote, pre, hr or splitting on breaks when none found.
- SanitizeParagraph(): Sanitizes HTML paragraph content by removing scripts/styles, stripping disallowed tags, normalizing allowed tags, HTML-decoding and trimming.
- CountWords(): Counts words in a text by splitting on whitespace characters; returns 0 for null/whitespace input.
- CreateAiTrigger(): Factory that creates an AiActionTriggerBlock with localized prompt and action labels.
- FindTitleInNavigation(): Recursively searches EPUB navigation items for a title that matches a given file path or file name.

## Dependencies

- No resolved dependencies.

## Calls

- No resolved calls.

## Unresolved References

- dependency-target: NexusReader.Data.Persistence (AppDbContext/Ebooks)
- dependency-target: VersOne.Epub (EpubReader, EpubNavigationItemRef)
- dependency-target: FluentResults (Result)
- call-target: self
- call-target: self
- call-target: self
- call-target: self
- call-target: self
- call-target: self
- call-target: self
- call-target: self
- interaction-target: var ebook = await context.Ebooks
- interaction-target: var chapterTitle = FindTitleInNavigation(navigation, chapterRef.FilePath)
- interaction-target: private static string? FindTitleInNavigation(IEnumerable<EpubNavigationItemRef> navigation, string? filePath)
- interaction-target: var childTitle = FindTitleInNavigation(item.NestedItems, filePath);
- interaction-target: Calls VersOne.Epub.EpubReader.OpenBookAsync to open the EPUB (external library)
- interaction-target: chapterRef.ReadContentAsTextAsync() (external EPUB object)

## Coverage

- Symbols: 9
- Executable symbols: 8
- Executable symbols with control flow: 8
- Grounded edges: 9
- Unresolved references: 17
- Control-flow fragments: 8
- Unresolved jumps: 0
- Unsupported constructs: 0
- Control-flow coverage: 100%
- Required diagrams: 2
- Generated diagrams: 7

## Control Flow Fragments

- EpubReaderService: 3 nodes, 2 edges, 0 jumps, 0 unsupported constructs
- GetEpubContentAsync: 78 nodes, 89 edges, 7 jumps, 0 unsupported constructs
- ResolvePath: 19 nodes, 22 edges, 0 jumps, 0 unsupported constructs
- ExtractParagraphs: 12 nodes, 13 edges, 0 jumps, 0 unsupported constructs
- SanitizeParagraph: 6 nodes, 5 edges, 0 jumps, 0 unsupported constructs
- CountWords: 11 nodes, 12 edges, 0 jumps, 0 unsupported constructs
- CreateAiTrigger: 3 nodes, 2 edges, 0 jumps, 0 unsupported constructs
- FindTitleInNavigation: 34 nodes, 40 edges, 1 jumps, 0 unsupported constructs

## Diagrams

### EpubReaderService Neighborhood

```mermaid
flowchart LR
    class_1ynrixc_epubreaderservice("EpubReaderService")
    file_q4k94a_epubreaderservice_cs("EpubReaderService")
    method_12jssth_findtitleinnavigation[["FindTitleInNavigation()"]]
    method_1mthy2_sanitizeparagraph[["SanitizeParagraph()"]]
    method_1tcm0y0_extractparagraphs[["ExtractParagraphs()"]]
    method_1y3guy7_epubreaderservice[["EpubReaderService()"]]
    method_85035t_countwords[["CountWords()"]]
    method_9ls8js_createaitrigger[["CreateAiTrigger()"]]
    method_bamm0e_getepubcontentasync[["GetEpubContentAsync()"]]
    method_fxyqm0_resolvepath[["ResolvePath()"]]
```

### EpubReaderService Execution Overview

_Warnings: diagram file_q4k94a_epubreaderservice_cs_execution_view exceeds preferred complexity thresholds (22 nodes, 22 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart TD
    class_1ynrixc_epubreaderservice("EpubReaderService")
    method_12jssth_findtitleinnavigation[["FindTitleInNavigation()"]]
    method_1mthy2_sanitizeparagraph[["SanitizeParagraph()"]]
    method_1tcm0y0_extractparagraphs[["ExtractParagraphs()"]]
    method_1y3guy7_epubreaderservice[["EpubReaderService()"]]
    method_85035t_countwords[["CountWords()"]]
    method_9ls8js_createaitrigger[["CreateAiTrigger()"]]
    method_bamm0e_getepubcontentasync[["GetEpubContentAsync()"]]
    method_fxyqm0_resolvepath[["ResolvePath()"]]
    unresolved_unresolved_10vtji3_call_target{"Unresolved: ExtractParagraphs"}
    unresolved_unresolved_19zzvhz_call_target{"Unresolved: CreateAiTrigger"}
    unresolved_unresolved_1jnjwar_interaction_target{"Unresolved: chapterRef.ReadContentAsTextAsync() (external EPUB object)"}
    unresolved_unresolved_1qm31wz_interaction_target{"Unresolved: var ebook = await context.Ebooks"}
    unresolved_unresolved_1tbpd8k_interaction_target{"Unresolved: var chapterTitle = FindTitleInNavigation(navigation, chapterRef.FilePath)"}
    unresolved_unresolved_1vbv9lo_interaction_target{"Unresolved: var childTitle = FindTitleInNavigation(item.NestedItems, filePath);"}
    unresolved_unresolved_fsn6r_call_target{"Unresolved: CountWords"}
    unresolved_unresolved_o3cgod_call_target{"Unresolved: FindTitleInNavigation"}
    unresolved_unresolved_p2zvza_call_target{"Unresolved: SanitizeParagraph"}
    unresolved_unresolved_pbjm7m_call_target{"Unresolved: ResolvePath"}
    unresolved_unresolved_sd20r_call_target{"Unresolved: FindTitleInNavigation"}
    unresolved_unresolved_tdlw7z_interaction_target{"Unresolved: Calls VersOne.Epub.EpubReader.OpenBookAsync to open the EPUB (external library)"}
    unresolved_unresolved_tivg13_interaction_target{"Unresolved: private static string? FindTitleInNavigation(IEnumerable<EpubNavigationItemRef> navigation, string? filePath)"}
    class_1ynrixc_epubreaderservice -->|contains| method_12jssth_findtitleinnavigation
    class_1ynrixc_epubreaderservice -->|contains| method_1mthy2_sanitizeparagraph
    class_1ynrixc_epubreaderservice -->|contains| method_1tcm0y0_extractparagraphs
    class_1ynrixc_epubreaderservice -->|contains| method_1y3guy7_epubreaderservice
    class_1ynrixc_epubreaderservice -->|contains| method_85035t_countwords
    class_1ynrixc_epubreaderservice -->|contains| method_9ls8js_createaitrigger
    class_1ynrixc_epubreaderservice -->|contains| method_bamm0e_getepubcontentasync
    class_1ynrixc_epubreaderservice -->|contains| method_fxyqm0_resolvepath
    class_1ynrixc_epubreaderservice -->|unresolved interaction| unresolved_unresolved_1jnjwar_interaction_target
    class_1ynrixc_epubreaderservice -->|unresolved interaction| unresolved_unresolved_1qm31wz_interaction_target
    class_1ynrixc_epubreaderservice -->|unresolved interaction| unresolved_unresolved_1tbpd8k_interaction_target
    class_1ynrixc_epubreaderservice -->|unresolved interaction| unresolved_unresolved_1vbv9lo_interaction_target
    class_1ynrixc_epubreaderservice -->|unresolved interaction| unresolved_unresolved_tdlw7z_interaction_target
    class_1ynrixc_epubreaderservice -->|unresolved interaction| unresolved_unresolved_tivg13_interaction_target
    method_12jssth_findtitleinnavigation -->|unresolved call| unresolved_unresolved_o3cgod_call_target
    method_bamm0e_getepubcontentasync -->|unresolved call| unresolved_unresolved_10vtji3_call_target
    method_bamm0e_getepubcontentasync -->|unresolved call| unresolved_unresolved_19zzvhz_call_target
    method_bamm0e_getepubcontentasync -->|unresolved call| unresolved_unresolved_19zzvhz_call_target
    method_bamm0e_getepubcontentasync -->|unresolved call| unresolved_unresolved_fsn6r_call_target
    method_bamm0e_getepubcontentasync -->|unresolved call| unresolved_unresolved_p2zvza_call_target
    method_bamm0e_getepubcontentasync -->|unresolved call| unresolved_unresolved_pbjm7m_call_target
    method_bamm0e_getepubcontentasync -->|unresolved call| unresolved_unresolved_sd20r_call_target
```

### GetEpubContentAsync() Control Flow

_Warnings: diagram method_bamm0e_getepubcontentasync__fragment_diagram exceeds preferred complexity thresholds (78 nodes, 89 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart TD
    method_bamm0e_getepubcontentasync__call_101_CreateAiTrigger[["CreateAiTrigger"]]
    method_bamm0e_getepubcontentasync__call_108_CreateAiTrigger[["CreateAiTrigger"]]
    method_bamm0e_getepubcontentasync__call_54_ResolvePath[["ResolvePath"]]
    method_bamm0e_getepubcontentasync__call_77_FindTitleInNavigation[["FindTitleInNavigation"]]
    method_bamm0e_getepubcontentasync__call_88_ExtractParagraphs[["ExtractParagraphs"]]
    method_bamm0e_getepubcontentasync__call_91_SanitizeParagraph[["SanitizeParagraph"]]
    method_bamm0e_getepubcontentasync__call_96_CountWords[["CountWords"]]
    method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__condition{"blocks.Any() && blocks.Last() is not AiActionTriggerBlock"}
    method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__false("false")
    method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__merge("merge")
    method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__true("true")
    method_bamm0e_getepubcontentasync__action_106_post_condition_106__linear("ensure trailing AI trigger")
    method_bamm0e_getepubcontentasync__action_113_getepubcontentasync_catch_113_20__catch("catch Exception ex")
    method_bamm0e_getepubcontentasync__action_115_getepubcontentasync_log_115_21__linear("Logs runtime state")
    method_bamm0e_getepubcontentasync__action_115_log_115__linear("log error on exception")
    method_bamm0e_getepubcontentasync__action_36_getepubcontentasync_try_36_0__try("Begins protected execution")
    method_bamm0e_getepubcontentasync__action_36_try_catch_36__linear("overall error handling")
    method_bamm0e_getepubcontentasync__action_39_getepubcontentasync_await_39_1__await[["Waits for async work"]]
    method_bamm0e_getepubcontentasync__action_39_persistence_read_39__linear("resolve ebook row")
    method_bamm0e_getepubcontentasync__action_41_getepubcontentasync_await_41_3__await[["Waits for async work"]]
    method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__condition{"ebook == null"}
    method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__false("false")
    method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__merge("merge")
    method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__true("true")
    method_bamm0e_getepubcontentasync__action_47_guard_clause_47__condition{"ebook == null"}
    method_bamm0e_getepubcontentasync__action_47_guard_clause_47__false("otherwise")
    method_bamm0e_getepubcontentasync__action_47_guard_clause_47__merge("merge")
    method_bamm0e_getepubcontentasync__action_47_guard_clause_47__true("fail-return")
    method_bamm0e_getepubcontentasync__action_54_external_file_check_54__linear("resolve filesystem path and verify file exists")
    method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__condition{"fullPath == null || !File.Exists(fullPath)"}
    method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__false("false")
    method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__merge("merge")
    method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__true("true")
    method_bamm0e_getepubcontentasync__action_57_getepubcontentasync_log_57_7__linear("Logs runtime state")
    method_bamm0e_getepubcontentasync__action_62_getepubcontentasync_await_62_9__await[["Waits for async work"]]
    method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__condition{"readingOrder == null || !readingOrder.Any()"}
    method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__false("false")
    method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__merge("merge")
    method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__true("true")
    method_bamm0e_getepubcontentasync__action_65_guard_clause_65__condition{"readingOrder == null || !readingOrder.Any()"}
    method_bamm0e_getepubcontentasync__action_65_guard_clause_65__false("otherwise")
    method_bamm0e_getepubcontentasync__action_65_guard_clause_65__merge("merge")
    method_bamm0e_getepubcontentasync__action_65_guard_clause_65__true("fail-return")
    method_bamm0e_getepubcontentasync__action_70_branch_70__condition{"chapterIndex out of bounds"}
    method_bamm0e_getepubcontentasync__action_70_branch_70__false("continue")
    method_bamm0e_getepubcontentasync__action_70_branch_70__merge("merge")
    method_bamm0e_getepubcontentasync__action_70_branch_70__true("reset-to-0")
    method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__condition{"chapterIndex < 0 || chapterIndex >= readingOrder.Count"}
    method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__false("false")
    method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__merge("merge")
    method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__true("true")
    method_bamm0e_getepubcontentasync__action_81_getepubcontentasync_await_81_14__await[["Waits for async work"]]
    method_bamm0e_getepubcontentasync__action_89_getepubcontentasync_loop_89_15__loop_body[["foreach (var p in paragraphs)"]]
    method_bamm0e_getepubcontentasync__action_89_getepubcontentasync_loop_89_15__loop_entry("var p in paragraphs")
    method_bamm0e_getepubcontentasync__action_89_getepubcontentasync_loop_89_15__loop_exit("Leaves the loop when the condition no longer holds.")
    method_bamm0e_getepubcontentasync__action_89_loop_89__loop_body[["foreach paragraphs: sanitize, skip empties, add TextSegmentBlock, count words, insert AI trigger when threshold reached"]]
    method_bamm0e_getepubcontentasync__action_89_loop_89__loop_entry("iterate paragraphs")
    method_bamm0e_getepubcontentasync__action_89_loop_89__loop_exit("exit loop")
    method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__condition{"string.IsNullOrWhiteSpace(sanitizedContent)"}
    method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__false("continue")
    method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__merge("merge")
    method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__true("exit")
    method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__condition{"totalWordCount >= WordThreshold"}
    method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__false("false")
    method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__merge("merge")
    method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__true("true")
    method_bamm0e_getepubcontentasync__action_99_threshold_99__linear("insert AI trigger after WordThreshold words")
    method_bamm0e_getepubcontentasync__entry(["GetEpubContentAsync entry"])
    method_bamm0e_getepubcontentasync__action_41_getepubcontentasync_repository_read_41_2__linear[("Reads repository or persistence state")]
    method_bamm0e_getepubcontentasync__action_62_external_call_62__linear("open EPUB")
    method_bamm0e_getepubcontentasync__action_77_getepubcontentasync_repository_read_77_13__linear[("Reads repository or persistence state")]
    method_bamm0e_getepubcontentasync__action_81_external_call_81__linear("read chapter text")
    method_bamm0e_getepubcontentasync__action_111_getepubcontentasync_return_111_19__return(["Returns result"])
    method_bamm0e_getepubcontentasync__action_111_return_111__return(["successful result"])
    method_bamm0e_getepubcontentasync__action_116_getepubcontentasync_return_116_22__return(["Returns result"])
    method_bamm0e_getepubcontentasync__action_49_getepubcontentasync_return_49_5__return(["Returns result"])
    method_bamm0e_getepubcontentasync__action_58_getepubcontentasync_return_58_8__return(["Returns result"])
    method_bamm0e_getepubcontentasync__action_67_getepubcontentasync_return_67_11__return(["Returns result"])
    method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__condition -->|false| method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__false
    method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__condition -->|true| method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__true
    method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__false -->|next| method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__merge
    method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__merge -->|next| method_bamm0e_getepubcontentasync__action_106_post_condition_106__linear
    method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__true -->|next| method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__merge
    method_bamm0e_getepubcontentasync__action_106_post_condition_106__linear -->|generated trigger id| method_bamm0e_getepubcontentasync__call_108_CreateAiTrigger
    method_bamm0e_getepubcontentasync__action_111_getepubcontentasync_return_111_19__return -->|exception| method_bamm0e_getepubcontentasync__action_113_getepubcontentasync_catch_113_20__catch
    method_bamm0e_getepubcontentasync__action_111_return_111__return -->|return| method_bamm0e_getepubcontentasync__action_111_getepubcontentasync_return_111_19__return
    method_bamm0e_getepubcontentasync__action_113_getepubcontentasync_catch_113_20__catch -->|next| method_bamm0e_getepubcontentasync__action_115_getepubcontentasync_log_115_21__linear
    method_bamm0e_getepubcontentasync__action_115_getepubcontentasync_log_115_21__linear -->|next| method_bamm0e_getepubcontentasync__action_115_log_115__linear
    method_bamm0e_getepubcontentasync__action_115_log_115__linear -->|return| method_bamm0e_getepubcontentasync__action_116_getepubcontentasync_return_116_22__return
    method_bamm0e_getepubcontentasync__action_36_getepubcontentasync_try_36_0__try -->|next| method_bamm0e_getepubcontentasync__action_39_getepubcontentasync_await_39_1__await
    method_bamm0e_getepubcontentasync__action_36_try_catch_36__linear -->|next| method_bamm0e_getepubcontentasync__action_36_getepubcontentasync_try_36_0__try
    method_bamm0e_getepubcontentasync__action_39_getepubcontentasync_await_39_1__await -->|next| method_bamm0e_getepubcontentasync__action_39_persistence_read_39__linear
    method_bamm0e_getepubcontentasync__action_39_persistence_read_39__linear -->|next| method_bamm0e_getepubcontentasync__action_41_getepubcontentasync_await_41_3__await
    method_bamm0e_getepubcontentasync__action_41_getepubcontentasync_await_41_3__await -->|next| method_bamm0e_getepubcontentasync__action_41_getepubcontentasync_repository_read_41_2__linear
    method_bamm0e_getepubcontentasync__action_41_getepubcontentasync_repository_read_41_2__linear -->|next| method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__condition
    method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__condition -->|false| method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__false
    method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__condition -->|true| method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__true
    method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__false -->|next| method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__merge
    method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__merge -->|next| method_bamm0e_getepubcontentasync__action_47_guard_clause_47__condition
    method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__true -->|next| method_bamm0e_getepubcontentasync__action_47_getepubcontentasync_branch_47_4__merge
    method_bamm0e_getepubcontentasync__action_47_guard_clause_47__condition -->|otherwise| method_bamm0e_getepubcontentasync__action_47_guard_clause_47__false
    method_bamm0e_getepubcontentasync__action_47_guard_clause_47__condition -->|fail-return| method_bamm0e_getepubcontentasync__action_47_guard_clause_47__true
    method_bamm0e_getepubcontentasync__action_47_guard_clause_47__false -->|next| method_bamm0e_getepubcontentasync__action_47_guard_clause_47__merge
    method_bamm0e_getepubcontentasync__action_47_guard_clause_47__merge -->|return| method_bamm0e_getepubcontentasync__action_49_getepubcontentasync_return_49_5__return
    method_bamm0e_getepubcontentasync__action_47_guard_clause_47__true -->|next| method_bamm0e_getepubcontentasync__action_47_guard_clause_47__merge
    method_bamm0e_getepubcontentasync__action_49_getepubcontentasync_return_49_5__return -->|next| method_bamm0e_getepubcontentasync__action_54_external_file_check_54__linear
    method_bamm0e_getepubcontentasync__action_54_external_file_check_54__linear -->|ebook.FilePath web-relative path| method_bamm0e_getepubcontentasync__call_54_ResolvePath
    method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__condition -->|false| method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__false
    method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__condition -->|true| method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__true
    method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__false -->|next| method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__merge
    method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__merge -->|next| method_bamm0e_getepubcontentasync__action_57_getepubcontentasync_log_57_7__linear
    method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__true -->|next| method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__merge
    method_bamm0e_getepubcontentasync__action_57_getepubcontentasync_log_57_7__linear -->|return| method_bamm0e_getepubcontentasync__action_58_getepubcontentasync_return_58_8__return
    method_bamm0e_getepubcontentasync__action_58_getepubcontentasync_return_58_8__return -->|next| method_bamm0e_getepubcontentasync__action_62_getepubcontentasync_await_62_9__await
    method_bamm0e_getepubcontentasync__action_62_external_call_62__linear -->|next| method_bamm0e_getepubcontentasync__action_65_guard_clause_65__condition
    method_bamm0e_getepubcontentasync__action_62_getepubcontentasync_await_62_9__await -->|next| method_bamm0e_getepubcontentasync__action_62_external_call_62__linear
    method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__condition -->|false| method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__false
    method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__condition -->|true| method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__true
    method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__false -->|next| method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__merge
    method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__merge -->|return| method_bamm0e_getepubcontentasync__action_67_getepubcontentasync_return_67_11__return
    method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__true -->|next| method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__merge
    method_bamm0e_getepubcontentasync__action_65_guard_clause_65__condition -->|otherwise| method_bamm0e_getepubcontentasync__action_65_guard_clause_65__false
    method_bamm0e_getepubcontentasync__action_65_guard_clause_65__condition -->|fail-return| method_bamm0e_getepubcontentasync__action_65_guard_clause_65__true
    method_bamm0e_getepubcontentasync__action_65_guard_clause_65__false -->|next| method_bamm0e_getepubcontentasync__action_65_guard_clause_65__merge
    method_bamm0e_getepubcontentasync__action_65_guard_clause_65__merge -->|next| method_bamm0e_getepubcontentasync__action_65_getepubcontentasync_branch_65_10__condition
    method_bamm0e_getepubcontentasync__action_65_guard_clause_65__true -->|next| method_bamm0e_getepubcontentasync__action_65_guard_clause_65__merge
    method_bamm0e_getepubcontentasync__action_67_getepubcontentasync_return_67_11__return -->|next| method_bamm0e_getepubcontentasync__action_70_branch_70__condition
    method_bamm0e_getepubcontentasync__action_70_branch_70__condition -->|continue| method_bamm0e_getepubcontentasync__action_70_branch_70__false
    method_bamm0e_getepubcontentasync__action_70_branch_70__condition -->|reset-to-0| method_bamm0e_getepubcontentasync__action_70_branch_70__true
    method_bamm0e_getepubcontentasync__action_70_branch_70__false -->|next| method_bamm0e_getepubcontentasync__action_70_branch_70__merge
    method_bamm0e_getepubcontentasync__action_70_branch_70__merge -->|next| method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__condition
    method_bamm0e_getepubcontentasync__action_70_branch_70__true -->|next| method_bamm0e_getepubcontentasync__action_70_branch_70__merge
    method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__condition -->|false| method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__false
    method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__condition -->|true| method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__true
    method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__false -->|next| method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__merge
    method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__merge -->|next| method_bamm0e_getepubcontentasync__action_77_getepubcontentasync_repository_read_77_13__linear
    method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__true -->|next| method_bamm0e_getepubcontentasync__action_70_getepubcontentasync_branch_70_12__merge
    method_bamm0e_getepubcontentasync__action_77_getepubcontentasync_repository_read_77_13__linear -->|navigation, chapterRef.FilePath| method_bamm0e_getepubcontentasync__call_77_FindTitleInNavigation
    method_bamm0e_getepubcontentasync__action_81_external_call_81__linear -->|chapterContent HTML string| method_bamm0e_getepubcontentasync__call_88_ExtractParagraphs
    method_bamm0e_getepubcontentasync__action_81_getepubcontentasync_await_81_14__await -->|next| method_bamm0e_getepubcontentasync__action_81_external_call_81__linear
    method_bamm0e_getepubcontentasync__action_89_getepubcontentasync_loop_89_15__loop_body -->|continue| method_bamm0e_getepubcontentasync__action_89_getepubcontentasync_loop_89_15__loop_entry
    method_bamm0e_getepubcontentasync__action_89_getepubcontentasync_loop_89_15__loop_entry -->|var p in paragraphs| method_bamm0e_getepubcontentasync__action_89_getepubcontentasync_loop_89_15__loop_body
    method_bamm0e_getepubcontentasync__action_89_getepubcontentasync_loop_89_15__loop_entry -->|Leaves the loop when the condition no longer holds.| method_bamm0e_getepubcontentasync__action_89_getepubcontentasync_loop_89_15__loop_exit
    method_bamm0e_getepubcontentasync__action_89_getepubcontentasync_loop_89_15__loop_exit -->|next| method_bamm0e_getepubcontentasync__action_89_loop_89__loop_entry
    method_bamm0e_getepubcontentasync__action_89_loop_89__loop_body -->|continue| method_bamm0e_getepubcontentasync__action_89_loop_89__loop_entry
    method_bamm0e_getepubcontentasync__action_89_loop_89__loop_entry -->|iterate| method_bamm0e_getepubcontentasync__action_89_loop_89__loop_body
    method_bamm0e_getepubcontentasync__action_89_loop_89__loop_entry -->|exit| method_bamm0e_getepubcontentasync__action_89_loop_89__loop_exit
    method_bamm0e_getepubcontentasync__action_89_loop_89__loop_exit -->|paragraph HTML| method_bamm0e_getepubcontentasync__call_91_SanitizeParagraph
    method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__condition -->|continue| method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__false
    method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__condition -->|exit| method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__true
    method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__false -->|next| method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__merge
    method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__merge -->|sanitized paragraph text| method_bamm0e_getepubcontentasync__call_96_CountWords
    method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__true -->|next| method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__merge
    method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__condition -->|false| method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__false
    method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__condition -->|true| method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__true
    method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__false -->|next| method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__merge
    method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__merge -->|generated trigger id| method_bamm0e_getepubcontentasync__call_101_CreateAiTrigger
    method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__true -->|next| method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__merge
    method_bamm0e_getepubcontentasync__action_99_threshold_99__linear -->|next| method_bamm0e_getepubcontentasync__action_99_getepubcontentasync_branch_99_17__condition
    method_bamm0e_getepubcontentasync__call_101_CreateAiTrigger -->|next| method_bamm0e_getepubcontentasync__action_106_getepubcontentasync_branch_106_18__condition
    method_bamm0e_getepubcontentasync__call_108_CreateAiTrigger -->|return| method_bamm0e_getepubcontentasync__action_111_return_111__return
    method_bamm0e_getepubcontentasync__call_54_ResolvePath -->|next| method_bamm0e_getepubcontentasync__action_55_getepubcontentasync_branch_55_6__condition
    method_bamm0e_getepubcontentasync__call_77_FindTitleInNavigation -->|next| method_bamm0e_getepubcontentasync__action_81_getepubcontentasync_await_81_14__await
    method_bamm0e_getepubcontentasync__call_88_ExtractParagraphs -->|next| method_bamm0e_getepubcontentasync__action_89_getepubcontentasync_loop_89_15__loop_entry
    method_bamm0e_getepubcontentasync__call_91_SanitizeParagraph -->|next| method_bamm0e_getepubcontentasync__action_92_getepubcontentasync_guard_clause_92_16__condition
    method_bamm0e_getepubcontentasync__call_96_CountWords -->|next| method_bamm0e_getepubcontentasync__action_99_threshold_99__linear
    method_bamm0e_getepubcontentasync__entry -->|next| method_bamm0e_getepubcontentasync__action_36_try_catch_36__linear
```

### ResolvePath() Control Flow

_Warnings: diagram method_fxyqm0_resolvepath__fragment_diagram exceeds preferred complexity thresholds (19 nodes, 22 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart TD
    method_fxyqm0_resolvepath__action_127_normalization_127__linear("normalize path separators")
    method_fxyqm0_resolvepath__action_130_loop_130__loop_body[["iteratively checks currentDir and its parents for candidate and devCandidate locations"]]
    method_fxyqm0_resolvepath__action_130_loop_130__loop_entry("walk parent directories")
    method_fxyqm0_resolvepath__action_130_loop_130__loop_exit("exit loop")
    method_fxyqm0_resolvepath__action_130_resolvepath_loop_130_0__loop_body[["while (currentDir != null)"]]
    method_fxyqm0_resolvepath__action_130_resolvepath_loop_130_0__loop_entry("currentDir != null")
    method_fxyqm0_resolvepath__action_130_resolvepath_loop_130_0__loop_exit("Leaves the loop when the condition no longer holds.")
    method_fxyqm0_resolvepath__action_132_file_exists_check_132__linear("check candidate paths")
    method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__condition{"File.Exists(candidate)"}
    method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__false("continue")
    method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__merge("merge")
    method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__true("exit")
    method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__condition{"File.Exists(devCandidate)"}
    method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__false("continue")
    method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__merge("merge")
    method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__true("exit")
    method_fxyqm0_resolvepath__entry(["ResolvePath entry"])
    method_fxyqm0_resolvepath__action_142_resolvepath_return_142_3__return(["Returns result"])
    method_fxyqm0_resolvepath__action_142_return_142__return(["not found"])
    method_fxyqm0_resolvepath__action_127_normalization_127__linear -->|next| method_fxyqm0_resolvepath__action_130_loop_130__loop_entry
    method_fxyqm0_resolvepath__action_130_loop_130__loop_body -->|continue| method_fxyqm0_resolvepath__action_130_loop_130__loop_entry
    method_fxyqm0_resolvepath__action_130_loop_130__loop_entry -->|iterate| method_fxyqm0_resolvepath__action_130_loop_130__loop_body
    method_fxyqm0_resolvepath__action_130_loop_130__loop_entry -->|exit| method_fxyqm0_resolvepath__action_130_loop_130__loop_exit
    method_fxyqm0_resolvepath__action_130_loop_130__loop_exit -->|next| method_fxyqm0_resolvepath__action_130_resolvepath_loop_130_0__loop_entry
    method_fxyqm0_resolvepath__action_130_resolvepath_loop_130_0__loop_body -->|continue| method_fxyqm0_resolvepath__action_130_resolvepath_loop_130_0__loop_entry
    method_fxyqm0_resolvepath__action_130_resolvepath_loop_130_0__loop_entry -->|transforms input| method_fxyqm0_resolvepath__action_130_resolvepath_loop_130_0__loop_body
    method_fxyqm0_resolvepath__action_130_resolvepath_loop_130_0__loop_entry -->|Leaves the loop when the condition no longer holds.| method_fxyqm0_resolvepath__action_130_resolvepath_loop_130_0__loop_exit
    method_fxyqm0_resolvepath__action_130_resolvepath_loop_130_0__loop_exit -->|next| method_fxyqm0_resolvepath__action_132_file_exists_check_132__linear
    method_fxyqm0_resolvepath__action_132_file_exists_check_132__linear -->|next| method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__condition
    method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__condition -->|continue| method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__false
    method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__condition -->|exit| method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__true
    method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__false -->|next| method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__merge
    method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__merge -->|next| method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__condition
    method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__true -->|next| method_fxyqm0_resolvepath__action_133_resolvepath_guard_clause_133_1__merge
    method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__condition -->|continue| method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__false
    method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__condition -->|exit| method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__true
    method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__false -->|next| method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__merge
    method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__merge -->|return| method_fxyqm0_resolvepath__action_142_resolvepath_return_142_3__return
    method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__true -->|next| method_fxyqm0_resolvepath__action_137_resolvepath_guard_clause_137_2__merge
    method_fxyqm0_resolvepath__action_142_resolvepath_return_142_3__return -->|return| method_fxyqm0_resolvepath__action_142_return_142__return
    method_fxyqm0_resolvepath__entry -->|next| method_fxyqm0_resolvepath__action_127_normalization_127__linear
```

### ExtractParagraphs() Control Flow

```mermaid
flowchart TD
    method_1tcm0y0_extractparagraphs__action_147_regex_parse_147__linear("extract body content")
    method_1tcm0y0_extractparagraphs__action_151_regex_parse_151__linear("find paragraph-like tags")
    method_1tcm0y0_extractparagraphs__action_153_extractparagraphs_loop_153_0__loop_body[["foreach (Match match in matches)"]]
    method_1tcm0y0_extractparagraphs__action_153_extractparagraphs_loop_153_0__loop_entry("Match match in matches")
    method_1tcm0y0_extractparagraphs__action_153_extractparagraphs_loop_153_0__loop_exit("Leaves the loop when the condition no longer holds.")
    method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__condition{"paragraphs.Count == 0"}
    method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__false("false")
    method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__merge("merge")
    method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__true("true")
    method_1tcm0y0_extractparagraphs__action_158_fallback_split_158__linear("split by breaks when no matches")
    method_1tcm0y0_extractparagraphs__entry(["ExtractParagraphs entry"])
    method_1tcm0y0_extractparagraphs__action_163_extractparagraphs_return_163_2__return(["Returns result"])
    method_1tcm0y0_extractparagraphs__action_147_regex_parse_147__linear -->|next| method_1tcm0y0_extractparagraphs__action_151_regex_parse_151__linear
    method_1tcm0y0_extractparagraphs__action_151_regex_parse_151__linear -->|next| method_1tcm0y0_extractparagraphs__action_153_extractparagraphs_loop_153_0__loop_entry
    method_1tcm0y0_extractparagraphs__action_153_extractparagraphs_loop_153_0__loop_body -->|continue| method_1tcm0y0_extractparagraphs__action_153_extractparagraphs_loop_153_0__loop_entry
    method_1tcm0y0_extractparagraphs__action_153_extractparagraphs_loop_153_0__loop_entry -->|Match match in matches| method_1tcm0y0_extractparagraphs__action_153_extractparagraphs_loop_153_0__loop_body
    method_1tcm0y0_extractparagraphs__action_153_extractparagraphs_loop_153_0__loop_entry -->|Leaves the loop when the condition no longer holds.| method_1tcm0y0_extractparagraphs__action_153_extractparagraphs_loop_153_0__loop_exit
    method_1tcm0y0_extractparagraphs__action_153_extractparagraphs_loop_153_0__loop_exit -->|next| method_1tcm0y0_extractparagraphs__action_158_fallback_split_158__linear
    method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__condition -->|false| method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__false
    method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__condition -->|true| method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__true
    method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__false -->|next| method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__merge
    method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__merge -->|return| method_1tcm0y0_extractparagraphs__action_163_extractparagraphs_return_163_2__return
    method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__true -->|next| method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__merge
    method_1tcm0y0_extractparagraphs__action_158_fallback_split_158__linear -->|next| method_1tcm0y0_extractparagraphs__action_158_extractparagraphs_branch_158_1__condition
    method_1tcm0y0_extractparagraphs__entry -->|next| method_1tcm0y0_extractparagraphs__action_147_regex_parse_147__linear
```

### CountWords() Control Flow

```mermaid
flowchart TD
    method_85035t_countwords__action_177_countwords_guard_clause_177_0__condition{"string.IsNullOrWhiteSpace(text)"}
    method_85035t_countwords__action_177_countwords_guard_clause_177_0__false("continue")
    method_85035t_countwords__action_177_countwords_guard_clause_177_0__merge("merge")
    method_85035t_countwords__action_177_countwords_guard_clause_177_0__true("exit")
    method_85035t_countwords__action_177_guard_clause_177__condition{"empty check"}
    method_85035t_countwords__action_177_guard_clause_177__false("false")
    method_85035t_countwords__action_177_guard_clause_177__merge("merge")
    method_85035t_countwords__action_177_guard_clause_177__true("true")
    method_85035t_countwords__action_178_split_count_178__linear("split on whitespace and count")
    method_85035t_countwords__entry(["CountWords entry"])
    method_85035t_countwords__action_178_countwords_return_178_1__return(["Returns result"])
    method_85035t_countwords__action_177_countwords_guard_clause_177_0__condition -->|continue| method_85035t_countwords__action_177_countwords_guard_clause_177_0__false
    method_85035t_countwords__action_177_countwords_guard_clause_177_0__condition -->|exit| method_85035t_countwords__action_177_countwords_guard_clause_177_0__true
    method_85035t_countwords__action_177_countwords_guard_clause_177_0__false -->|next| method_85035t_countwords__action_177_countwords_guard_clause_177_0__merge
    method_85035t_countwords__action_177_countwords_guard_clause_177_0__merge -->|next| method_85035t_countwords__action_177_guard_clause_177__condition
    method_85035t_countwords__action_177_countwords_guard_clause_177_0__true -->|next| method_85035t_countwords__action_177_countwords_guard_clause_177_0__merge
    method_85035t_countwords__action_177_guard_clause_177__condition -->|false| method_85035t_countwords__action_177_guard_clause_177__false
    method_85035t_countwords__action_177_guard_clause_177__condition -->|true| method_85035t_countwords__action_177_guard_clause_177__true
    method_85035t_countwords__action_177_guard_clause_177__false -->|next| method_85035t_countwords__action_177_guard_clause_177__merge
    method_85035t_countwords__action_177_guard_clause_177__merge -->|next| method_85035t_countwords__action_178_split_count_178__linear
    method_85035t_countwords__action_177_guard_clause_177__true -->|next| method_85035t_countwords__action_177_guard_clause_177__merge
    method_85035t_countwords__action_178_split_count_178__linear -->|return| method_85035t_countwords__action_178_countwords_return_178_1__return
    method_85035t_countwords__entry -->|next| method_85035t_countwords__action_177_countwords_guard_clause_177_0__condition
```

### FindTitleInNavigation() Control Flow

_Warnings: diagram method_12jssth_findtitleinnavigation__fragment_diagram exceeds preferred complexity thresholds (34 nodes, 40 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart TD
    method_12jssth_findtitleinnavigation__call_198_FindTitleInNavigation[["FindTitleInNavigation"]]
    method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__condition{"string.IsNullOrEmpty(filePath)"}
    method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__false("continue")
    method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__merge("merge")
    method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__true("exit")
    method_12jssth_findtitleinnavigation__action_188_guard_clause_188__condition{"null/empty filePath"}
    method_12jssth_findtitleinnavigation__action_188_guard_clause_188__false("false")
    method_12jssth_findtitleinnavigation__action_188_guard_clause_188__merge("merge")
    method_12jssth_findtitleinnavigation__action_188_guard_clause_188__true("true")
    method_12jssth_findtitleinnavigation__action_191_findtitleinnavigation_loop_191_2__loop_body[["foreach (var item in navigation)"]]
    method_12jssth_findtitleinnavigation__action_191_findtitleinnavigation_loop_191_2__loop_entry("var item in navigation")
    method_12jssth_findtitleinnavigation__action_191_findtitleinnavigation_loop_191_2__loop_exit("Leaves the loop when the condition no longer holds.")
    method_12jssth_findtitleinnavigation__action_191_loop_191__loop_body[["for each navigation item compare Link.ContentFilePath or fileName and return item.Title if match"]]
    method_12jssth_findtitleinnavigation__action_191_loop_191__loop_entry("iterate navigation items")
    method_12jssth_findtitleinnavigation__action_191_loop_191__loop_exit("exit loop")
    method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__condition{"item.Link?.ContentFilePath == filePath || item.Link?.ContentFilePath == fileName"}
    method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__false("false")
    method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__merge("merge")
    method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__true("true")
    method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__condition{"item.NestedItems?.Any() == true"}
    method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__false("false")
    method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__merge("merge")
    method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__true("true")
    method_12jssth_findtitleinnavigation__action_196_recursion_196__linear("search nested items")
    method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__condition{"childTitle != null"}
    method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__false("continue")
    method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__merge("merge")
    method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__true("exit")
    method_12jssth_findtitleinnavigation__entry(["FindTitleInNavigation entry"])
    method_12jssth_findtitleinnavigation__action_186_findtitleinnavigation_repository_read_186_0__linear[("Reads repository or persistence state")]
    method_12jssth_findtitleinnavigation__action_198_findtitleinnavigation_repository_read_198_6__linear[("Reads repository or persistence state")]
    method_12jssth_findtitleinnavigation__action_194_findtitleinnavigation_return_194_4__return(["Returns result"])
    method_12jssth_findtitleinnavigation__action_203_findtitleinnavigation_return_203_8__return(["Returns result"])
    method_12jssth_findtitleinnavigation__action_203_return_203__return(["not found"])
    method_12jssth_findtitleinnavigation__action_186_findtitleinnavigation_repository_read_186_0__linear -->|next| method_12jssth_findtitleinnavigation__action_188_guard_clause_188__condition
    method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__condition -->|continue| method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__false
    method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__condition -->|exit| method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__true
    method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__false -->|next| method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__merge
    method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__merge -->|next| method_12jssth_findtitleinnavigation__action_191_findtitleinnavigation_loop_191_2__loop_entry
    method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__true -->|next| method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__merge
    method_12jssth_findtitleinnavigation__action_188_guard_clause_188__condition -->|false| method_12jssth_findtitleinnavigation__action_188_guard_clause_188__false
    method_12jssth_findtitleinnavigation__action_188_guard_clause_188__condition -->|true| method_12jssth_findtitleinnavigation__action_188_guard_clause_188__true
    method_12jssth_findtitleinnavigation__action_188_guard_clause_188__false -->|next| method_12jssth_findtitleinnavigation__action_188_guard_clause_188__merge
    method_12jssth_findtitleinnavigation__action_188_guard_clause_188__merge -->|next| method_12jssth_findtitleinnavigation__action_188_findtitleinnavigation_guard_clause_188_1__condition
    method_12jssth_findtitleinnavigation__action_188_guard_clause_188__true -->|next| method_12jssth_findtitleinnavigation__action_188_guard_clause_188__merge
    method_12jssth_findtitleinnavigation__action_191_findtitleinnavigation_loop_191_2__loop_body -->|continue| method_12jssth_findtitleinnavigation__action_191_findtitleinnavigation_loop_191_2__loop_entry
    method_12jssth_findtitleinnavigation__action_191_findtitleinnavigation_loop_191_2__loop_entry -->|var item in navigation| method_12jssth_findtitleinnavigation__action_191_findtitleinnavigation_loop_191_2__loop_body
    method_12jssth_findtitleinnavigation__action_191_findtitleinnavigation_loop_191_2__loop_entry -->|Leaves the loop when the condition no longer holds.| method_12jssth_findtitleinnavigation__action_191_findtitleinnavigation_loop_191_2__loop_exit
    method_12jssth_findtitleinnavigation__action_191_findtitleinnavigation_loop_191_2__loop_exit -->|next| method_12jssth_findtitleinnavigation__action_191_loop_191__loop_entry
    method_12jssth_findtitleinnavigation__action_191_loop_191__loop_body -->|continue| method_12jssth_findtitleinnavigation__action_191_loop_191__loop_entry
    method_12jssth_findtitleinnavigation__action_191_loop_191__loop_entry -->|iterate| method_12jssth_findtitleinnavigation__action_191_loop_191__loop_body
    method_12jssth_findtitleinnavigation__action_191_loop_191__loop_entry -->|exit| method_12jssth_findtitleinnavigation__action_191_loop_191__loop_exit
    method_12jssth_findtitleinnavigation__action_191_loop_191__loop_exit -->|next| method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__condition
    method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__condition -->|false| method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__false
    method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__condition -->|true| method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__true
    method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__false -->|next| method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__merge
    method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__merge -->|return| method_12jssth_findtitleinnavigation__action_194_findtitleinnavigation_return_194_4__return
    method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__true -->|next| method_12jssth_findtitleinnavigation__action_193_findtitleinnavigation_branch_193_3__merge
    method_12jssth_findtitleinnavigation__action_194_findtitleinnavigation_return_194_4__return -->|next| method_12jssth_findtitleinnavigation__action_196_recursion_196__linear
    method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__condition -->|false| method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__false
    method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__condition -->|true| method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__true
    method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__false -->|next| method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__merge
    method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__merge -->|next| method_12jssth_findtitleinnavigation__action_198_findtitleinnavigation_repository_read_198_6__linear
    method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__true -->|next| method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__merge
    method_12jssth_findtitleinnavigation__action_196_recursion_196__linear -->|next| method_12jssth_findtitleinnavigation__action_196_findtitleinnavigation_branch_196_5__condition
    method_12jssth_findtitleinnavigation__action_198_findtitleinnavigation_repository_read_198_6__linear -->|item.NestedItems, filePath recursive search| method_12jssth_findtitleinnavigation__call_198_FindTitleInNavigation
    method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__condition -->|continue| method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__false
    method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__condition -->|exit| method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__true
    method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__false -->|next| method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__merge
    method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__merge -->|return| method_12jssth_findtitleinnavigation__action_203_findtitleinnavigation_return_203_8__return
    method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__true -->|next| method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__merge
    method_12jssth_findtitleinnavigation__action_203_findtitleinnavigation_return_203_8__return -->|return| method_12jssth_findtitleinnavigation__action_203_return_203__return
    method_12jssth_findtitleinnavigation__call_198_FindTitleInNavigation -->|next| method_12jssth_findtitleinnavigation__action_199_findtitleinnavigation_guard_clause_199_7__condition
    method_12jssth_findtitleinnavigation__entry -->|next| method_12jssth_findtitleinnavigation__action_186_findtitleinnavigation_repository_read_186_0__linear
```

## Diagram Validation

- Status: warn
- Warning: execution-overview: diagram file_q4k94a_epubreaderservice_cs_execution_view exceeds preferred complexity thresholds (22 nodes, 22 edges).
- Warning: control-flow: diagram method_bamm0e_getepubcontentasync__fragment_diagram exceeds preferred complexity thresholds (78 nodes, 89 edges).
- Warning: control-flow: diagram method_fxyqm0_resolvepath__fragment_diagram exceeds preferred complexity thresholds (19 nodes, 22 edges).
- Warning: control-flow: diagram method_12jssth_findtitleinnavigation__fragment_diagram exceeds preferred complexity thresholds (34 nodes, 40 edges).
