@model StoryIntelligenceProgressViewModel @{ ViewData["Title"] = "Review locations"; var locationCandidates = Model.LocationReview.Candidates.ToList(); }

Story Intelligence

Review Locations

Explore important story settings first. Resolve uncertain identities and use the full list to inspect or organise every detected place.

@if (TempData["OnboardingStoryIntelligenceError"] is string error) {
@error
} @if (TempData["OnboardingStoryIntelligenceMessage"] is string message) {
@message
}

Parent locations are included for context. Confidence describes identification; significance describes story importance.

@if (Model.LocationReview.Candidates.Count == 0) {
No locations match this filter.

Choose All detected locations to explore the complete list.

} else {
Page @Model.LocationReview.PageNumber.ToString("N0") of @Model.LocationReview.PageCount.ToString("N0") · Showing @Model.LocationReview.ShowingStart.ToString("N0")-@Model.LocationReview.ShowingEnd.ToString("N0") of @Model.LocationReview.FilteredCount.ToString("N0") locations
@for (var i = 0; i < locationCandidates.Count; i++) { var candidate = locationCandidates[i]; var status = candidate.IsExistingMatch ? "existing" : "new"; var proposedParentLabel = candidate.ProposedParentLocationName ?? candidate.ParentLocationHint; var proposedParentValue = candidate.ProposedParentLocationID.HasValue ? $"existing:{candidate.ProposedParentLocationID.Value}" : !string.IsNullOrWhiteSpace(candidate.ProposedParentCandidateKey) ? $"candidate:{candidate.ProposedParentCandidateKey}" : string.Empty; var searchText = string.Join(" ", new[] { candidate.LocationName, candidate.ExistingLocationName, candidate.Category, candidate.ParentLocationHint, candidate.ProposedParentLocationName });
@if (!string.IsNullOrWhiteSpace(proposedParentLabel)) { Within @proposedParentLabel } @candidate.LocationName @(candidate.Significance?.Classification ?? "Not yet assessed") · @(candidate.IsPending && candidate.NeedsReview ? "Identity needs review" : "") @candidate.Category · @candidate.AppearsInScenes.ToString("N0") scene@(candidate.AppearsInScenes == 1 ? string.Empty : "s") Confidence: @candidate.Confidence
@if (candidate.Significance is { } significance) {
@significance.Classification · significance @significance.Score/100
    @foreach (var reason in significance.Reasons) {
  • @reason
  • }
@if (significance.Characters.Any()) {

Characters: @string.Join(", ", significance.Characters)

} @if (significance.PlotLines.Any()) {

Plot lines: @string.Join(", ", significance.PlotLines)

} @foreach (var scene in significance.KeyScenes) { @scene.SceneLabel
}
}
First appearance
@Display(candidate.ExampleFirstAppearance)
Proposed parent
@Display(proposedParentLabel)
Existing match
@(candidate.ExistingLocationName ?? "None")
@if (!string.IsNullOrWhiteSpace(candidate.ExampleContext)) {
Scene context

@candidate.ExampleContext

} @if (candidate.EvidenceSummaries.Any()) {
Evidence from @candidate.AppearsInScenes.ToString("N0") scene@(candidate.AppearsInScenes == 1 ? string.Empty : "s")
    @foreach (var evidence in candidate.EvidenceSummaries) {
  • @evidence
  • }
} @if (candidate.IsPending) { @if (candidate.IsExistingMatch) {
Existing location matched

@candidate.LocationName is linked to @candidate.ExistingLocationName. Review only the parent location if needed.

} @if (candidate.IsExistingMatch) { } else {
Decision
}
@if (!candidate.IsExistingMatch) { } } else {

Decision saved: @candidate.DecisionStatus

}
}
Page @Model.LocationReview.PageNumber.ToString("N0") of @Model.LocationReview.PageCount.ToString("N0") · Showing @Model.LocationReview.ShowingStart.ToString("N0")-@Model.LocationReview.ShowingEnd.ToString("N0") of @Model.LocationReview.FilteredCount.ToString("N0") locations @if (Model.LocationReview.HasPreviousPage) { Previous } @if (Model.LocationReview.HasNextPage) { Next } @if (Model.LocationReview.CanImport) { } Back to Review Centre
}
@section Scripts { } @functions { private static string Display(string? value) => string.IsNullOrWhiteSpace(value) ? "Not detected" : value; private static string TargetLabel(StoryIntelligenceLocationTargetOptionViewModel target) => string.IsNullOrWhiteSpace(target.AliasSummary) ? target.DisplayName : $"{target.DisplayName} ({target.AliasSummary})"; private static bool IsSelfTarget(StoryIntelligenceLocationTargetOptionViewModel target, StoryIntelligenceLocationReviewCandidateViewModel candidate) => (target.LocationID.HasValue && candidate.ExistingLocationID == target.LocationID) || (!string.IsNullOrWhiteSpace(target.CandidateKey) && string.Equals(target.CandidateKey, candidate.Key, StringComparison.OrdinalIgnoreCase)); }