///|
fn html_escape(value : String) -> String {
  let output = StringBuilder()
  for character in value.to_array() {
    match character {
      '&' => output.write_string("&")
      '<' => output.write_string("<")
      '>' => output.write_string(">")
      '"' => output.write_string(""")
      '\'' => output.write_string("'")
      _ => output.write_char(character)
    }
  }
  output.to_string()
}

///|
fn html_status_class(status : @evidence.AssessmentStatus) -> String {
  match status {
    @evidence.InControl => "in-control"
    @evidence.Warning => "warning"
    @evidence.RequiresReview => "requires-review"
    @evidence.Incomplete => "incomplete"
  }
}

///|
fn html_find_run(runs : Array[@run.QCRun], run_index : Int) -> @run.QCRun? {
  runs.get(run_index)
}

///|
fn html_find_first_assessment(
  trajectory : @evidence.Trajectory,
  status : @evidence.AssessmentStatus,
) -> Int? {
  for index, assessment in trajectory.assessments {
    if assessment.status == status {
      return Some(index)
    }
  }
  None
}

///|
fn html_find_epoch_run_index(
  runs : Array[@run.QCRun],
  epoch : @epoch.QCEpoch,
) -> Int? {
  for index, run in runs {
    if run.epoch.has_same_metadata(epoch) {
      return Some(index)
    }
  }
  None
}

///|
fn html_find_evidence_run_index(
  runs : Array[@run.QCRun],
  evidence : @evidence.EvidencePoint,
) -> Int? {
  for index, run in runs {
    if run.run_id == evidence.run_id &&
      run.sequence == evidence.sequence &&
      run.epoch.id == evidence.epoch_id {
      return Some(index)
    }
  }
  None
}

///|
fn html_find_control_rule_run_index(
  trajectory : @evidence.Trajectory,
  control_level_id : String,
  rule : @assay.Rule,
) -> Int? {
  for index, assessment in trajectory.assessments {
    for hit in assessment.hits {
      if hit.rule == rule {
        for point in hit.evidence {
          if point.control_level_id == control_level_id {
            return Some(index)
          }
        }
      }
    }
  }
  None
}

///|
fn html_find_epoch_control_rule_run_index(
  runs : Array[@run.QCRun],
  trajectory : @evidence.Trajectory,
  epoch : @epoch.QCEpoch,
  control_level_id : String,
  rule : @assay.Rule,
) -> Int? {
  for index, assessment in trajectory.assessments {
    match runs.get(index) {
      Some(run) if run.epoch.has_same_metadata(epoch) =>
        for hit in assessment.hits {
          if hit.rule == rule {
            for point in hit.evidence {
              if point.control_level_id == control_level_id {
                return Some(index)
              }
            }
          }
        }
      _ => ()
    }
  }
  None
}

///|
fn html_find_coverage_gap_run_index(
  runs : Array[@run.QCRun],
  trajectory : @evidence.Trajectory,
  coverage : ControlCoverageCount,
  precision : Int,
) -> Int? {
  for index, run in runs {
    if run.epoch.has_same_metadata(coverage.epoch) &&
      trajectory.assessments.get(index) is Some(_) {
      let mut point : @run.ControlPoint? = None
      for observation in run.observations {
        if observation.control_level_id == coverage.control_level_id &&
          point is None {
          point = Some(observation)
        }
      }
      if coverage.missing_runs > 0 && point is None {
        return Some(index)
      }
      if coverage.missing_runs == 0 &&
        coverage.precision_mismatch_runs > 0 &&
        point is Some(observation) &&
        observation.precision != precision {
        return Some(index)
      }
    }
  }
  None
}

///|
fn html_append_status_card(
  output : StringBuilder,
  label : String,
  count : Int,
  status : @evidence.AssessmentStatus,
  trajectory : @evidence.Trajectory,
) -> Unit {
  output.write_string("\n")
}

///|
fn html_append_evidence(
  output : StringBuilder,
  evidence : @evidence.EvidencePoint,
  runs : Array[@run.QCRun],
) -> Unit {
  output.write_string("")
  match html_find_evidence_run_index(runs, evidence) {
    Some(index) => {
      output.write_string("")
      output.write_string(html_escape(evidence.run_id))
      output.write_string("")
    }
    None => output.write_string(html_escape(evidence.run_id))
  }
  output.write_string(
    "" +
    html_escape(evidence.control_level_id) +
    "" +
    format_scaled(evidence.value, evidence.precision) +
    " " +
    html_escape(evidence.unit) +
    "" +
    format_scaled(evidence.mean, evidence.precision) +
    "" +
    format_scaled(evidence.standard_deviation, evidence.precision) +
    "" +
    format_scaled(evidence.threshold, evidence.precision) +
    "" +
    direction_name(evidence.direction) +
    "\n",
  )
}

///|
fn html_append_assessment(
  output : StringBuilder,
  program : @assay.AssayProgram,
  run_index : Int,
  assessment : @evidence.RunAssessment,
  runs : Array[@run.QCRun],
) -> Unit {
  output.write_string("
") output.write_string(assessment.status.name()) output.write_string("Run ") output.write_string(html_escape(assessment.run_id)) output.write_string("sequence ") output.write_string(assessment.sequence.to_string()) output.write_string("
\n") match html_find_run(runs, run_index) { Some(run) => { output.write_string("
Timestamp
") output.write_string(html_escape(run.timestamp)) output.write_string("
Epoch
") output.write_string(html_escape(run.epoch.id)) output.write_string("
Reagent lot
") output.write_string(html_escape(run.epoch.reagent_lot)) output.write_string("
Control lot
") output.write_string(html_escape(run.epoch.control_lot)) output.write_string("
Calibration
") output.write_string(html_escape(run.epoch.calibration_id)) output.write_string("
Program version
") output.write_string(html_escape(run.epoch.program_version)) output.write_string("
\n") output.write_string( "

Observations

\n\n", ) if run.observations.length() == 0 { output.write_string("\n") } else { for point in run.observations { output.write_string( "\n", ) } } output.write_string("
ControlValuePrecision
No observations
" + html_escape(point.control_level_id) + "" + format_scaled(point.value, point.precision) + " " + html_escape(program.unit) + "" + point.precision.to_string() + "
\n") } None => output.write_string("

Run snapshot unavailable.

\n") } if assessment.hits.length() == 0 { output.write_string("

No rule hits.

\n") } else { output.write_string("

Rule signals and evidence

\n") for hit in assessment.hits { output.write_string("
") output.write_string(hit.rule.name()) output.write_string(" ") output.write_string(scope_name(hit.scope)) output.write_string("

") output.write_string(html_escape(hit.reason)) output.write_string("

\n") if hit.evidence.length() > 0 { output.write_string( "\n", ) for evidence in hit.evidence { html_append_evidence(output, evidence, runs) } output.write_string("
RunControlObservedMeanSDThreshold distanceDirection
\n") } output.write_string("
\n") } } for issue in assessment.input_issues { output.write_string("

Input issue [") output.write_string(issue.code.name()) output.write_string("]: ") output.write_string(html_escape(issue.message)) output.write_string("

\n") } output.write_string("
\n") } ///| /// Render a deterministic, self-contained HTML audit report with an embedded /// Levey–Jennings chart. The document has no scripts, external styles, or /// network dependencies and can be opened offline. pub fn render_audit_html( program : @assay.AssayProgram, runs : Array[@run.QCRun], trajectory : @evidence.Trajectory, ) -> String { let summary = audit_summary(program, runs, trajectory) let output = StringBuilder() output.write_string( "\n\nQC audit report — ", ) output.write_string(html_escape(program.assay_id)) output.write_string("
\n

Offline QC audit report · schema version 1

", ) output.write_string(html_escape(program.assay_id)) output.write_string("

Measurement unit: ") output.write_string(html_escape(program.unit)) output.write_string(" · Decimal precision: ") output.write_string(program.precision.to_string()) output.write_string("

\n") output.write_string( "

Summary

\n", ) output.write_string("
Input runs") output.write_string(summary.input_runs.to_string()) output.write_string( "
Assessed runs", ) output.write_string(summary.assessed_runs.to_string()) output.write_string("
\n") html_append_status_card( output, "In control", summary.in_control, @evidence.InControl, trajectory, ) html_append_status_card( output, "Warning", summary.warning, @evidence.Warning, trajectory, ) html_append_status_card( output, "Requires review", summary.requires_review, @evidence.RequiresReview, trajectory, ) html_append_status_card( output, "Incomplete", summary.incomplete, @evidence.Incomplete, trajectory, ) output.write_string("
Rule hits") output.write_string(summary.total_rule_hits.to_string()) output.write_string("
Track issues") output.write_string(summary.track_issues.to_string()) output.write_string("

Rule hit counts

\n") if summary.total_rule_hits == 0 { output.write_string("

No rule hits.

\n") } else { output.write_string( "\n", ) for hit in summary.rule_hits { if hit.count > 0 { output.write_string("\n") } } output.write_string("
RuleCountDisposition
") output.write_string(hit.rule.name()) output.write_string("") output.write_string(hit.count.to_string()) output.write_string("") output.write_string( audit_rule_disposition_name(program.disposition_for(hit.rule)), ) output.write_string("
\n") } output.write_string("

Control rule hit counts

\n") if summary.control_rule_hits.length() == 0 { output.write_string("

No control-level rule hits.

\n") } else { output.write_string( "\n", ) for entry in summary.control_rule_hits { output.write_string("\n") } output.write_string("
ControlRuleHit runsNavigate
") output.write_string(html_escape(entry.control_level_id)) output.write_string("") output.write_string(entry.rule.name()) output.write_string("") output.write_string(entry.count.to_string()) output.write_string("") match html_find_control_rule_run_index( trajectory, entry.control_level_id, entry.rule, ) { Some(index) => { output.write_string("Open first signal") } None => output.write_string("No evidence run") } output.write_string("
\n") } output.write_string("

Rule signals by epoch and control

\n") if summary.epoch_control_rule_hits.length() == 0 { output.write_string( "

No epoch-specific control rule hits.

\n", ) } else { output.write_string( "\n", ) for entry in summary.epoch_control_rule_hits { output.write_string("\n") } output.write_string("
EpochControlRuleHit runsDispositionNavigate
") output.write_string(html_escape(entry.epoch.id)) output.write_string("") output.write_string(html_escape(entry.control_level_id)) output.write_string("") output.write_string(entry.rule.name()) output.write_string("") output.write_string(entry.count.to_string()) output.write_string("") output.write_string( audit_rule_disposition_name(program.disposition_for(entry.rule)), ) output.write_string("") match html_find_epoch_control_rule_run_index( runs, trajectory, entry.epoch, entry.control_level_id, entry.rule, ) { Some(index) => { output.write_string("Open first signal") } None => output.write_string("No evidence run") } output.write_string("
\n") } output.write_string("

Control observation coverage

\n") if summary.control_coverage.length() == 0 { output.write_string( "

No expected control observations.

\n", ) } else { output.write_string( "\n", ) for coverage in summary.control_coverage { output.write_string("\n") } output.write_string("
EpochControlRequiredExpected runsObserved runsMissing runsPrecision mismatchNavigate
") output.write_string(html_escape(coverage.epoch.id)) output.write_string("") output.write_string(html_escape(coverage.control_level_id)) output.write_string("") output.write_string(if coverage.required { "Yes" } else { "No" }) output.write_string("") output.write_string(coverage.expected_runs.to_string()) output.write_string("") output.write_string(coverage.observed_runs.to_string()) output.write_string("") output.write_string(coverage.missing_runs.to_string()) output.write_string("") output.write_string(coverage.precision_mismatch_runs.to_string()) output.write_string("") match html_find_coverage_gap_run_index( runs, trajectory, coverage, program.precision, ) { Some(index) => { output.write_string("") output.write_string( if coverage.missing_runs > 0 { "Open first missing run" } else { "Open first precision mismatch" }, ) output.write_string("") } None => output.write_string("No coverage gaps") } output.write_string("
\n") } output.write_string("
\n") output.write_string( "

Assay configuration

Program: ", ) output.write_string(html_escape(program.assay_id)) output.write_string("; unit: ") output.write_string(html_escape(program.unit)) output.write_string("; precision: ") output.write_string(program.precision.to_string()) output.write_string( "

\n", ) for level in program.levels { output.write_string("\n") } output.write_string("
ControlMeanStandard deviationRequired
") output.write_string(html_escape(level.id)) output.write_string("") output.write_string(format_scaled(level.mean, program.precision)) output.write_string("") output.write_string( format_scaled(level.standard_deviation, program.precision), ) output.write_string("") output.write_string(if level.required { "Yes" } else { "No" }) output.write_string("

Rule dispositions

\n") output.write_string( "\n", ) for rule in audit_rule_order() { output.write_string("\n") } output.write_string("
RuleDisposition
") output.write_string(rule.name()) output.write_string("") output.write_string( audit_rule_disposition_name(program.disposition_for(rule)), ) output.write_string("

QC epochs

\n") if summary.epoch_runs.length() == 0 { output.write_string("

No epochs.

\n") } else { output.write_string( "\n", ) for entry in summary.epoch_runs { output.write_string("\n") } output.write_string("
EpochReagent lotControl lotCalibrationProgram versionRunsIn controlWarningRequires reviewIncompleteRule hitsNavigate
") output.write_string(html_escape(entry.epoch.id)) output.write_string("") output.write_string(html_escape(entry.epoch.reagent_lot)) output.write_string("") output.write_string(html_escape(entry.epoch.control_lot)) output.write_string("") output.write_string(html_escape(entry.epoch.calibration_id)) output.write_string("") output.write_string(html_escape(entry.epoch.program_version)) output.write_string("") output.write_string(entry.count.to_string()) output.write_string("") output.write_string(entry.in_control.to_string()) output.write_string("") output.write_string(entry.warning.to_string()) output.write_string("") output.write_string(entry.requires_review.to_string()) output.write_string("") output.write_string(entry.incomplete.to_string()) output.write_string("") output.write_string( audit_epoch_total_rule_hits(summary.epoch_rule_hits, entry.epoch).to_string(), ) output.write_string("") match html_find_epoch_run_index(runs, entry.epoch) { Some(index) => { output.write_string("Open first run") } None => output.write_string("No run detail") } output.write_string("
\n") } output.write_string("
\n") output.write_string( "

Levey–Jennings chart

", ) output.write_string(render_levey_jennings_svg(program, runs, trajectory)) output.write_string( "
Control observations, target mean, ±1/2/3 SD lines, epoch boundaries, and rule evidence.
\n", ) output.write_string("

Run assessments

") if trajectory.assessments.length() == 0 { output.write_string("

No run assessments.

\n") } else { for index, assessment in trajectory.assessments { html_append_assessment(output, program, index, assessment, runs) } } output.write_string("
\n") if trajectory.input_issues.length() > 0 { output.write_string("

Track issues

\n") for issue in trajectory.input_issues { output.write_string("

") output.write_string(issue.code.name()) output.write_string("") match issue.run_id { Some(run_id) => { output.write_string(" · run ") output.write_string(html_escape(run_id)) } None => () } output.write_string(": ") output.write_string(html_escape(issue.message)) output.write_string("

\n") } output.write_string("
\n") } output.write_string( "
\n", ) output.to_string() }