deepseek-v4-flash-0731 @ high · dsh

dshhigh
config
deepseek-v4-flash-0731-eff-high--cli--dsh--dev
batch
2026-07-19--unified
transport
dsh-0.1.0-rc.8-headless-isolated-home
protocol
cli · api
served model
deepseek-v4-flash
采集于
2026年7月18日 11:54 · N=2
variant
live
slot 0 · P-q · sandboxed iframe
deepseek-v4-flash-0731 @high · dsh P-q slot 0 截图

输出带 markdown 围栏 — 模型把 HTML 包在代码围栏里返回,提取时已剥离;记录在此以便追溯。

截图是 similarity 通道测量时的原始像素。运行 live 会在 sandboxed iframe 中重新执行原始输出;渲染结果取决于你的浏览器和字体,不保证与测量像素一致。

similarity 邻居

限于 session 2026-07-19--unified

similarity 衡量本 session 内的趋同程度 —— 不是质量。

Fidelity —— 卡片展示的数据对不对?

  • namematch
  • conditionmatch
  • datematch
  • max tempambiguousinsufficient-distinct-temperature-nodes
  • min tempambiguousinsufficient-distinct-temperature-nodes
  • hourlyambiguouscoverage · 0 命中 · 0 不符 · 24 未展示
  • request sidematch0 处违规

extractor fidelity-extractor-v1+Berlin-2026-07-15

源码 —— 原始模型输出,一字节未改

