@model StoryPointSnapshot @using System.Globalization @if (Model is null) {

No scenes are available in this project.

} else { var scene = Model.Scene; var exactTime = scene.TimeModeName is "Exact DateTime" or "Exact Date and Time";

@Model.Book.BookDisplayTitle · Chapter @Model.Chapter.ChapterNumber.ToString("g") · Scene @scene.SceneNumber.ToString("g")

@scene.SceneTitle

@if (scene.StartDateTime.HasValue) { @scene.StartDateTime.Value.ToString("dddd, d MMMM yyyy", CultureInfo.GetCultureInfo("en-GB")) @if (exactTime) { · @scene.StartDateTime.Value.ToString("h:mm tt", CultureInfo.GetCultureInfo("en-GB")) } } else { Story date unknown } @if (!string.IsNullOrWhiteSpace(scene.RelativeTimeText)) { · @scene.RelativeTimeText } · @scene.TimeModeName

POV: @(scene.POVCharacterName ?? "Not recorded") · Location: @(Model.Location?.LocationPath ?? scene.PrimaryLocationName ?? "Not recorded")

Open Scene Timeline @if (scene.StartDateTime.HasValue) { Calendar }

Characters present @Model.Characters.Count

@if (Model.Characters.Count == 0) {

No characters attached to this scene.

} else {
@foreach (var person in Model.Characters) { }
CharacterAge at this pointKnown locationPrevious appearance
@person.Appearance.CharacterName @person.Appearance.RoleInSceneTypeName @person.Appearance.PresenceTypeName @(person.Age.DisplayText ?? "Unknown") @if (!person.Age.HasExactAge && person.Age.DisplayText is not null) { Approximate } @(person.State?.CurrentLocation ?? "Unknown")@(person.State?.State == "Inferred" ? "Last known" : "") @if (person.PreviousAppearance is { } previous) { @previous.Label } else { First recorded appearance }
}

Character knowledge

@if (Model.Characters.All(x => x.Knowledge.Count == 0)) {

No structured knowledge recorded by this point.

} @foreach (var person in Model.Characters.Where(x => x.Knowledge.Count > 0)) {

@person.Appearance.CharacterName

}

Relationships at this point

@if (Model.Relationships.Count == 0) {

No historically established relationships recorded for these characters.

}
    @foreach (var relationship in Model.Relationships) { var source = relationship.History.LastOrDefault(x => x.SceneID.HasValue);
  • @relationship.CharacterAName ↔ @relationship.CharacterBName
    @relationship.CurrentStateName
    @if (source?.SceneID is int sourceId) { @(Model.Sources.GetValueOrDefault(sourceId)?.Label ?? "Source scene") } else { Established at story start }
  • }

Assets / important objects

@if (Model.Assets.Count == 0) {

No relevant assets recorded by this point.

} else {
@foreach (var asset in Model.Assets) { }
AssetHolderLocationStatusLast recorded event
@asset.AssetName@asset.Holder@asset.Location@asset.Status@asset.LatestEvent @if (asset.LastConfirmedSceneID is int sourceId) { @(Model.Sources.GetValueOrDefault(sourceId)?.Label ?? "Source scene") }
}

Location state

@if (Model.Location is { } location) {

@location.LocationPath

People last known here: @(location.CharactersPresent.Count == 0 ? "None recorded" : string.Join(", ", location.CharactersPresent))

Assets last known here: @(location.AssetsPresent.Count == 0 ? "None recorded" : string.Join(", ", location.AssetsPresent))

@if (Model.PreviousLocationUse is { } previous) {

Previous scene here: @previous.Label

} } else {

No primary location recorded.

}

Active threads / questions / clues

@if (Model.Threads.Count == 0) {

No active threads established by this point.

}
    @foreach (var thread in Model.Threads) {
  • @thread.Title @thread.Type · @thread.State @if (thread.Source is { } source) { @source.Label }
  • }

Things worth checking at this point

@if (Model.Warnings.Count == 0) {

No relevant continuity warnings.

}
}