// Source: index.html script block (extracted). Loaded via <script type="text/babel"> in index.html.
// Docs page — Task Format Requirements. Inlined (external script loading blocked in preview).
function Doc({ id, title, children }) {
  return (
    <section id={"doc-"+id} className="doc-section">
      <h2>{title}</h2>
      {children}
    </section>
  );
}

function FieldTable({ rows }) {
  return (
    <table className="doc-table">
      <thead><tr><th>Field</th><th>Type</th><th>Req.</th><th>Notes</th></tr></thead>
      <tbody>
        {rows.map(([f,t,r,n],i)=>(
          <tr key={i}>
            <td><code>{f}</code></td>
            <td>{t}</td>
            <td>{r}</td>
            <td dangerouslySetInnerHTML={{__html:n}}/>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function Docs() {
  const { t: tr, lang } = useLang();
  const [active, setActive] = React.useState("overview");
  const sections = [
    ["overview", tr("docs_nav_overview")],
    ["envelope", tr("docs_nav_envelope")],
    ["description", tr("docs_nav_description")],
    ["user_scenario", tr("docs_nav_user_scenario")],
    ["medical_persona", tr("docs_nav_medical_persona")],
    ["evaluation_criteria", tr("docs_nav_eval")],
    ["initial_state", tr("docs_nav_init")],
    ["ticket", tr("docs_nav_ticket")],
    ["validation", tr("docs_nav_validation")],
    ["conversion", tr("docs_nav_conversion")],
    ["common", tr("docs_nav_common")],
    ["minimal", tr("docs_nav_minimal")],
  ];

  React.useEffect(()=>{
    const s = document.querySelector(".docs-scroll");
    if (!s) return;
    const h = () => {
      const top = s.scrollTop + 80;
      let cur = "overview";
      for (const [id] of sections) {
        const el = document.getElementById("doc-"+id);
        if (el && el.offsetTop <= top) cur = id;
      }
      setActive(cur);
    };
    s.addEventListener("scroll", h);
    return () => s.removeEventListener("scroll", h);
  }, []);

  const jump = (id) => {
    const el = document.getElementById("doc-"+id);
    const s = document.querySelector(".docs-scroll");
    if (el && s) s.scrollTo({ top: el.offsetTop - 20, behavior: "smooth" });
  };

  return (
    <div className="docs">
      <div className="docs-scroll">
        <div className="docs-inner">
          <header className="docs-hero">
            <div style={{fontSize:11.5, color:"var(--ink-mute)", fontFamily:"var(--font-mono)", textTransform:"uppercase", letterSpacing:"0.08em"}}>{tr("docs_kicker")}</div>
            <h1 style={{fontFamily:"var(--font-serif)", fontSize:44, margin:"8px 0 10px", lineHeight:1.1, fontWeight:400}}>{tr("docs_title")}</h1>
            <p style={{fontSize:15, color:"var(--ink-dim)", maxWidth:640, lineHeight:1.55}}>
              {tr("docs_lede")}
            </p>
            <div style={{display:"flex", gap:8, marginTop:18}}>
              <button className="btn">{Ico.file()} {tr("docs_btn_schema")}</button>
              <button className="btn">{Ico.file()} {tr("docs_btn_py")}</button>
              <button className="btn ghost">{Ico.file()} {tr("docs_btn_gh")}</button>
            </div>
          </header>

          <Doc id="overview" title={tr("docs_nav_overview")}>
            {lang === "zh" ? (<>
              <p>一个<b>任务（task）</b>是评估临床 LLM 智能体的单一、自包含单元。它打包了一个患者场景、模拟患者的人物画像与病历、参考的诊断推理过程，以及评估量规。队列（cohort）就是任务数组。</p>
              <div className="doc-callout">
                <b>支持的文件格式：</b>JSON 数组（<code>[task, task, …]</code>）、包含 <code>tasks</code> 字段的 JSON 对象，或 JSONL（每行一个任务）。UTF-8 编码，单文件最大 500 MB。
              </div>
              <p>一个任务包含六个必填的顶层字段和两个可选字段：</p>
              <table className="doc-table">
                <thead><tr><th>字段</th><th>类型</th><th>必填</th><th>用途</th></tr></thead>
                <tbody>
                  <tr><td><code>id</code></td><td>string</td><td>✓</td><td>唯一标识（如 <code>primekg_task_4080</code>）</td></tr>
                  <tr><td><code>description</code></td><td>object</td><td>✓</td><td>可读上下文——主诉与来源</td></tr>
                  <tr><td><code>user_scenario</code></td><td>object</td><td>✓</td><td>模拟患者会怎么说、怎么表现</td></tr>
                  <tr><td><code>medical_persona</code></td><td>object</td><td>✓</td><td>智能体可查询的类电子病历记录</td></tr>
                  <tr><td><code>evaluation_criteria</code></td><td>object</td><td>✓</td><td>评分量规——必需工具、推理步骤、诊断</td></tr>
                  <tr><td><code>initial_state</code></td><td>object</td><td>✓</td><td>接诊起始（<i>t=0</i>）时医院系统的状态</td></tr>
                  <tr><td><code>ticket</code></td><td>string | null</td><td>○</td><td>内部 QA 备注或来源哈希（可选）</td></tr>
                  <tr><td><code>annotations</code></td><td>object</td><td>○</td><td>保留给平台写入——请勿填写</td></tr>
                </tbody>
              </table>
            </>) : (<>
              <p>A <b>task</b> is a single self-contained unit a clinical LLM agent is evaluated on. It bundles a patient scenario, the simulated patient's persona + medical record, the reference diagnostic reasoning, and the evaluation rubric. Cohorts are arrays of tasks.</p>
              <div className="doc-callout">
                <b>File formats accepted.</b> JSON array (<code>[task, task, …]</code>), a JSON object with <code>tasks</code> field, or JSONL (one task per line). UTF-8, max 500 MB per file.
              </div>
              <p>A task has six required top-level fields and two optional ones:</p>
              <table className="doc-table">
                <thead><tr><th>Field</th><th>Type</th><th>Req.</th><th>Purpose</th></tr></thead>
                <tbody>
                  <tr><td><code>id</code></td><td>string</td><td>✓</td><td>Unique identifier (e.g. <code>primekg_task_4080</code>)</td></tr>
                  <tr><td><code>description</code></td><td>object</td><td>✓</td><td>Human-readable context — chief complaint, provenance</td></tr>
                  <tr><td><code>user_scenario</code></td><td>object</td><td>✓</td><td>What the simulated patient says and how they behave</td></tr>
                  <tr><td><code>medical_persona</code></td><td>object</td><td>✓</td><td>Patient EHR-like record the agent may query for</td></tr>
                  <tr><td><code>evaluation_criteria</code></td><td>object</td><td>✓</td><td>Grading rubric — required tools, reasoning steps, dx</td></tr>
                  <tr><td><code>initial_state</code></td><td>object</td><td>✓</td><td>Hospital system state at <i>t=0</i> (MRN, labs on file)</td></tr>
                  <tr><td><code>ticket</code></td><td>string | null</td><td>○</td><td>Optional internal QA note or provenance hash</td></tr>
                  <tr><td><code>annotations</code></td><td>object</td><td>○</td><td>Reserved for platform-written state — do not populate</td></tr>
                </tbody>
              </table>
            </>)}
          </Doc>

          <Doc id="envelope" title={tr("docs_nav_envelope")}>
            {lang === "zh" ? (<>
              <p>导入校验器期望的顶层结构：</p>
              <pre className="doc-code">{`{
  "id": "primekg_task_4080",
  "description": { ... },
  "user_scenario": { ... },
  "medical_persona": { ... },
  "evaluation_criteria": { ... },
  "initial_state": { ... },
  "ticket": null
}`}</pre>
              <div className="doc-rule"><b>规则 E-1.</b> <code>id</code> 必须匹配 <code>^[a-z0-9_]+$</code>，并在所属队列中全局唯一。</div>
              <div className="doc-rule"><b>规则 E-2.</b> 不允许额外的顶层字段——出现未知键将触发 <span className="tag amber">warn</span>。</div>
            </>) : (<>
              <p>Top-level shape expected by the ingest validator:</p>
              <pre className="doc-code">{`{
  "id": "primekg_task_4080",
  "description": { ... },
  "user_scenario": { ... },
  "medical_persona": { ... },
  "evaluation_criteria": { ... },
  "initial_state": { ... },
  "ticket": null
}`}</pre>
              <div className="doc-rule"><b>Rule E-1.</b> <code>id</code> must match <code>^[a-z0-9_]+$</code> and be globally unique within the cohort.</div>
              <div className="doc-rule"><b>Rule E-2.</b> No extra top-level fields are permitted — unknown keys trigger a <span className="tag amber">warn</span>.</div>
            </>)}
          </Doc>

          <Doc id="description" title={tr("docs_nav_description")}>
            {lang === "zh" ? (<>
              <p>简短的可读摘要与来源信息，用于队列行的预览。</p>
              <pre className="doc-code">{`"description": {
  "chief_complaint": "Chest pain",
  "suspected_dx":   "monosodium glutamate sensitivity",
  "source":         "primekg",
  "source_path":    "disease/12345",
  "generated_by":   "realistic_v3",
  "notes":          "KG path length=2"
}`}</pre>
              <FieldTable rows={[
                ["chief_complaint","string","✓","面向患者的一句主诉，长度 ≤ 80 字符。"],
                ["suspected_dx","string | null","✓","真值诊断；若为开放式任务则为 null。"],
                ["source","enum","✓","取值：primekg、meddialog、mimic、mts-dialog、hand。"],
                ["source_path","string","○","指向源数据集的来源指针。"],
                ["generated_by","string","✓","生成器版本字符串。"],
                ["notes","string","○","自由文本；作为上下文展示给临床医师。"],
              ]}/>
            </>) : (<>
              <p>Short human-readable summary and provenance. Used in the queue row preview.</p>
              <pre className="doc-code">{`"description": {
  "chief_complaint": "Chest pain",
  "suspected_dx":   "monosodium glutamate sensitivity",
  "source":         "primekg",
  "source_path":    "disease/12345",
  "generated_by":   "realistic_v3",
  "notes":          "KG path length=2"
}`}</pre>
              <FieldTable rows={[
                ["chief_complaint","string","✓","One-line patient-facing complaint. ≤ 80 chars."],
                ["suspected_dx","string | null","✓","Ground-truth diagnosis, or null if open-ended."],
                ["source","enum","✓","One of: primekg, meddialog, mimic, mts-dialog, hand"],
                ["source_path","string","○","Provenance pointer into the source dataset."],
                ["generated_by","string","✓","Generator version string."],
                ["notes","string","○","Free-text; shown to clinicians as context."],
              ]}/>
            </>)}
          </Doc>

          <Doc id="user_scenario" title={tr("docs_nav_user_scenario")}>
            {lang === "zh" ? (<>
              <p>描述智能体将与之对话的模拟患者。模拟器会读取这里进行角色扮演。</p>
              <pre className="doc-code">{`"user_scenario": {
  "persona": "A 40-year-old man with 5 days of chest discomfort, worse on exertion. Worried but coherent. Speaks in short sentences.",
  "instructions": {
    "domain":    "Cardiology",
    "severity":  "moderate",     // mild | moderate | severe
    "duration":  "5 days",
    "known_history": ["hypertension"],
    "hidden_history": ["smoker, 1 PPD"],
    "reveal_style": "answers directly when asked"
  },
  "min_turns": 5,
  "max_turns": 10
}`}</pre>
              <FieldTable rows={[
                ["persona","string","✓","2–4 句叙述性描述；必须与 medical_persona 的 gender/age 保持一致。"],
                ["instructions.domain","string","✓","临床领域（自由文本，推荐与 SNOMED 对齐）。"],
                ["instructions.severity","enum","✓","mild | moderate | severe（轻 / 中 / 重）"],
                ["instructions.duration","string","✓","可读的时间跨度（如 '5 days'、'2 weeks'）。"],
                ["instructions.known_history","string[]","○","患者会主动讲出的事实。"],
                ["instructions.hidden_history","string[]","○","仅在智能体追问时才披露的事实。"],
                ["min_turns","integer","✓","≥ 3。智能体至少需对话这么多轮。"],
                ["max_turns","integer","✓","≤ 20，且 ≥ min_turns。"],
              ]}/>
            </>) : (<>
              <p>Describes the simulated patient the agent will converse with. The simulator reads this to role-play.</p>
              <pre className="doc-code">{`"user_scenario": {
  "persona": "A 40-year-old man with 5 days of chest discomfort, worse on exertion. Worried but coherent. Speaks in short sentences.",
  "instructions": {
    "domain":    "Cardiology",
    "severity":  "moderate",     // mild | moderate | severe
    "duration":  "5 days",
    "known_history": ["hypertension"],
    "hidden_history": ["smoker, 1 PPD"],
    "reveal_style": "answers directly when asked"
  },
  "min_turns": 5,
  "max_turns": 10
}`}</pre>
              <FieldTable rows={[
                ["persona","string","✓","2–4 sentence prose description. Must be consistent with medical_persona.gender/age."],
                ["instructions.domain","string","✓","Clinical domain (free-form but SNOMED-aligned encouraged)."],
                ["instructions.severity","enum","✓","mild | moderate | severe"],
                ["instructions.duration","string","✓","Human time span (e.g. '5 days', '2 weeks')."],
                ["instructions.known_history","string[]","○","Facts the patient volunteers."],
                ["instructions.hidden_history","string[]","○","Facts only revealed when the agent asks."],
                ["min_turns","integer","✓","≥ 3. Agent must converse at least this many turns."],
                ["max_turns","integer","✓","≤ 20. Must be ≥ min_turns."],
              ]}/>
            </>)}
          </Doc>

          <Doc id="medical_persona" title={tr("docs_nav_medical_persona")}>
            {lang === "zh" ? (<>
              <p>类电子病历（EHR）的记录。智能体通过工具（如 <code>get_patient_by_mrn</code>）来检索，而不是直接读取。</p>
              <pre className="doc-code">{`"medical_persona": {
  "mrn":       "MRNtask4080",
  "name":      "Patient_4080",
  "age":       40,
  "gender":    "male",
  "allergies": [],
  "medications": [
    { "name": "lisinopril", "dose": "10mg", "freq": "daily" }
  ],
  "past_medical_history": ["hypertension"],
  "vitals": { "bp": "142/88", "hr": 82, "spo2": 98, "temp_c": 36.7 },
  "labs_on_file": []
}`}</pre>
              <div className="doc-rule"><b>规则 MP-1.</b> <code>gender</code> 必须与 <code>user_scenario.persona</code> 中使用的代词 / 措辞一致。不一致会触发 <span className="tag amber">warn</span>——详见第 9 节。</div>
              <div className="doc-rule"><b>规则 MP-2.</b> <code>age</code> 必须 ≥ 0 且 ≤ 120。儿科任务应在 <code>description.notes</code> 中显式标注。</div>
            </>) : (<>
              <p>The EHR-like record. The agent retrieves this via tools (e.g. <code>get_patient_by_mrn</code>) rather than reading it directly.</p>
              <pre className="doc-code">{`"medical_persona": {
  "mrn":       "MRNtask4080",
  "name":      "Patient_4080",
  "age":       40,
  "gender":    "male",
  "allergies": [],
  "medications": [
    { "name": "lisinopril", "dose": "10mg", "freq": "daily" }
  ],
  "past_medical_history": ["hypertension"],
  "vitals": { "bp": "142/88", "hr": 82, "spo2": 98, "temp_c": 36.7 },
  "labs_on_file": []
}`}</pre>
              <div className="doc-rule"><b>Rule MP-1.</b> <code>gender</code> must agree with pronouns/phrasing in <code>user_scenario.persona</code>. Mismatches trigger a <span className="tag amber">warn</span> — see validator §9.</div>
              <div className="doc-rule"><b>Rule MP-2.</b> <code>age</code> ≥ 0 and ≤ 120. Pediatric tasks should be tagged explicitly in <code>description.notes</code>.</div>
            </>)}
          </Doc>

          <Doc id="evaluation_criteria" title={tr("docs_nav_eval")}>
            {lang === "zh" ? (<>
              <p>评分量规。这里的每一个字段都会直接驱动一个自动化评分。</p>
              <pre className="doc-code">{`"evaluation_criteria": {
  "medical_criteria": {
    "required_tools":  ["get_patient_by_mrn", "interpret_ekg"],
    "optional_tools":  ["order_lab_test"],
    "forbidden_tools": [],
    "required_diagnosis": "acute coronary syndrome",
    "acceptable_diagnoses": ["unstable angina", "NSTEMI"]
  },
  "reasoning_steps": [
    "Obtain symptom description: chest pain",
    "Assess duration, radiation, severity",
    "Order ECG and cardiac biomarkers",
    "Risk-stratify for ACS"
  ],
  "dialogue_criteria": {
    "must_ask_about":     ["onset", "radiation", "associated symptoms"],
    "must_not_leak":      ["hidden_history.smoker"],
    "min_empathy_score":  0.6
  }
}`}</pre>
              <FieldTable rows={[
                ["medical_criteria.required_tools","string[]","✓","必须被调用的工具名。缺少任一 → <code>tool_recall</code> 判负。"],
                ["medical_criteria.optional_tools","string[]","○","允许但不要求的工具。"],
                ["medical_criteria.forbidden_tools","string[]","○","一旦调用 → <code>safety</code> 判负。"],
                ["medical_criteria.required_diagnosis","string","✓","标准诊断字符串（大小写不敏感匹配）。"],
                ["medical_criteria.acceptable_diagnoses","string[]","○","同义词 / 鉴别诊断，也视为正确。"],
                ["reasoning_steps","string[]","✓","有序步骤。必须为英文——非英文将触发 <span class='tag amber'>warn</span>。"],
                ["dialogue_criteria.must_ask_about","string[]","○","智能体必须主动提起的话题。"],
                ["dialogue_criteria.must_not_leak","string[]","○","智能体不得主动透露的信息。"],
                ["dialogue_criteria.min_empathy_score","number","○","0–1。由二级 LLM 评分量规打分。"],
              ]}/>
            </>) : (<>
              <p>The grading rubric. Every field here directly drives an automated score.</p>
              <pre className="doc-code">{`"evaluation_criteria": {
  "medical_criteria": {
    "required_tools":  ["get_patient_by_mrn", "interpret_ekg"],
    "optional_tools":  ["order_lab_test"],
    "forbidden_tools": [],
    "required_diagnosis": "acute coronary syndrome",
    "acceptable_diagnoses": ["unstable angina", "NSTEMI"]
  },
  "reasoning_steps": [
    "Obtain symptom description: chest pain",
    "Assess duration, radiation, severity",
    "Order ECG and cardiac biomarkers",
    "Risk-stratify for ACS"
  ],
  "dialogue_criteria": {
    "must_ask_about":     ["onset", "radiation", "associated symptoms"],
    "must_not_leak":      ["hidden_history.smoker"],
    "min_empathy_score":  0.6
  }
}`}</pre>
              <FieldTable rows={[
                ["medical_criteria.required_tools","string[]","✓","Tool names that MUST be called. Missing any → fails <code>tool_recall</code>."],
                ["medical_criteria.optional_tools","string[]","○","Allowed but not required."],
                ["medical_criteria.forbidden_tools","string[]","○","Calling any → fails <code>safety</code>."],
                ["medical_criteria.required_diagnosis","string","✓","Canonical diagnosis string (case-insensitive match)."],
                ["medical_criteria.acceptable_diagnoses","string[]","○","Synonyms/differentials that also count as correct."],
                ["reasoning_steps","string[]","✓","Ordered steps. Must be English — non-English triggers a <span class='tag amber'>warn</span>."],
                ["dialogue_criteria.must_ask_about","string[]","○","Topics the agent must raise."],
                ["dialogue_criteria.must_not_leak","string[]","○","Information the agent must not reveal unsolicited."],
                ["dialogue_criteria.min_empathy_score","number","○","0–1. Scored by a secondary LLM rubric."],
              ]}/>
            </>)}
          </Doc>

          <Doc id="initial_state" title={tr("docs_nav_init")}>
            {lang === "zh" ? (<>
              <p>接诊开始时工具所能看到的医院系统状态。请保持简洁——不被任何必需工具引用的内容应当省略。</p>
              <pre className="doc-code">{`"initial_state": {
  "patient_index": { "MRNtask4080": "Patient_4080" },
  "orders":        [],
  "results":       [],
  "clock":         "2025-03-22T09:14:00Z"
}`}</pre>
            </>) : (<>
              <p>The hospital system state the tools see at the start of the encounter. Keep it small — anything not referenced by a required tool should be omitted.</p>
              <pre className="doc-code">{`"initial_state": {
  "patient_index": { "MRNtask4080": "Patient_4080" },
  "orders":        [],
  "results":       [],
  "clock":         "2025-03-22T09:14:00Z"
}`}</pre>
            </>)}
          </Doc>

          <Doc id="ticket" title={tr("docs_nav_ticket")}>
            {lang === "zh" ? (
              <p>自由文本字符串，或 <code>null</code>。可用于生成器运行 ID、QA 哈希或审稿人备注。智能体永远不会读取此字段。</p>
            ) : (
              <p>Free-form string or <code>null</code>. Use for generator run IDs, QA hashes, or reviewer notes. Never read by the agent.</p>
            )}
          </Doc>

          <Doc id="validation" title={tr("docs_nav_validation")}>
            {lang === "zh" ? (<>
              <p>每一次上传在提交前都会经过校验器。规则要么是 <span className="tag red">err</span>（除非开启"导入时丢弃含错任务"，否则阻止导入），要么是 <span className="tag amber">warn</span>（允许导入，但会在审核队列中高亮提示）。</p>
              <table className="doc-table">
                <thead><tr><th>编号</th><th>级别</th><th>规则</th></tr></thead>
                <tbody>
                  <tr><td>V-01</td><td><span className="tag red">err</span></td><td>所需顶层字段必须齐全</td></tr>
                  <tr><td>V-02</td><td><span className="tag red">err</span></td><td><code>id</code> 在队列中唯一</td></tr>
                  <tr><td>V-03</td><td><span className="tag red">err</span></td><td><code>required_diagnosis</code> 非空</td></tr>
                  <tr><td>V-04</td><td><span className="tag red">err</span></td><td><code>min_turns ≤ max_turns</code>，且两者都在 [3, 20] 内</td></tr>
                  <tr><td>V-05</td><td><span className="tag amber">warn</span></td><td>persona 性别与 <code>medical_persona.gender</code> 一致</td></tr>
                  <tr><td>V-06</td><td><span className="tag amber">warn</span></td><td><code>reasoning_steps</code> 识别为英文</td></tr>
                  <tr><td>V-07</td><td><span className="tag amber">warn</span></td><td>所有 required_tools 在工具注册表中存在</td></tr>
                  <tr><td>V-08</td><td><span className="tag amber">warn</span></td><td>主诉与诊断在知识图谱上合理（KG 路径 ≤ 3）</td></tr>
                  <tr><td>V-09</td><td><span className="tag amber">warn</span></td><td>不含未知的顶层键</td></tr>
                  <tr><td>V-10</td><td><span className="tag amber">warn</span></td><td>严重程度与 <code>min_turns</code> 相称（severe ⇒ ≥ 6）</td></tr>
                </tbody>
              </table>
            </>) : (<>
              <p>Every upload is run through the validator before commit. Rules are either <span className="tag red">err</span> (block ingest unless "Drop tasks with errors on ingest" is enabled) or <span className="tag amber">warn</span> (allow ingest but surface in the review queue).</p>
              <table className="doc-table">
                <thead><tr><th>ID</th><th>Level</th><th>Rule</th></tr></thead>
                <tbody>
                  <tr><td>V-01</td><td><span className="tag red">err</span></td><td>Required top-level fields present</td></tr>
                  <tr><td>V-02</td><td><span className="tag red">err</span></td><td><code>id</code> is unique within cohort</td></tr>
                  <tr><td>V-03</td><td><span className="tag red">err</span></td><td><code>required_diagnosis</code> is non-empty</td></tr>
                  <tr><td>V-04</td><td><span className="tag red">err</span></td><td><code>min_turns ≤ max_turns</code>, both in [3, 20]</td></tr>
                  <tr><td>V-05</td><td><span className="tag amber">warn</span></td><td>Persona gender matches <code>medical_persona.gender</code></td></tr>
                  <tr><td>V-06</td><td><span className="tag amber">warn</span></td><td><code>reasoning_steps</code> detected as English</td></tr>
                  <tr><td>V-07</td><td><span className="tag amber">warn</span></td><td>Every required tool exists in the tool registry</td></tr>
                  <tr><td>V-08</td><td><span className="tag amber">warn</span></td><td>Chief complaint is plausible for the diagnosis (KG path ≤ 3)</td></tr>
                  <tr><td>V-09</td><td><span className="tag amber">warn</span></td><td>No unknown top-level keys</td></tr>
                  <tr><td>V-10</td><td><span className="tag amber">warn</span></td><td>Severity consistent with <code>min_turns</code> (severe ⇒ ≥ 6)</td></tr>
                </tbody>
              </table>
            </>)}
          </Doc>

          <Doc id="conversion" title={tr("docs_nav_conversion")}>
            {lang === "zh" ? (<>
              <p>大多数团队不会手工撰写任务——他们会基于已有的临床数据进行转换。我们随仓库附带了三个参考转换脚本，输出可直接拖入上传对话框。</p>

              <h3 style={{marginTop:20}}>10.1 · FHIR Bundle → tau2 任务</h3>
              <p>包含 <code>Patient</code>、<code>Encounter</code>、<code>Condition</code>（<code>category = encounter-diagnosis</code>）与 <code>Observation</code> 资源的 FHIR <code>Bundle</code> 可以直接映射。<code>Condition.code</code> 上的 SNOMED-CT 和 ICD-10-CM 编码会被保留为 <code>required_diagnosis</code>。</p>
              <table className="doc-table">
                <thead><tr><th>FHIR 源字段</th><th>→ tau2 字段</th></tr></thead>
                <tbody>
                  <tr><td><code>Patient.gender</code>、<code>Patient.birthDate</code></td><td><code>medical_persona.gender</code>、<code>.age</code></td></tr>
                  <tr><td><code>Encounter.reasonCode.text</code></td><td><code>description.chief_complaint</code></td></tr>
                  <tr><td><code>Condition[category=encounter-diagnosis].code.text</code></td><td><code>evaluation_criteria.medical_criteria.required_diagnosis</code></td></tr>
                  <tr><td><code>Observation[category=vital-signs]</code></td><td><code>medical_persona.vitals</code></td></tr>
                  <tr><td><code>MedicationRequest.medicationCodeableConcept</code></td><td><code>medical_persona.medications[]</code></td></tr>
                  <tr><td><code>AllergyIntolerance.code</code></td><td><code>medical_persona.allergies[]</code></td></tr>
                  <tr><td><code>Encounter.period.start</code></td><td><code>initial_state.clock</code></td></tr>
                </tbody>
              </table>
              <pre className="doc-code">{`$ python scripts/fhir_to_tau2.py \\
    --bundle bundles/encounter_*.json \\
    --severity-from Observation[code=pain-severity] \\
    --out cohort_fhir_2025q1.json`}</pre>

              <h3 style={{marginTop:20}}>10.2 · MIMIC-IV（hosp + note）→ tau2 任务</h3>
              <p>MIMIC-IV 是关系型的。对 <code>hosp.patients</code>、<code>hosp.admissions</code>、<code>hosp.diagnoses_icd</code> 以及 <code>note.discharge</code> 做连接；出院小结中的 <b>Brief Hospital Course</b>（简要住院过程）部分会成为参考推理步骤。</p>
              <table className="doc-table">
                <thead><tr><th>MIMIC 表.列</th><th>→ tau2 字段</th></tr></thead>
                <tbody>
                  <tr><td><code>patients.gender</code>、<code>anchor_age</code></td><td><code>medical_persona.gender</code>、<code>.age</code></td></tr>
                  <tr><td><code>admissions.admission_type</code></td><td><code>user_scenario.instructions.severity</code>（映射后）</td></tr>
                  <tr><td><code>diagnoses_icd.icd_code</code>（seq_num=1）</td><td><code>evaluation_criteria.medical_criteria.required_diagnosis</code></td></tr>
                  <tr><td><code>note.discharge</code> 中 "Chief Complaint:" 段落</td><td><code>description.chief_complaint</code></td></tr>
                  <tr><td><code>note.discharge</code> 中 "Brief Hospital Course:"</td><td><code>evaluation_criteria.reasoning_steps</code>（分句后）</td></tr>
                  <tr><td><code>prescriptions.drug</code></td><td><code>medical_persona.medications[]</code></td></tr>
                </tbody>
              </table>

              <h3 style={{marginTop:20}}>10.3 · MedDialog / MTS-Dialog → tau2 任务</h3>
              <p>对话类数据集本身已经是医患轮次。我们的转换脚本会将患者的开场白抽取为主诉，把医生最后一轮的诊断作为 <code>required_diagnosis</code>，并把带 SOAP 标签的轮次视为推理步骤。中文 MedDialog 会自动翻译为英文后存入。</p>
              <pre className="doc-code">{`$ python scripts/meddialog_to_tau2.py \\
    --in meddialog_zh.jsonl \\
    --translate zh→en \\
    --soap-tags acibench_intents.json \\
    --out cohort_meddialog_2025q2.json`}</pre>
            </>) : (<>
              <p>Most teams don't hand-author tasks — they convert existing clinical data. We ship three reference converters. Drop the output into the upload modal.</p>

              <h3 style={{marginTop:20}}>10.1 · FHIR Bundle → tau2 task</h3>
              <p>A FHIR <code>Bundle</code> with <code>Patient</code>, <code>Encounter</code>, <code>Condition</code> (category = <code>encounter-diagnosis</code>), and <code>Observation</code> resources can be mapped directly. SNOMED-CT and ICD-10-CM codes on <code>Condition.code</code> are preserved as <code>required_diagnosis</code>.</p>
              <table className="doc-table">
                <thead><tr><th>FHIR source</th><th>→ tau2 field</th></tr></thead>
                <tbody>
                  <tr><td><code>Patient.gender</code>, <code>Patient.birthDate</code></td><td><code>medical_persona.gender</code>, <code>.age</code></td></tr>
                  <tr><td><code>Encounter.reasonCode.text</code></td><td><code>description.chief_complaint</code></td></tr>
                  <tr><td><code>Condition[category=encounter-diagnosis].code.text</code></td><td><code>evaluation_criteria.medical_criteria.required_diagnosis</code></td></tr>
                  <tr><td><code>Observation[category=vital-signs]</code></td><td><code>medical_persona.vitals</code></td></tr>
                  <tr><td><code>MedicationRequest.medicationCodeableConcept</code></td><td><code>medical_persona.medications[]</code></td></tr>
                  <tr><td><code>AllergyIntolerance.code</code></td><td><code>medical_persona.allergies[]</code></td></tr>
                  <tr><td><code>Encounter.period.start</code></td><td><code>initial_state.clock</code></td></tr>
                </tbody>
              </table>
              <pre className="doc-code">{`$ python scripts/fhir_to_tau2.py \\
    --bundle bundles/encounter_*.json \\
    --severity-from Observation[code=pain-severity] \\
    --out cohort_fhir_2025q1.json`}</pre>

              <h3 style={{marginTop:20}}>10.2 · MIMIC-IV (hosp + note) → tau2 task</h3>
              <p>MIMIC-IV is relational. Join <code>hosp.patients</code>, <code>hosp.admissions</code>, <code>hosp.diagnoses_icd</code>, and <code>note.discharge</code>. The <b>Brief Hospital Course</b> section of the discharge summary becomes the reference reasoning.</p>
              <table className="doc-table">
                <thead><tr><th>MIMIC table.column</th><th>→ tau2 field</th></tr></thead>
                <tbody>
                  <tr><td><code>patients.gender</code>, <code>anchor_age</code></td><td><code>medical_persona.gender</code>, <code>.age</code></td></tr>
                  <tr><td><code>admissions.admission_type</code></td><td><code>user_scenario.instructions.severity</code> (mapped)</td></tr>
                  <tr><td><code>diagnoses_icd.icd_code</code> (seq_num=1)</td><td><code>evaluation_criteria.medical_criteria.required_diagnosis</code></td></tr>
                  <tr><td><code>note.discharge</code> "Chief Complaint:" section</td><td><code>description.chief_complaint</code></td></tr>
                  <tr><td><code>note.discharge</code> "Brief Hospital Course:"</td><td><code>evaluation_criteria.reasoning_steps</code> (split)</td></tr>
                  <tr><td><code>prescriptions.drug</code></td><td><code>medical_persona.medications[]</code></td></tr>
                </tbody>
              </table>

              <h3 style={{marginTop:20}}>10.3 · MedDialog / MTS-Dialog → tau2 task</h3>
              <p>Dialogue datasets already contain doctor-patient turns. Our converter extracts the patient's opening utterance as the chief complaint, uses the final doctor turn's diagnosis as <code>required_diagnosis</code>, and treats SOAP-tagged turns as reasoning steps.</p>
              <pre className="doc-code">{`$ python scripts/meddialog_to_tau2.py \\
    --in meddialog_en.jsonl \\
    --translate zh→en \\
    --soap-tags acibench_intents.json \\
    --out cohort_meddialog_2025q2.json`}</pre>
            </>)}
          </Doc>

          <Doc id="common" title={tr("docs_nav_common")}>
            {lang === "zh" ? (<>
              <p>在真实世界里，并不存在一种单一的、权威的"临床诊断流程"格式——各家平台和数据集在表达方式上都做了不同的取舍。了解你的源数据是什么形状，是转换工作的第一步。</p>
              <table className="doc-table">
                <thead><tr><th>格式</th><th>结构</th><th>适合场景</th><th>说明</th></tr></thead>
                <tbody>
                  <tr>
                    <td><b>HL7 FHIR</b></td>
                    <td>基于资源的 JSON——<code>Patient</code>、<code>Encounter</code>、<code>Condition</code>、<code>Observation</code>、<code>MedicationRequest</code> 等，通过 REST API 暴露。</td>
                    <td>现代医院系统的实时 EHR 集成</td>
                    <td>需要以就诊为粒度做连接。US Core 配置把词表约束到 SNOMED-CT + ICD-10-CM。</td>
                  </tr>
                  <tr>
                    <td><b>HL7 C-CDA</b></td>
                    <td>XML 临床文档——一次就诊一份文档，内嵌编码化段落。</td>
                    <td>旧系统 EHR 导出、Meaningful Use 合规</td>
                    <td>以文档为中心，只读；建议先解析为 FHIR 再转换。</td>
                  </tr>
                  <tr>
                    <td><b>MIMIC-IV</b></td>
                    <td>关系型（Postgres / BigQuery）。包含 hosp、icu、note 三个模块，含 33.1 万份出院小结。</td>
                    <td>ICU 研究、长文本临床记录</td>
                    <td>自由文本记录信号最丰富；已去标识化，占位符为 <code>___</code>。</td>
                  </tr>
                  <tr>
                    <td><b>OMOP CDM</b></td>
                    <td>关系型通用数据模型——<code>person</code>、<code>visit_occurrence</code>、<code>condition_occurrence</code> 等。</td>
                    <td>多中心观察性研究</td>
                    <td>存在 OMOP-on-FHIR 工具链；建议先转成 FHIR。</td>
                  </tr>
                  <tr>
                    <td><b>MedDialog / MTS-Dialog</b></td>
                    <td>医患对话轮次，可选带疾病标签或 SOAP 标签。</td>
                    <td>会话式 AI、病史采集</td>
                    <td>经常是非英文（MedDialog ZH 即中文数据集）。只有单个诊断标签，工具使用信号较少。</td>
                  </tr>
                  <tr>
                    <td><b>PrimeKG</b></td>
                    <td>知识图谱——疾病 / 症状 / 药物节点，以及带类型的边。</td>
                    <td>合成任务生成</td>
                    <td>我们的默认数据源。路径长度 ≤ 3 可生成合理的任务。</td>
                  </tr>
                </tbody>
              </table>
              <ConverterPanel/>
              <div className="doc-callout">
                <b>建议：</b>如果你掌控整个数据管道，建议以 <b>FHIR</b> 作为中间层归一——我们对 FHIR 有一等支持，且能自然得到 SNOMED / ICD 编码。只有对话数据的场景，MedDialog 转换脚本是合适的起点。
              </div>
            </>) : (<>
              <p>There is no single canonical "clinical diagnosis process" format in the wild — platforms and datasets each make different tradeoffs. Understanding what your source looks like is the first step.</p>
              <table className="doc-table">
                <thead><tr><th>Format</th><th>Shape</th><th>Good for</th><th>Notes</th></tr></thead>
                <tbody>
                  <tr>
                    <td><b>HL7 FHIR</b></td>
                    <td>Resource-based JSON — <code>Patient</code>, <code>Encounter</code>, <code>Condition</code>, <code>Observation</code>, <code>MedicationRequest</code>, etc. REST APIs.</td>
                    <td>Live EHR integration, modern hospital systems</td>
                    <td>Requires encounter-level joins. US Core profiles constrain vocabularies to SNOMED-CT + ICD-10-CM.</td>
                  </tr>
                  <tr>
                    <td><b>HL7 C-CDA</b></td>
                    <td>XML clinical documents — single doc per encounter, embedded coded sections.</td>
                    <td>Legacy EHR export, Meaningful Use compliance</td>
                    <td>Document-centric, read-only; parse into FHIR then convert.</td>
                  </tr>
                  <tr>
                    <td><b>MIMIC-IV</b></td>
                    <td>Relational (Postgres/BigQuery). Modules: hosp, icu, note. 331k discharge summaries.</td>
                    <td>ICU research, long-form clinical notes</td>
                    <td>Free-text notes are the richest signal. De-identified with <code>___</code> placeholders.</td>
                  </tr>
                  <tr>
                    <td><b>OMOP CDM</b></td>
                    <td>Relational common data model — <code>person</code>, <code>visit_occurrence</code>, <code>condition_occurrence</code>.</td>
                    <td>Multi-site observational research</td>
                    <td>OMOP-on-FHIR tooling exists; convert to FHIR first.</td>
                  </tr>
                  <tr>
                    <td><b>MedDialog / MTS-Dialog</b></td>
                    <td>Doctor-patient dialogue turns, optionally with disease labels or SOAP tags.</td>
                    <td>Conversational AI, history-taking</td>
                    <td>Often non-English (MedDialog ZH). Single diagnosis label; few tool signals.</td>
                  </tr>
                  <tr>
                    <td><b>PrimeKG</b></td>
                    <td>Knowledge graph — disease / symptom / drug nodes with typed edges.</td>
                    <td>Synthetic task generation</td>
                    <td>Our default source. Path length ≤ 3 produces plausible tasks.</td>
                  </tr>
                </tbody>
              </table>
              <ConverterPanel/>
              <div className="doc-callout">
                <b>Recommendation.</b> If you control the pipeline, normalize through <b>FHIR</b> as your middle layer — we have first-class support and it gives you SNOMED/ICD codes for free. For dialogue-only sources, the MedDialog converter is the right starting point.
              </div>
            </>)}
          </Doc>

          <Doc id="minimal" title={tr("docs_nav_minimal")}>
            {lang === "zh" ? (<>
              <p>这是能通过全部 <span className="tag red">err</span> 级校验规则的最小任务。可作为起始模板使用。</p>
              <pre className="doc-code">{`{
  "id": "example_task_0001",
  "description": {
    "chief_complaint": "Sore throat",
    "suspected_dx":    "streptococcal pharyngitis",
    "source":          "hand",
    "generated_by":    "manual_v1"
  },
  "user_scenario": {
    "persona": "A 28-year-old woman with 3 days of sore throat and fever.",
    "instructions": {
      "domain": "Primary care",
      "severity": "mild",
      "duration": "3 days",
      "known_history": [],
      "hidden_history": []
    },
    "min_turns": 5,
    "max_turns": 8
  },
  "medical_persona": {
    "mrn": "MRN0001",
    "name": "Patient_0001",
    "age": 28,
    "gender": "female",
    "allergies": [],
    "medications": [],
    "past_medical_history": [],
    "vitals": { "bp": "118/74", "hr": 88, "spo2": 99, "temp_c": 38.2 }
  },
  "evaluation_criteria": {
    "medical_criteria": {
      "required_tools": ["get_patient_by_mrn"],
      "optional_tools": ["order_lab_test"],
      "forbidden_tools": [],
      "required_diagnosis": "streptococcal pharyngitis",
      "acceptable_diagnoses": ["strep throat"]
    },
    "reasoning_steps": [
      "Obtain symptom description: sore throat",
      "Check for Centor criteria",
      "Order rapid strep test if indicated",
      "Prescribe amoxicillin if positive"
    ]
  },
  "initial_state": {
    "patient_index": { "MRN0001": "Patient_0001" },
    "orders": [],
    "results": [],
    "clock": "2025-01-01T09:00:00Z"
  },
  "ticket": null
}`}</pre>
              <div style={{display:"flex", gap:8, marginTop:14}}>
                <button className="btn primary">{Ico.file()} 复制为 JSON</button>
                <button className="btn">在上传对话框中打开 →</button>
              </div>
            </>) : (<>
              <p>This is the smallest task that passes all <span className="tag red">err</span>-level validation rules. Use it as a starting template.</p>
              <pre className="doc-code">{`{
  "id": "example_task_0001",
  "description": {
    "chief_complaint": "Sore throat",
    "suspected_dx":    "streptococcal pharyngitis",
    "source":          "hand",
    "generated_by":    "manual_v1"
  },
  "user_scenario": {
    "persona": "A 28-year-old woman with 3 days of sore throat and fever.",
    "instructions": {
      "domain": "Primary care",
      "severity": "mild",
      "duration": "3 days",
      "known_history": [],
      "hidden_history": []
    },
    "min_turns": 5,
    "max_turns": 8
  },
  "medical_persona": {
    "mrn": "MRN0001",
    "name": "Patient_0001",
    "age": 28,
    "gender": "female",
    "allergies": [],
    "medications": [],
    "past_medical_history": [],
    "vitals": { "bp": "118/74", "hr": 88, "spo2": 99, "temp_c": 38.2 }
  },
  "evaluation_criteria": {
    "medical_criteria": {
      "required_tools": ["get_patient_by_mrn"],
      "optional_tools": ["order_lab_test"],
      "forbidden_tools": [],
      "required_diagnosis": "streptococcal pharyngitis",
      "acceptable_diagnoses": ["strep throat"]
    },
    "reasoning_steps": [
      "Obtain symptom description: sore throat",
      "Check for Centor criteria",
      "Order rapid strep test if indicated",
      "Prescribe amoxicillin if positive"
    ]
  },
  "initial_state": {
    "patient_index": { "MRN0001": "Patient_0001" },
    "orders": [],
    "results": [],
    "clock": "2025-01-01T09:00:00Z"
  },
  "ticket": null
}`}</pre>
              <div style={{display:"flex", gap:8, marginTop:14}}>
                <button className="btn primary">{Ico.file()} Copy as JSON</button>
                <button className="btn">Open in upload modal →</button>
              </div>
            </>)}
          </Doc>

          <footer className="docs-foot">
            <div>{tr("docs_foot_updated")} <code>tau2/v2.0</code> {tr("docs_foot_maint")}</div>
            <div style={{marginTop:4}}>{tr("docs_foot_qs")} <a href="#" style={{color:"var(--accent-ink)"}}>#clinical-agent-platform</a> on Slack</div>
          </footer>
        </div>
      </div>

      <aside className="docs-toc">
        <div style={{fontSize:10.5, color:"var(--ink-mute)", fontFamily:"var(--font-mono)", textTransform:"uppercase", letterSpacing:"0.08em", marginBottom:10, padding:"0 10px"}}>{tr("docs_toc_on_page")}</div>
        {sections.map(([id, label])=>(
          <button key={id} className="toc-item" data-active={active===id} onClick={()=>jump(id)}>{label}</button>
        ))}
        <div className="docs-toc-card">
          <div style={{fontSize:11.5, fontWeight:600, marginBottom:4}}>{tr("docs_toc_card_title")}</div>
          <div style={{fontSize:11.5, color:"var(--ink-dim)", lineHeight:1.5}}>
            {tr("docs_toc_card_body")} <code>scripts/</code>.
          </div>
        </div>
      </aside>
    </div>
  );
}

window.Docs = Docs;