下载 card.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1280">
<meta name="color-scheme" content="dark">
<title>Weather</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>⛅</text></svg>">
<style>
  :root{
    --ink:#eef2ff;
    --muted:#8ea0b8;
    --accent:#7dd3fc;
    --card-bg:rgba(13,18,34,.62);
  }
  *{box-sizing:border-box;margin:0;padding:0}
  [hidden]{display:none!important}
  html,body{height:100%}
  body{
    font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
    color:var(--ink);
    background:
      radial-gradient(1000px 640px at 88% -12%, rgba(99,102,241,.30), transparent 62%),
      radial-gradient(860px 600px at -12% 112%, rgba(14,165,233,.22), transparent 60%),
      radial-gradient(720px 520px at 52% 125%, rgba(168,85,247,.18), transparent 62%),
      linear-gradient(180deg,#0b1022,#070b16);
    min-height:100vh;
    display:grid;
    place-items:center;
    overflow:hidden;
    -webkit-font-smoothing:antialiased;
    text-rendering:optimizeLegibility;
  }
  .scene{position:relative;z-index:2;display:flex;flex-direction:column;align-items:center;gap:22px}
  .stars{
    position:fixed;inset:0;z-index:0;pointer-events:none;
    width:2px;height:2px;border-radius:50%;
    background:rgba(255,255,255,.55);
    animation:twinkle 5s ease-in-out infinite alternate;
  }
  @keyframes twinkle{from{opacity:.25}to{opacity:.9}}

  .card{
    position:relative;z-index:1;
    width:min(1180px,calc(100vw - 96px));
    height:640px;
    display:flex;
    border-radius:36px;
    overflow:hidden;
    background:var(--card-bg);
    border:1px solid rgba(255,255,255,.10);
    box-shadow:0 60px 120px -45px rgba(0,0,0,.85), 0 2px 0 rgba(255,255,255,.06) inset;
    backdrop-filter:blur(28px) saturate(1.25);
    -webkit-backdrop-filter:blur(28px) saturate(1.25);
    animation:rise .9s cubic-bezier(.16,1,.3,1) both;
  }
  @keyframes rise{from{opacity:0;transform:translateY(26px) scale(.985)}to{opacity:1;transform:none}}

  /* ---------- hero (left panel) ---------- */
  .hero{
    flex:0 0 388px;
    padding:46px 42px 42px;
    display:flex;flex-direction:column;justify-content:space-between;
    position:relative;overflow:hidden;
    background-image:linear-gradient(163deg,#334155 0%,#1e293b 55%,#0f172a 100%);
    transition:background 1.2s ease;
  }
  .hero::before{
    content:"";position:absolute;inset:0;pointer-events:none;
    background:
      radial-gradient(520px 300px at 18% -8%, rgba(255,255,255,.16), transparent 60%),
      radial-gradient(420px 300px at 110% 120%, rgba(255,255,255,.10), transparent 60%);
  }
  .hero>*{position:relative}
  .loc-row{display:flex;align-items:center;gap:10px;min-width:0}
  .loc-row svg{opacity:.92;flex:0 0 auto;filter:drop-shadow(0 2px 6px rgba(0,0,0,.35))}
  .loc{font-size:27px;font-weight:650;letter-spacing:-.01em;line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .date{margin-top:8px;font-size:13.5px;letter-spacing:.06em;color:rgba(255,255,255,.78)}
  .hero-mid{display:flex;flex-direction:column;align-items:center;text-align:center;margin:14px 0 10px}
  .icon{width:108px;height:108px;filter:drop-shadow(0 14px 26px rgba(0,0,0,.35))}
  .icon svg{width:100%;height:100%;display:block}
  .temp{
    font-size:118px;font-weight:200;letter-spacing:-.02em;line-height:1;
    font-variant-numeric:tabular-nums;margin-top:8px;
    text-shadow:0 18px 40px rgba(0,0,0,.28);
  }
  .cond{font-size:20px;font-weight:560;margin-top:14px;letter-spacing:.01em;opacity:.95}
  .chips{display:flex;gap:12px}
  .chip{
    display:flex;align-items:center;gap:11px;padding:10px 18px;border-radius:999px;
    background:rgba(255,255,255,.13);border:1px solid rgba(255,255,255,.17);
    backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
    box-shadow:0 10px 24px -12px rgba(0,0,0,.5);
  }
  .chip-k{font-size:10.5px;font-weight:650;letter-spacing:.14em;text-transform:uppercase;opacity:.7}
  .chip-v{font-size:21px;font-weight:620;font-variant-numeric:tabular-nums;line-height:1}
  .unit{font-size:11.5px;color:rgba(255,255,255,.62);letter-spacing:.05em;margin-top:16px;font-variant-numeric:tabular-nums}

  .hero-top{animation:fadeUp .7s .05s ease both}
  .hero-mid{animation:fadeUp .8s .15s ease both}
  .hero-bottom{animation:fadeUp .7s .28s ease both}
  @keyframes fadeUp{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
  .card.is-error .hero{filter:saturate(.55) brightness(.72)}

  /* ---------- detail (right panel) ---------- */
  .detail{flex:1;min-width:0;padding:44px 46px 40px;display:flex;flex-direction:column}
  .detail-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px}
  .title{font-size:12.5px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}
  .range{display:flex;align-items:center;gap:9px;font-size:13.5px;color:rgba(238,242,255,.78);font-variant-numeric:tabular-nums}
  .range .dot{width:7px;height:7px;border-radius:50%;background:var(--accent);box-shadow:0 0 12px var(--accent)}
  .chart{flex:1;min-height:0;margin-top:16px;position:relative;display:flex;flex-direction:column;justify-content:center;gap:16px}
  .chart-body{position:relative;width:100%;max-width:724px;margin:0 auto;aspect-ratio:660/360}
  .svgwrap{position:absolute;inset:0}
  .svgwrap svg{width:100%;height:100%;display:block}
  .chart-meta{display:flex;justify-content:center;gap:28px;font-size:12.5px;color:rgba(226,232,240,.72);font-variant-numeric:tabular-nums}
  .chart-meta b{font-weight:700}
  .chart-meta .hi{color:#fcd34d}
  .chart-meta .lo{color:#67e8f9}

  /* chart svg elements */
  .gridline{stroke:rgba(255,255,255,.08);stroke-dasharray:2 6}
  .glabel{fill:rgba(148,163,184,.5);font-size:10.5px;font-variant-numeric:tabular-nums}
  .tlabel{fill:rgba(148,163,184,.82);font-size:10.5px;letter-spacing:.05em;font-variant-numeric:tabular-nums}
  .vlabel{fill:rgba(226,232,240,.88);font-size:10.5px;font-weight:600;font-variant-numeric:tabular-nums}
  .pt{fill:#0a0f1e;stroke:rgba(226,232,240,.92);stroke-width:1.6;opacity:0;animation:pop .45s ease forwards}
  @keyframes pop{from{opacity:0}to{opacity:1}}
  .draw{stroke-dasharray:2400;stroke-dashoffset:2400;animation:draw 1.6s .2s cubic-bezier(.4,0,.2,1) forwards}
  @keyframes draw{to{stroke-dashoffset:0}}
  .hl{opacity:0;animation:pop .5s .95s ease forwards}
  .badge-text{font-size:11px;font-weight:700;stroke:rgba(9,13,26,.95);stroke-width:4px;paint-order:stroke}

  /* tooltip */
  .tip{position:absolute;inset:0;pointer-events:none;z-index:3;opacity:0;transition:opacity .18s}
  .tip.on{opacity:1}
  .tip .guide{
    position:absolute;top:6px;bottom:70px;width:1.5px;
    background:linear-gradient(180deg,rgba(255,255,255,.5),rgba(255,255,255,.12));
    border-radius:2px;transform:translateX(-50%);
  }
  .tip .bubble{
    position:absolute;padding:7px 12px;border-radius:11px;
    background:rgba(9,13,26,.94);border:1px solid rgba(255,255,255,.16);
    font-size:12.5px;font-weight:600;font-variant-numeric:tabular-nums;
    white-space:nowrap;transform:translate(-50%,-135%);
    box-shadow:0 12px 28px -10px rgba(0,0,0,.7);letter-spacing:.02em;
  }

  /* states */
  .spinner{
    position:absolute;inset:0;z-index:2;display:flex;flex-direction:column;
    align-items:center;justify-content:center;gap:18px;
    color:var(--muted);font-size:13.5px;letter-spacing:.04em;
  }
  .spinner .ring{
    width:46px;height:46px;border-radius:50%;
    border:3px solid rgba(255,255,255,.12);border-top-color:var(--accent);
    animation:spin 1s linear infinite;
  }
  @keyframes spin{to{transform:rotate(360deg)}}
  .err{
    position:absolute;inset:0;z-index:2;display:flex;flex-direction:column;
    align-items:center;justify-content:center;text-align:center;
    gap:10px;padding:30px;
  }
  .err-ico{width:54px;height:54px;margin-bottom:6px;opacity:.95}
  .err h3{font-size:19px;font-weight:600;letter-spacing:.01em}
  .err p{font-size:13.5px;color:var(--muted);max-width:430px;line-height:1.6}
  .btn-retry{
    margin-top:16px;padding:10px 22px;border-radius:999px;
    border:1px solid rgba(255,255,255,.22);background:rgba(255,255,255,.08);
    color:var(--ink);font-size:13px;font-weight:600;cursor:pointer;letter-spacing:.03em;
    font-family:inherit;transition:background .2s, transform .15s;
  }
  .btn-retry:hover{background:rgba(255,255,255,.16)}
  .btn-retry:active{transform:scale(.97)}

  .foot{font-size:11.5px;color:rgba(148,163,184,.65);letter-spacing:.06em;text-align:center}

  @media (prefers-reduced-motion:reduce){
    .card,.stars,.hero-top,.hero-mid,.hero-bottom{animation:none}
    .pt,.hl,.draw{animation:none!important;opacity:1!important;stroke-dashoffset:0!important}
    .tip{transition:none}
  }
</style>
</head>
<body>
  <main class="scene">
    <div class="stars" aria-hidden="true"></div>

    <div class="card" id="card">
      <!-- left: hero -->
      <section class="hero" id="hero" aria-label="Current conditions">
        <div class="hero-top">
          <div class="loc-row">
            <svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/>
              <circle cx="12" cy="10" r="3"/>
            </svg>
            <h1 class="loc" id="loc">…</h1>
          </div>
          <p class="date" id="date"></p>
        </div>

        <div class="hero-mid">
          <div class="icon" id="icon" aria-hidden="true"></div>
          <div class="temp" id="temp">–°</div>
          <div class="cond" id="cond"></div>
        </div>

        <div class="hero-bottom">
          <div class="chips">
            <span class="chip"><span class="chip-k">Max</span><span class="chip-v" id="maxV">–°</span></span>
            <span class="chip"><span class="chip-k">Min</span><span class="chip-v" id="minV">–°</span></span>
          </div>
          <p class="unit" id="coords"></p>
        </div>
      </section>

      <!-- right: hourly chart -->
      <section class="detail" aria-label="Hourly temperatures">
        <div class="detail-head">
          <h2 class="title">Hourly temperatures</h2>
          <span class="range" id="range"><span class="dot"></span>–</span>
        </div>

        <div class="chart" id="chart">
          <div class="spinner" id="spinner" hidden>
            <div class="ring"></div>
            <span>Loading weather…</span>
          </div>

          <div class="err" id="errBox" hidden role="alert" aria-live="polite">
            <svg class="err-ico" viewBox="0 0 96 96" fill="none" aria-hidden="true">
              <path d="M48 12 86 78 H10 Z" fill="#fbbf24" opacity=".9"/>
              <path d="M48 36 v18" stroke="#0f172a" stroke-width="6" stroke-linecap="round"/>
              <circle cx="48" cy="68" r="4" fill="#0f172a"/>
            </svg>
            <h3 id="errTitle">…</h3>
            <p id="errSub">…</p>
            <button class="btn-retry" id="retryBtn" type="button">Try again</button>
          </div>

          <div class="chart-body" id="chartBody" hidden>
            <div class="svgwrap" id="svgwrap"></div>
            <div class="tip" id="tip" hidden>
              <div class="guide"></div>
              <div class="bubble" id="bubble"></div>
            </div>
          </div>

          <p class="chart-meta" id="chartMeta" hidden></p>
        </div>
      </section>
    </div>

    <p class="foot">Open-Meteo API · same-origin · no key · timezone UTC · temperatures in °C</p>
  </main>

  <noscript><p style="color:#e2e8f0;padding:24px;text-align:center">This page needs JavaScript to load the weather data.</p></noscript>

<script>
(() => {
'use strict';

/* ================= helpers ================= */
const $ = (s, r = document) => r.querySelector(s);
const todayUTC = () => new Date().toISOString().slice(0, 10);

const q = new URLSearchParams(location.search);
const numParam = (key, def, lo, hi) => {
  const n = Number(q.get(key));
  return Number.isFinite(n) && n >= lo && n <= hi ? n : def;
};
let dateParam = q.get('date') || '';
if (!/^\d{4}-\d{2}-\d{2}$/.test(dateParam)) dateParam = todayUTC();

const CFG = {
  lat: numParam('lat', 52.52, -90, 90),
  lon: numParam('lon', 13.405, -180, 180),
  name: String(q.get('name') || 'Berlin').trim().slice(0, 80) || 'Berlin',
  date: dateParam
};
document.title = CFG.name + ' · Weather';

const fmtCoord = (v, pos, neg) => Math.abs(v).toFixed(2) + '°' + (v >= 0 ? pos : neg);
const HOUR_NOW = new Date().getUTCHours();
const isNight = CFG.date === todayUTC() && (HOUR_NOW < 6 || HOUR_NOW >= 18);

/* ================= weather codes (WMO) ================= */
function describe(code) {
  if (code === 0)         return { label: 'Clear sky',       group: 'clear' };
  if (code === 1)         return { label: 'Mainly clear',    group: 'partly' };
  if (code === 2)         return { label: 'Partly cloudy',   group: 'partly' };
  if (code === 3)         return { label: 'Overcast',        group: 'cloudy' };
  if (code === 45 || code === 48) return { label: 'Fog', group: 'fog' };
  if (code >= 51 && code <= 57)   return { label: 'Drizzle', group: 'rain' };
  if (code >= 61 && code <= 67)   return { label: 'Rain', group: 'rain' };
  if (code >= 71 && code <= 77)   return { label: 'Snow', group: 'snow' };
  if (code >= 80 && code <= 82)   return { label: 'Rain showers', group: 'rain' };
  if (code >= 85 && code <= 86)   return { label: 'Snow showers', group: 'snow' };
  if (code >= 95)                 return { label: 'Thunderstorm', group: 'thunder' };
  return { label: 'Cloudy', group: 'cloudy' };
}

/* ================= themes ================= */
const THEMES = {
  clear:    { g: ['#0ea5e9', '#3b82f6', '#4f46e5'], accent: '#7dd3fc', soft: 'rgba(125,211,252,.20)' },
  clearN:   { g: ['#1e1b4b', '#312e81', '#4c1d95'], accent: '#a5b4fc', soft: 'rgba(165,180,252,.20)' },
  partly:   { g: ['#38bdf8', '#6366f1', '#4338ca'], accent: '#fcd34d', soft: 'rgba(252,211,77,.16)' },
  partlyN:  { g: ['#0f172a', '#3730a3', '#4c1d95'], accent: '#c4b5fd', soft: 'rgba(196,181,253,.16)' },
  cloudy:   { g: ['#475569', '#334155', '#1e293b'], accent: '#cbd5e1', soft: 'rgba(203,213,225,.14)' },
  fog:      { g: ['#64748b', '#475569', '#334155'], accent: '#e2e8f0', soft: 'rgba(226,232,240,.14)' },
  rain:     { g: ['#3b82f6', '#1d4ed8', '#172554'], accent: '#93c5fd', soft: 'rgba(147,197,253,.18)' },
  snow:     { g: ['#7dd3fc', '#60a5fa', '#3b82f6'], accent: '#f0f9ff', soft: 'rgba(240,249,255,.22)' },
  thunder:  { g: ['#4c1d95', '#312e81', '#0f172a'], accent: '#fde047', soft: 'rgba(253,224,71,.18)' }
};

/* ================= SVG icons ================= */
const SUN_GRAD = '<linearGradient id="sunG" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#fde68a"/><stop offset="1" stop-color="#f59e0b"/></linearGradient>';
const MOON_GRAD = '<linearGradient id="moonG" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#eef2ff"/><stop offset="1" stop-color="#a5b4fc"/></linearGradient>';
const CLOUD_GRAD = '<linearGradient id="clG" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#e2e8f0"/><stop offset="1" stop-color="#94a3b8"/></linearGradient>';

const cloudShape = (fill) =>
  '<g fill="' + fill + '">' +
    '<circle cx="33" cy="57" r="14"/>' +
    '<circle cx="49" cy="49" r="17"/>' +
    '<circle cx="65" cy="57" r="13"/>' +
    '<rect x="24" y="53" width="50" height="16" rx="8"/>' +
  '</g>';

const ICONS = {
  sun: '<svg viewBox="0 0 96 96" fill="none"><defs>' + SUN_GRAD + '</defs>' +
    '<g stroke="url(#sunG)" stroke-width="5" stroke-linecap="round">' +
      '<line x1="48" y1="6" x2="48" y2="17"/><line x1="48" y1="79" x2="48" y2="90"/>' +
      '<line x1="6" y1="48" x2="17" y2="48"/><line x1="79" y1="48" x2="90" y2="48"/>' +
      '<line x1="18.3" y1="18.3" x2="26" y2="26"/><line x1="70" y1="70" x2="77.7" y2="77.7"/>' +
      '<line x1="18.3" y1="77.7" x2="26" y2="70"/><line x1="70" y1="26" x2="77.7" y2="18.3"/>' +
    '</g><circle cx="48" cy="48" r="21" fill="url(#sunG)"/></svg>',

  moon: '<svg viewBox="0 0 96 96" fill="none"><defs>' + MOON_GRAD + '</defs>' +
    '<path d="M58 14 A34 34 0 1 0 82 50 A26 26 0 0 1 58 14 Z" fill="url(#moonG)"/>' +
    '<g fill="#c7d2fe"><circle cx="22" cy="22" r="1.8"/><circle cx="31" cy="14" r="1.2"/><circle cx="12" cy="32" r="1.2"/></g></svg>',

  partlyDay: '<svg viewBox="0 0 96 96" fill="none"><defs>' + SUN_GRAD + CLOUD_GRAD + '</defs>' +
    '<g stroke="url(#sunG)" stroke-width="4.5" stroke-linecap="round">' +
      '<line x1="63" y1="11" x2="63" y2="17"/><line x1="63" y1="41" x2="63" y2="47"/>' +
      '<line x1="73" y1="21" x2="76.5" y2="24.5"/><line x1="73" y1="37" x2="76.5" y2="33.5"/>' +
      '<line x1="49.5" y1="21" x2="46" y2="24.5"/><line x1="49.5" y1="37" x2="46" y2="33.5"/>' +
    '</g>' +
    '<circle cx="63" cy="29" r="10" fill="url(#sunG)"/>' +
    '<g fill="url(#clG)"><circle cx="34" cy="58" r="13"/><circle cx="49" cy="51" r="16"/><circle cx="63" cy="58" r="12"/><rect x="26" y="54" width="46" height="15" rx="7.5"/></g></svg>',

  partlyNight: '<svg viewBox="0 0 96 96" fill="none"><defs>' + MOON_GRAD + CLOUD_GRAD + '</defs>' +
    '<path d="M64 20 A16 16 0 1 0 76 34 A12 12 0 0 1 64 20 Z" fill="url(#moonG)"/>' +
    '<g fill="#c7d2fe"><circle cx="40" cy="18" r="1.4"/><circle cx="34" cy="30" r="1.1"/></g>' +
    '<g fill="url(#clG)"><circle cx="34" cy="58" r="13"/><circle cx="49" cy="51" r="16"/><circle cx="63" cy="58" r="12"/><rect x="26" y="54" width="46" height="15" rx="7.5"/></g></svg>',

  cloudy: '<svg viewBox="0 0 96 96" fill="none"><defs>' + CLOUD_GRAD + '</defs>' + cloudShape('url(#clG)') + '</svg>',

  fog: '<svg viewBox="0 0 96 96" fill="none"><defs>' + CLOUD_GRAD + '</defs>' + cloudShape('url(#clG)') +
    '<g stroke="#e2e8f0" stroke-width="4" stroke-linecap="round">' +
      '<line x1="26" y1="77" x2="70" y2="77"/><line x1="32" y1="85" x2="63" y2="85"/>' +
    '</g></svg>',

  rain: '<svg viewBox="0 0 96 96" fill="none"><defs>' + CLOUD_GRAD + '</defs>' + cloudShape('url(#clG)') +
    '<g stroke="#7dd3fc" stroke-width="4" stroke-linecap="round">' +
      '<line x1="31" y1="72" x2="25" y2="84"/><line x1="46" y1="72" x2="40" y2="84"/><line x1="61" y1="72" x2="55" y2="84"/>' +
    '</g></svg>',

  snow: '<svg viewBox="0 0 96 96" fill="none"><defs>' + CLOUD_GRAD + '</defs>' + cloudShape('url(#clG)') +
    '<g stroke="#e0f2fe" stroke-width="2.6" stroke-linecap="round">' +
      '<line x1="31" y1="72" x2="31" y2="84"/><line x1="25" y1="78" x2="37" y2="78"/>' +
      '<line x1="46" y1="72" x2="46" y2="84"/><line x1="40" y1="78" x2="52" y2="78"/>' +
      '<line x1="61" y1="72" x2="61" y2="84"/><line x1="55" y1="78" x2="67" y2="78"/>' +
    '</g></svg>',

  thunder: '<svg viewBox="0 0 96 96" fill="none"><defs>' + CLOUD_GRAD + '</defs>' + cloudShape('url(#clG)') +
    '<polygon points="50,56 36,72 45,72 38,90 62,68 52,68 58,56" fill="#fde047"/>' +
    '</svg>'
};

/* ================= smooth line ================= */
function smoothPath(pts) {
  if (pts.length < 2) return '';
  let d = 'M ' + pts[0][0].toFixed(1) + ',' + pts[0][1].toFixed(1);
  for (let i = 0; i < pts.length - 1; i++) {
    const p0 = pts[Math.max(0, i - 1)], p1 = pts[i], p2 = pts[i + 1], p3 = pts[Math.min(pts.length - 1, i + 2)];
    const c1x = p1[0] + (p2[0] - p0[0]) / 6, c1y = p1[1] + (p2[1] - p0[1]) / 6;
    const c2x = p2[0] - (p3[0] - p1[0]) / 6, c2y = p2[1] - (p3[1] - p1[1]) / 6;
    d += ' C ' + c1x.toFixed(1) + ',' + c1y.toFixed(1) + ' ' + c2x.toFixed(1) + ',' + c2y.toFixed(1) + ' ' + p2[0].toFixed(1) + ',' + p2[1].toFixed(1);
  }
  return d;
}

/* ================= chart renderer ================= */
function renderChart(wrap, times, temps, theme, extremes) {
  const n = times.length;
  const W = 660, H = 360, L = 48, R = 652, T = 34, B = 236;
  const minT = Math.min.apply(null, temps), maxT = Math.max.apply(null, temps);
  const span = (maxT - minT) || 1;
  const pad = span * 0.16;
  const lo = minT - pad, hi = maxT + pad;
  const X = i => L + (R - L) * (n === 1 ? 0.5 : i / (n - 1));
  const Y = v => T + (B - T) * (1 - (v - lo) / (hi - lo));

  const pts = times.map((t, i) => ({ x: X(i), y: Y(temps[i]), t: temps[i], hour: parseInt(t.slice(11, 13), 10) }));

  const linePath = smoothPath(pts.map(p => [p.x, p.y]));
  const areaPath = linePath + ' L' + pts[n - 1].x.toFixed(1) + ',' + B + ' L' + pts[0].x.toFixed(1) + ',' + B + ' Z';

  /* gridlines */
  let grid = '';
  [0.25, 0.5, 0.75].forEach(f => {
    const v = lo + (hi - lo) * f;
    const y = Y(v);
    grid += '<line class="gridline" x1="' + L + '" y1="' + y.toFixed(1) + '" x2="' + R + '" y2="' + y.toFixed(1) + '"/>' +
            '<text class="glabel" x="' + (L - 10) + '" y="' + (y + 3.5).toFixed(1) + '" text-anchor="end">' + Math.round(v) + '°</text>';
  });

  /* time labels every 3 h */
  let tlabels = '';
  for (let i = 0; i < n; i += 3) {
    tlabels += '<text class="tlabel" x="' + pts[i].x.toFixed(1) + '" y="' + (B + 26) + '" text-anchor="middle">' +
      String(pts[i].hour).padStart(2, '0') + ':00</text>';
  }

  /* value labels every 6 h */
  let vlabels = '';
  for (let i = 0; i < n; i += 6) {
    vlabels += '<text class="vlabel" x="' + pts[i].x.toFixed(1) + '" y="' + (pts[i].y - 13).toFixed(1) + '" text-anchor="middle">' + Math.round(pts[i].t) + '°</text>';
  }

  /* dots */
  let dots = '';
  for (let i = 0; i < n; i++) {
    dots += '<circle class="pt" cx="' + pts[i].x.toFixed(1) + '" cy="' + pts[i].y.toFixed(1) + '" r="3.6" style="animation-delay:' + (0.3 + i * 0.035).toFixed(2) + 's"/>';
  }

  /* max / min badges */
  const clampX = (x, padX) => Math.min(Math.max(x, padX), W - padX);
  const hiP = pts[extremes.peakIdx], loP = pts[extremes.lowIdx];
  const badge = (p, color, above) =>
    '<g class="hl">' +
      '<circle cx="' + p.x.toFixed(1) + '" cy="' + p.y.toFixed(1) + '" r="7" fill="rgba(9,13,26,.9)" stroke="' + color + '" stroke-width="2"/>' +
      '<text class="badge-text" x="' + p.x.toFixed(1) + '" y="' + (p.y + (above ? -14 : 20)).toFixed(1) + '" text-anchor="middle" fill="' + color + '">' +
        Math.round(p.t) + '°' +
      '</text>' +
    '</g>';
  const extras =
    badge({ x: clampX(hiP.x, 40), y: hiP.y }, '#fcd34d', true) +
    badge({ x: clampX(loP.x, 44), y: loP.y }, '#67e8f9', false);

  /* "now" marker when the requested date is today */
  let nowMark = '';
  if (CFG.date === todayUTC()) {
    const i = Math.min(Math.max(HOUR_NOW, 0), n - 1);
    const nx = pts[i].x;
    nowMark =
      '<g>' +
        '<line x1="' + nx.toFixed(1) + '" y1="' + (T - 4) + '" x2="' + nx.toFixed(1) + '" y2="' + B + '" stroke="rgba(255,255,255,.35)" stroke-dasharray="3 5"/>' +
        '<rect x="' + (nx - 21).toFixed(1) + '" y="' + (T - 27) + '" width="42" height="17" rx="8.5" fill="rgba(255,255,255,.16)"/>' +
        '<text x="' + nx.toFixed(1) + '" y="' + (T - 15) + '" text-anchor="middle" fill="#fff" style="font-size:10px;font-weight:700;letter-spacing:.08em">NOW</text>' +
      '</g>';
  }

  const svg =
    '<svg viewBox="0 0 ' + W + ' ' + H + '" preserveAspectRatio="xMidYMid meet" role="img" aria-label="Hourly temperatures for ' + CFG.date + '">' +
      '<defs>' +
        '<linearGradient id="areaG" x1="0" y1="0" x2="0" y2="1">' +
          '<stop offset="0" stop-color="' + theme.soft + '"/>' +
          '<stop offset="1" stop-color="rgba(0,0,0,0)"/>' +
        '</linearGradient>' +
        '<linearGradient id="lineG" x1="0" y1="0" x2="1" y2="0">' +
          '<stop offset="0" stop-color="' + theme.accent + '"/>' +
          '<stop offset="1" stop-color="#a5b4fc"/>' +
        '</linearGradient>' +
      '</defs>' +
      grid + tlabels + vlabels +
      '<path class="area" d="' + areaPath + '" fill="url(#areaG)"/>' +
      '<path class="draw" d="' + linePath + '" fill="none" stroke="url(#lineG)" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>' +
      dots + extras + nowMark +
    '</svg>';

  wrap.innerHTML = svg;

  /* hover tooltip */
  const tip = document.getElementById('tip');
  const bubble = document.getElementById('bubble');
  const guide = tip.querySelector('.guide');
  wrap.addEventListener('mousemove', e => {
    const rect = wrap.getBoundingClientRect();
    const frac = (e.clientX - rect.left) / rect.width;
    const i = Math.max(0, Math.min(n - 1, Math.round(frac * (n - 1))));
    const p = pts[i];
    const xpct = (p.x / W) * 100, ypct = (p.y / H) * 100;
    guide.style.left = xpct + '%';
    bubble.style.left = xpct + '%';
    bubble.style.top = ypct + '%';
    bubble.textContent = String(p.hour).padStart(2, '0') + ':00  ·  ' + Math.round(p.t) + '°C';
    tip.classList.add('on');
  });
  wrap.addEventListener('mouseleave', () => tip.classList.remove('on'));
}

/* ================= DOM refs ================= */
const cardEl = document.getElementById('card');
const heroEl = document.getElementById('hero');
const heroIcon = document.getElementById('icon');
const heroTemp = document.getElementById('temp');
const heroCond = document.getElementById('cond');
const maxV = document.getElementById('maxV');
const minV = document.getElementById('minV');
const locEl = document.getElementById('loc');
const dateEl = document.getElementById('date');
const coordsEl = document.getElementById('coords');
const rangeEl = document.getElementById('range');
const metaEl = document.getElementById('chartMeta');
const spinner = document.getElementById('spinner');
const errBox = document.getElementById('errBox');
const errTitle = document.getElementById('errTitle');
const errSub = document.getElementById('errSub');
const chartBody = document.getElementById('chartBody');
const svgwrap = document.getElementById('svgwrap');
const tip = document.getElementById('tip');

/* ================= view state ================= */
const dateLine = (() => {
  const d = new Date(CFG.date + 'T00:00:00Z');
  const fmt = d.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric', timeZone: 'UTC' });
  const diff = Math.round((Date.parse(CFG.date + 'T00:00:00Z') - Date.parse(todayUTC() + 'T00:00:00Z')) / 864e5);
  const when = diff === 0 ? 'Today' : diff === 1 ? 'Tomorrow' : diff === -1 ? 'Yesterday' : '';
  return when ? when + ' · ' + fmt : fmt;
})();

const coordsLine = fmtCoord(CFG.lat, 'N', 'S') + '  ·  ' + fmtCoord(CFG.lon, 'E', 'W') + '  ·  UTC  ·  °C';

function setLoading() {
  locEl.textContent = CFG.name;
  dateEl.textContent = dateLine;
  coordsEl.textContent = coordsLine;
  heroTemp.textContent = '–°';
  heroCond.textContent = 'Loading…';
  maxV.textContent = '–°';
  minV.textContent = '–°';
  spinner.hidden = false;
  errBox.hidden = true;
  chartBody.hidden = true;
  metaEl.hidden = true;
  tip.hidden = true;
}

function paint({ max, min, code, hours }) {
  spinner.hidden = true;
  const desc = describe(code);
  const nightKey =
    desc.group === 'clear' ? (isNight ? 'clearN' : 'clear') :
    desc.group === 'partly' ? (isNight ? 'partlyN' : 'partly') : desc.group;
  const theme = THEMES[nightKey];

  heroEl.style.backgroundImage = 'linear-gradient(163deg, ' + theme.g[0] + ' 0%, ' + theme.g[1] + ' 55%, ' + theme.g[2] + ' 100%)';
  document.documentElement.style.setProperty('--accent', theme.accent);

  const iconKey = {
    clear: isNight ? 'moon' : 'sun',
    partly: isNight ? 'partlyNight' : 'partlyDay',
    cloudy: 'cloudy', fog: 'fog', rain: 'rain', snow: 'snow', thunder: 'thunder'
  }[desc.group];
  heroIcon.innerHTML = ICONS[iconKey];

  const hh = t => t.slice(11, 13) + ':00';
  const hMax = Math.max.apply(null, hours.map(p => p.v));
  const hMin = Math.min.apply(null, hours.map(p => p.v));
  const peakIdx = hours.findIndex(p => p.v === hMax);
  const lowIdx = hours.findIndex(p => p.v === hMin);

  heroTemp.textContent = Math.round(max) + '°';
  heroCond.textContent = desc.label;
  maxV.textContent = Math.round(max) + '°';
  minV.textContent = Math.round(min) + '°';
  rangeEl.innerHTML = '<span class="dot"></span>' + Math.round(hMin) + '° – ' + Math.round(hMax) + '°';
  metaEl.innerHTML =
    'Peak <b class="hi">' + Math.round(hMax) + '°</b> at ' + hh(hours[peakIdx].t) +
    ' &nbsp;·&nbsp; Low <b class="lo">' + Math.round(hMin) + '°</b> at ' + hh(hours[lowIdx].t);

  chartBody.hidden = false;
  metaEl.hidden = false;
  tip.hidden = false;
  renderChart(svgwrap, hours.map(p => p.t), hours.map(p => p.v), theme, { peakIdx, lowIdx });
}

function fail(title, sub) {
  cardEl.classList.add('is-error');
  heroEl.style.backgroundImage = 'linear-gradient(163deg, #334155 0%, #1e293b 60%, #0f172a 100%)';
  heroTemp.textContent = '—';
  heroCond.textContent = 'Unavailable';
  maxV.textContent = '–°';
  minV.textContent = '–°';
  rangeEl.innerHTML = '<span class="dot"></span>–';
  spinner.hidden = true;
  chartBody.hidden = true;
  metaEl.hidden = true;
  errTitle.textContent = title;
  errSub.textContent = sub;
  errBox.hidden = false;
}

/* ================= data ================= */
async function load() {
  const kind = CFG.date < todayUTC() ? 'archive' : 'forecast';
  const url = '/api/om/' + kind + '?' + new URLSearchParams({
    latitude: CFG.lat,
    longitude: CFG.lon,
    daily: 'temperature_2m_max,temperature_2m_min,weather_code',
    hourly: 'temperature_2m',
    timezone: 'UTC',
    temperature_unit: 'celsius',
    start_date: CFG.date,
    end_date: CFG.date
  });
  const res = await fetch(url, { headers: { Accept: 'application/json' } });
  if (!res.ok) throw new Error('The weather service responded with HTTP ' + res.status + '.');
  const data = await res.json();

  const d = data.daily || {}, h = data.hourly || {};
  const dTime = d.time || [], dMax = d.temperature_2m_max || [], dMin = d.temperature_2m_min || [], dCode = d.weather_code || [];
  const hTime = h.time || [], hTemp = h.temperature_2m || [];

  const idx = dTime.findIndex(t => String(t).slice(0, 10) === CFG.date);
  if (idx === -1) throw new Error('no-data');

  const hours = [];
  for (let i = 0; i < hTime.length; i++) {
    if (String(hTime[i]).slice(0, 10) === CFG.date && Number.isFinite(hTemp[i])) {
      hours.push({ t: hTime[i], v: hTemp[i] });
    }
  }
  if (hours.length < 2) throw new Error('no-data');

  const fallbackMax = Math.max.apply(null, hours.map(p => p.v));
  const fallbackMin = Math.min.apply(null, hours.map(p => p.v));
  return {
    max: Number.isFinite(dMax[idx]) ? dMax[idx] : fallbackMax,
    min: Number.isFinite(dMin[idx]) ? dMin[idx] : fallbackMin,
    code: dCode[idx],
    hours
  };
}

/* ================= boot ================= */
function boot() {
  /* starfield */
  const stars = [];
  for (let i = 0; i < 70; i++) {
    const x = (Math.random() * 100).toFixed(2), y = (Math.random() * 100).toFixed(2);
    const s = (Math.random() * 1.8 + 0.6).toFixed(2), o = (Math.random() * 0.45 + 0.25).toFixed(2);
    stars.push(x + 'vw ' + y + 'vh 0 ' + s + 'px rgba(255,255,255,' + o + ')');
  }
  document.querySelector('.stars').style.boxShadow = stars.join(', ');

  setLoading();
  load()
    .then(paint)
    .catch(err => {
      if (err && err.message === 'no-data') {
        fail('No weather data for this date',
          'The weather service returned no readings for ' + CFG.date + '. This date may be outside the supported range.');
      } else {
        fail('We couldn\u2019t load the weather data',
          (err && err.message ? err.message + ' ' : '') + 'Please check the connection and try again.');
      }
    });
}

document.getElementById('retryBtn').addEventListener('click', () => location.reload());
boot();
})();
</script>
</body>
</html>

L1 —— 廉价的确定性描述量

bytes 总计31,805html / css / js3,379 / 8,538 / 19,888
dom 节点60dom 深度9
css 规则84含 js是
brightness35.3contrast33.2
colorfulness69.1留白71.8%

该 slot 的 telemetry

prompt tokens8,449completion tokens53,882
total tokens62,331wall315.9 s
cost—request id—
config.json606 B
{
  "N": 2,
  "auth": {
    "credential_ref": "WCB_DEEPSEEK_KEY",
    "method": "api-key"
  },
  "billing": "api",
  "config_id": "deepseek-v4-flash-0731-eff-high--cli--dsh--dev",
  "effort": "high",
  "family": "deepseek",
  "m": {
    "min": 2,
    "q": 2
  },
  "model_id": "deepseek-v4-flash-0731",
  "protocol": "cli",
  "served_model": "deepseek-v4-flash",
  "telemetry": {
    "completion_tokens": 158003,
    "cost_usd": null,
    "prompt_tokens": 62140,
    "total_tokens": 220143,
    "wall_ms": 1433234
  },
  "transport": "dsh-0.1.0-rc.8-headless-isolated-home",
  "vendor_sanction_ref": null
}
send-log2.5 KB
{
  "N": 2,
  "batch_id": "2026-08-21--dsh-s1",
  "config_id": "deepseek-v4-flash-0731-eff-high--cli--dsh--dev",
  "positions": [
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-21T13:39:12.624375+00:00",
          "http_status": null,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-21T13:33:56.726642+00:00"
        }
      ],
      "block_index": 0,
      "model_reaching_attempt_index": 0,
      "slot_index": 0,
      "terminal_state": "valid",
      "variant": "P-q"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-21T13:50:09.754864+00:00",
          "http_status": null,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-21T13:39:16.459464+00:00"
        }
      ],
      "block_index": 0,
      "model_reaching_attempt_index": 0,
      "slot_index": 0,
      "terminal_state": "valid",
      "variant": "P-min"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-21T13:52:03.385941+00:00",
          "http_status": null,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-21T13:50:13.135783+00:00"
        }
      ],
      "block_index": 1,
      "model_reaching_attempt_index": 0,
      "slot_index": 1,
      "terminal_state": "valid",
      "variant": "P-min"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-21T13:58:01.050677+00:00",
          "http_status": null,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-21T13:52:07.303064+00:00"
        }
      ],
      "block_index": 1,
      "model_reaching_attempt_index": 0,
      "slot_index": 1,
      "terminal_state": "valid",
      "variant": "P-q"
    }
  ],
  "retry_policy": {
    "max_unreachable_retries": 5,
    "rate_limit_backoff": {
      "max_attempts": 4,
      "max_total_ms": 60000
    }
  }
}