glm-5.1 @ enabled · api

apienabled
config
glm-5.1-eff-enabled--api--official--dev
batch
2026-07-19--unified
transport
bigmodel-openai-compat
protocol
api · metered
served model
glm-5.1
采集于
2026年7月18日 11:54 · N=4
variant
live
slot 0 · P-q · sandboxed iframe
glm-5.1 @enabled · api P-q slot 0 截图

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

冻结后仍在变 — 时钟冻结之后页面还在继续改变,抓拍取的是冻结时刻的状态。

渲染不确定 — 同一份输入重复渲染会得到不同像素(随机/时间相关的内容),因此视觉通道对这张卡的读数不如其他卡稳定。

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

similarity 邻居

限于 session 2026-07-19--unified

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

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

  • namematch
  • conditionmatch
  • datematch
  • max tempambiguous展示值:25max-equals-min
  • min tempambiguous展示值:25max-equals-min
  • 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">
<title>Weather</title>
<style>
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
:root{
  --bg-1:#0B1120;--bg-2:#1A1A2E;
  --card-bg:rgba(15,25,45,0.72);
  --card-border:rgba(255,255,255,0.07);
  --accent:#F0963C;--accent-soft:rgba(240,150,60,0.13);
  --cool:#6AB4E0;--cool-soft:rgba(106,180,224,0.12);
  --text:#E8ECF1;--text-dim:#7A8BA0;
  --divider:rgba(255,255,255,0.07);
}
html,body{width:1280px;height:800px;overflow:hidden;
  font-family:'SF Pro Display',-apple-system,'Segoe UI','Helvetica Neue',sans-serif;
  color:var(--text);background:linear-gradient(155deg,var(--bg-1) 0%,var(--bg-2) 100%)}
body{display:flex;align-items:center;justify-content:center;position:relative}

/* Ambient background orbs */
.bg-orb{position:absolute;border-radius:50%;filter:blur(110px);pointer-events:none;transition:background 2.5s ease}
.orb-a{width:520px;height:520px;top:-160px;right:-120px;background:rgba(240,150,60,0.08);animation:dA 26s ease-in-out infinite}
.orb-b{width:420px;height:420px;bottom:-120px;left:-90px;background:rgba(240,150,60,0.05);animation:dB 32s ease-in-out infinite}
.orb-c{width:280px;height:280px;top:55%;left:58%;background:rgba(240,150,60,0.04);animation:dC 22s ease-in-out infinite}
@keyframes dA{0%,100%{transform:translate(0,0) scale(1)}33%{transform:translate(-40px,35px) scale(1.08)}66%{transform:translate(25px,-25px) scale(.94)}}
@keyframes dB{0%,100%{transform:translate(0,0) scale(1)}33%{transform:translate(35px,-40px) scale(1.06)}66%{transform:translate(-25px,25px) scale(1.1)}}
@keyframes dC{0%,100%{transform:translate(0,0)}50%{transform:translate(-30px,30px)}}

/* Noise grain overlay */
body::after{content:'';position:fixed;inset:0;
  background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.04'/%3E%3C/svg%3E");
  opacity:.45;pointer-events:none;z-index:0}

/* Card */
.card{width:900px;background:var(--card-bg);backdrop-filter:blur(44px);-webkit-backdrop-filter:blur(44px);
  border:1px solid var(--card-border);border-radius:28px;padding:52px;position:relative;z-index:1;
  animation:cardIn .85s cubic-bezier(.16,1,.3,1) both;
  box-shadow:0 8px 40px rgba(0,0,0,.35),inset 0 1px 0 rgba(255,255,255,.04)}
.card::before{content:'';position:absolute;top:0;left:48px;right:48px;height:1px;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.09),transparent);border-radius:1px}
@keyframes cardIn{from{opacity:0;transform:translateY(24px) scale(.97)}to{opacity:1;transform:none}}

/* Loading */
.loading-state{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:340px;gap:22px}
.spinner{width:38px;height:38px;border:3px solid var(--divider);border-top-color:var(--accent);border-radius:50%;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.loading-text{color:var(--text-dim);font-size:14px;letter-spacing:.6px;text-transform:uppercase;font-weight:500}

/* Error */
.error-state{display:none;flex-direction:column;align-items:center;justify-content:center;min-height:340px;gap:18px;text-align:center}
.error-icon{width:52px;height:52px;color:#E06060}
.error-title{font-size:18px;font-weight:700;color:var(--text);letter-spacing:-.2px}
.error-msg{font-size:14px;color:var(--text-dim);max-width:380px;line-height:1.6}

/* Content */
.content{display:none;animation:fadeUp .65s cubic-bezier(.16,1,.3,1) both}
@keyframes fadeUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}

/* Header */
.header{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:44px}
.location-name{font-size:24px;font-weight:700;letter-spacing:-.4px}
.date-display{font-size:14px;color:var(--text-dim);font-weight:400;letter-spacing:.2px}

/* Hero */
.hero{display:flex;align-items:center;gap:40px;margin-bottom:40px}
.icon-wrap{width:130px;height:130px;flex-shrink:0;display:flex;align-items:center;justify-content:center;animation:iconBob 5s ease-in-out infinite}
.icon-wrap svg{width:100%;height:100%}
@keyframes iconBob{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}
.temp-block{flex:1}
.main-temp{font-size:88px;font-weight:200;letter-spacing:-5px;line-height:.9;color:var(--text);margin-bottom:6px;
  text-shadow:0 0 80px rgba(240,150,60,.12)}
.condition{font-size:21px;font-weight:500;color:var(--text);opacity:.82;margin-bottom:16px}
.temp-range{display:flex;gap:14px}
.badge{display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border-radius:10px;font-size:13.5px;font-weight:600;letter-spacing:.1px}
.badge.hi{background:var(--accent-soft);color:#EEA04E}
.badge.lo{background:var(--cool-soft);color:#6AB4E0}
.badge .arr{font-size:10px;opacity:.7}

/* Divider */
.divider{height:1px;background:var(--divider);margin-bottom:34px}

/* Hourly */
.hourly-label{font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:1.6px;color:var(--text-dim);margin-bottom:20px}
.chart-wrap{width:100%;position:relative}
.chart-wrap canvas{width:100%;display:block}

/* Reduced motion */
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}
</style>
</head>
<body>

<div class="bg-orb orb-a" id="orbA"></div>
<div class="bg-orb orb-b" id="orbB"></div>
<div class="bg-orb orb-c" id="orbC"></div>

<main class="card" id="card">
  <div class="loading-state" id="loadState">
    <div class="spinner"></div>
    <div class="loading-text">Loading weather data</div>
  </div>
  <div class="error-state" id="errState">
    <svg class="error-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
      <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>
    </svg>
    <div class="error-title">Unable to load weather data</div>
    <div class="error-msg" id="errMsg">Please check your connection and try again.</div>
  </div>
  <div class="content" id="content"></div>
</main>

<script>
/* ═══════════════════════════════════════
   WMO Weather Code Mapping
   ═══════════════════════════════════════ */
const WMO = {
  0:{d:'Clear Sky',t:'clear'},1:{d:'Mainly Clear',t:'clear'},2:{d:'Partly Cloudy',t:'partial'},
  3:{d:'Overcast',t:'cloudy'},45:{d:'Foggy',t:'fog'},48:{d:'Rime Fog',t:'fog'},
  51:{d:'Light Drizzle',t:'rain'},53:{d:'Moderate Drizzle',t:'rain'},55:{d:'Dense Drizzle',t:'rain'},
  56:{d:'Freezing Drizzle',t:'rain'},57:{d:'Heavy Freezing Drizzle',t:'rain'},
  61:{d:'Light Rain',t:'rain'},63:{d:'Moderate Rain',t:'rain'},65:{d:'Heavy Rain',t:'rain'},
  66:{d:'Light Freezing Rain',t:'rain'},67:{d:'Heavy Freezing Rain',t:'rain'},
  71:{d:'Light Snow',t:'snow'},73:{d:'Moderate Snow',t:'snow'},75:{d:'Heavy Snow',t:'snow'},
  77:{d:'Snow Grains',t:'snow'},80:{d:'Light Showers',t:'rain'},81:{d:'Moderate Showers',t:'rain'},
  82:{d:'Violent Showers',t:'rain'},85:{d:'Light Snow Showers',t:'snow'},86:{d:'Heavy Snow Showers',t:'snow'},
  95:{d:'Thunderstorm',t:'storm'},96:{d:'Thunderstorm with Hail',t:'storm'},99:{d:'Thunderstorm with Heavy Hail',t:'storm'}
};

const THEMES = {
  clear:  {o1:'rgba(245,165,55,0.10)', o2:'rgba(250,200,80,0.07)', o3:'rgba(240,140,50,0.05)', bg2:'#1C1830'},
  partial:{o1:'rgba(230,160,60,0.08)', o2:'rgba(200,180,120,0.06)',o3:'rgba(180,170,140,0.04)', bg2:'#1A1D2C'},
  cloudy: {o1:'rgba(130,155,185,0.09)',o2:'rgba(150,170,195,0.06)',o3:'rgba(110,135,165,0.04)', bg2:'#1A2536'},
  rain:   {o1:'rgba(80,140,200,0.09)', o2:'rgba(65,120,180,0.06)', o3:'rgba(90,150,210,0.04)', bg2:'#121E2E'},
  snow:   {o1:'rgba(170,210,240,0.10)',o2:'rgba(190,220,245,0.07)',o3:'rgba(155,200,230,0.05)', bg2:'#182838'},
  storm:  {o1:'rgba(150,110,190,0.09)',o2:'rgba(130,90,170,0.06)', o3:'rgba(110,80,150,0.04)', bg2:'#121220'},
  fog:    {o1:'rgba(150,170,190,0.09)',o2:'rgba(165,185,205,0.06)',o3:'rgba(140,160,180,0.04)', bg2:'#1A2228'}
};

/* ═══════════════════════════════════════
   URL Parameter Parsing
   ═══════════════════════════════════════ */
const qs = new URLSearchParams(location.search);
const lat = parseFloat(qs.get('lat')) || 52.52;
const lon = parseFloat(qs.get('lon')) || 13.405;
const locName = qs.get('name') || 'Berlin';
const dateStr = qs.get('date') || new Date().toISOString().split('T')[0];

/* Determine past vs future for API selection */
const nowUTC = new Date(); nowUTC.setMinutes(nowUTC.getMinutes() + nowUTC.getTimezoneOffset());
const todayStr = nowUTC.toISOString().split('T')[0];
const apiBase = dateStr < todayStr ? '/api/om/archive' : '/api/om/forecast';

/* ═══════════════════════════════════════
   Utilities
   ═══════════════════════════════════════ */
function fmtDate(iso) {
  const d = new Date(iso + 'T00:00:00Z');
  return d.toLocaleDateString('en-US',{weekday:'long',year:'numeric',month:'long',day:'numeric',timeZone:'UTC'});
}
function esc(s) { const d=document.createElement('div'); d.textContent=s; return d.innerHTML; }
function wmo(code) { return WMO[code] || {d:'Unknown',t:'clear'}; }

/* ═══════════════════════════════════════
   SVG Weather Icons
   ═══════════════════════════════════════ */
function weatherSVG(code) {
  /* Sun rays helper */
  const rays = (cx,cy,inner,outer,w,op) => [0,45,90,135,180,225,270,315].map(a=>{
    const r=a*Math.PI/180;
    return `<line x1="${cx+Math.cos(r)*inner}" y1="${cy+Math.sin(r)*inner}" x2="${cx+Math.cos(r)*outer}" y2="${cy+Math.sin(r)*outer}" stroke="#FBBF24" stroke-width="${w}" stroke-linecap="round" opacity="${op}"/>`;
  }).join('');

  /* Cloud shape helper */
  const cloud = (cy,op) => `
    <ellipse cx="64" cy="${cy+14}" rx="30" ry="14" fill="#96A8BC" opacity="${op*.7}"/>
    <ellipse cx="48" cy="${cy+8}" rx="22" ry="13" fill="#A8B8CA" opacity="${op*.85}"/>
    <ellipse cx="80" cy="${cy+8}" rx="18" ry="11" fill="#A8B8CA" opacity="${op*.85}"/>
    <ellipse cx="62" cy="${cy+2}" rx="24" ry="14" fill="#B8C8D8" opacity="${op}"/>`;

  /* Clear / Mainly Clear */
  if (code <= 1) return `<svg viewBox="0 0 130 130" fill="none">
    <circle cx="65" cy="65" r="20" fill="#FBBF24" opacity=".9"><animate attributeName="r" values="20;22;20" dur="4s" repeatCount="indefinite"/></circle>
    <circle cx="65" cy="65" r="28" fill="none" stroke="#FBBF24" stroke-width="1" opacity=".18"><animate attributeName="r" values="28;32;28" dur="4s" repeatCount="indefinite"/></circle>
    ${rays(65,65,34,48,3,.6)}</svg>`;

  /* Partly Cloudy */
  if (code === 2) return `<svg viewBox="0 0 130 130" fill="none">
    <circle cx="50" cy="42" r="16" fill="#FBBF24" opacity=".75"/>
    ${rays(50,42,26,36,2.5,.4)}
    ${cloud(56,.92)}</svg>`;

  /* Overcast */
  if (code === 3) return `<svg viewBox="0 0 130 130" fill="none">${cloud(48,.95)}
    <ellipse cx="72" cy="68" rx="20" ry="10" fill="#8898A8" opacity=".6"/></svg>`;

  /* Fog */
  if (code === 45 || code === 48) return `<svg viewBox="0 0 130 130" fill="none">
    <line x1="22" y1="38" x2="108" y2="38" stroke="#B0C0D0" stroke-width="7" stroke-linecap="round" opacity=".35"/>
    <line x1="18" y1="56" x2="112" y2="56" stroke="#B8C8D8" stroke-width="7" stroke-linecap="round" opacity=".45"/>
    <line x1="26" y1="74" x2="104" y2="74" stroke="#C0D0E0" stroke-width="7" stroke-linecap="round" opacity=".4"/>
    <line x1="36" y1="92" x2="94" y2="92" stroke="#C8D8E8" stroke-width="7" stroke-linecap="round" opacity=".3"/></svg>`;

  /* Rain / Drizzle / Showers */
  if ([51,53,55,56,57,61,63,65,66,67,80,81,82].includes(code)) {
    const n = [51,56,80].includes(code)?4:[53,61,66,81].includes(code)?5:7;
    const drops = Array.from({length:n},(_,i)=>{
      const x=38+(i/(n-1))*50, y1=78+(i%2)*6, y2=y1+14+(i%3)*3;
      return `<line x1="${x}" y1="${y1}" x2="${x-3}" y2="${y2}" stroke="#68B0DC" stroke-width="2" stroke-linecap="round" opacity=".7">
        <animate attributeName="y1" values="${y1};${y1+5};${y1}" dur="${.7+i*.08}s" repeatCount="indefinite"/>
        <animate attributeName="y2" values="${y2};${y2+5};${y2}" dur="${.7+i*.08}s" repeatCount="indefinite"/>
        <animate attributeName="opacity" values=".7;.25;.7" dur="${.7+i*.08}s" repeatCount="indefinite"/></line>`;
    }).join('');
    return `<svg viewBox="0 0 130 130" fill="none">${cloud(40,.9)}${drops}</svg>`;
  }

  /* Snow */
  if ([71,73,75,77,85,86].includes(code)) {
    const flakes = Array.from({length:7},(_,i)=>{
      const x=34+(i/6)*52, y=78+(i%3)*8;
      return `<circle cx="${x}" cy="${y}" r="3" fill="#D4E8F8" opacity=".8">
        <animate attributeName="cy" values="${y};${y+7};${y}" dur="${1.3+i*.15}s" repeatCount="indefinite"/>
        <animate attributeName="opacity" values=".8;.3;.8" dur="${1.3+i*.15}s" repeatCount="indefinite"/></circle>`;
    }).join('');
    return `<svg viewBox="0 0 130 130" fill="none">${cloud(38,.9)}${flakes}</svg>`;
  }

  /* Thunderstorm */
  if ([95,96,99].includes(code)) {
    return `<svg viewBox="0 0 130 130" fill="none">
      ${cloud(34,.9).replace(/#96A8BC/g,'#6878A0').replace(/#A8B8CA/g,'#7888A8').replace(/#B8C8D8/g,'#8898B0')}
      <polygon points="66,58 56,80 63,80 53,100 77,74 68,74 76,58" fill="#FBBF24" opacity=".9">
        <animate attributeName="opacity" values=".9;.35;.9;.9;.25;.9" dur="2.8s" repeatCount="indefinite"/></polygon></svg>`;
  }

  /* Fallback */
  return `<svg viewBox="0 0 130 130" fill="none">
    <circle cx="65" cy="65" r="26" stroke="#7A8BA0" stroke-width="2.5" opacity=".4"/>
    <text x="65" y="72" text-anchor="middle" fill="#7A8BA0" font-size="22" font-family="sans-serif" opacity=".5">?</text></svg>`;
}

/* ═══════════════════════════════════════
   Apply Visual Theme
   ═══════════════════════════════════════ */
function applyTheme(name) {
  const t = THEMES[name] || THEMES.clear;
  document.documentElement.style.setProperty('--bg-2', t.bg2);
  document.getElementById('orbA').style.background = t.o1;
  document.getElementById('orbB').style.background = t.o2;
  document.getElementById('orbC').style.background = t.o3;
}

/* ═══════════════════════════════════════
   Hourly Temperature Chart (Canvas)
   ═══════════════════════════════════════ */
function drawChart(canvas, hourly) {
  const dpr = window.devicePixelRatio || 1;
  const W = canvas.parentElement.getBoundingClientRect().width;
  const H = 190;
  canvas.width = W * dpr; canvas.height = H * dpr;
  canvas.style.width = W + 'px'; canvas.style.height = H + 'px';
  const ctx = canvas.getContext('2d');
  ctx.scale(dpr, dpr);

  const ml=44, mr=16, mt=28, mb=32;
  const cw = W - ml - mr, ch = H - mt - mb;

  /* Filter valid data and build 24-slot array */
  const slots = new Array(24).fill(null);
  hourly.forEach(h => { if(h.temp!=null) slots[h.hour] = h.temp; });
  const valid = [];
  for (let i=0;i<24;i++) if(slots[i]!==null) valid.push({h:i,t:slots[i]});
  if (valid.length < 2) return;

  const temps = valid.map(v=>v.t);
  let minT = Math.floor(Math.min(...temps)) - 2;
  let maxT = Math.ceil(Math.max(...temps)) + 2;
  const rangeT = Math.max(maxT - minT, 1);

  const xOf = h => ml + (h / 23) * cw;
  const yOf = t => mt + (1 - (t - minT) / rangeT) * ch;

  /* Horizontal grid lines */
  const step = rangeT <= 8 ? 1 : rangeT <= 18 ? 2 : 5;
  ctx.strokeStyle = 'rgba(255,255,255,0.04)';
  ctx.lineWidth = 1;
  for (let t = Math.ceil(minT/step)*step; t <= maxT; t += step) {
    const y = yOf(t);
    ctx.beginPath(); ctx.moveTo(ml,y); ctx.lineTo(W-mr,y); ctx.stroke();
  }

  /* Build points */
  const pts = valid.map(v=>({x:xOf(v.h), y:yOf(v.t), t:v.t, h:v.h}));

  /* Smooth curve helper */
  function traceCurve() {
    ctx.beginPath();
    ctx.moveTo(pts[0].x, pts[0].y);
    for (let i=0; i<pts.length-1; i++) {
      const p0 = i>0 ? pts[i-1] : pts[0];
      const p1 = pts[i];
      const p2 = pts[i+1];
      const p3 = i<pts.length-2 ? pts[i+2] : pts[pts.length-1];
      const tn = 0.32;
      ctx.bezierCurveTo(
        p1.x + (p2.x-p0.x)*tn, p1.y + (p2.y-p0.y)*tn,
        p2.x - (p3.x-p1.x)*tn, p2.y - (p3.y-p1.y)*tn,
        p2.x, p2.y
      );
    }
  }

  /* Gradient fill under curve */
  const grad = ctx.createLinearGradient(0, mt, 0, mt+ch);
  grad.addColorStop(0, 'rgba(240,150,60,0.22)');
  grad.addColorStop(0.6, 'rgba(240,150,60,0.06)');
  grad.addColorStop(1, 'rgba(240,150,60,0.0)');
  traceCurve();
  ctx.lineTo(pts[pts.length-1].x, mt+ch);
  ctx.lineTo(pts[0].x, mt+ch);
  ctx.closePath();
  ctx.fillStyle = grad;
  ctx.fill();

  /* Glow line */
  traceCurve();
  ctx.strokeStyle = 'rgba(240,150,60,0.22)';
  ctx.lineWidth = 7;
  ctx.stroke();

  /* Main line */
  traceCurve();
  ctx.strokeStyle = '#F0963C';
  ctx.lineWidth = 2.5;
  ctx.lineCap = 'round';
  ctx.stroke();

  /* Dots */
  pts.forEach(p => {
    ctx.beginPath(); ctx.arc(p.x, p.y, 3.5, 0, Math.PI*2);
    ctx.fillStyle = '#F0963C'; ctx.fill();
    ctx.beginPath(); ctx.arc(p.x, p.y, 1.5, 0, Math.PI*2);
    ctx.fillStyle = '#FFF'; ctx.fill();
  });

  /* Time labels */
  ctx.font = '11.5px -apple-system, "Segoe UI", sans-serif';
  ctx.textAlign = 'center';
  ctx.fillStyle = 'rgba(122,139,160,0.75)';
  for (let h=0; h<=21; h+=3) {
    ctx.fillText(String(h).padStart(2,'0')+':00', xOf(h), mt+ch+22);
  }

  /* Temp labels every 3h */
  ctx.font = '600 11px -apple-system, "Segoe UI", sans-serif';
  ctx.fillStyle = 'rgba(232,236,241,0.65)';
  pts.forEach(p => {
    if (p.h % 3 === 0) {
      ctx.fillText(Math.round(p.t)+'°', p.x, p.y - 14);
    }
  });
}

/* ═══════════════════════════════════════
   Render Weather Card Content
   ═══════════════════════════════════════ */
function render(data) {
  const info = wmo(data.code);
  applyTheme(info.t);

  const el = document.getElementById('content');
  el.innerHTML = `
    <header class="header">
      <h1 class="location-name">${esc(locName)}</h1>
      <time class="date-display">${fmtDate(dateStr)}</time>
    </header>
    <section class="hero" aria-label="Current conditions">
      <div class="icon-wrap" role="img" aria-label="${esc(info.d)}">${weatherSVG(data.code)}</div>
      <div class="temp-block">
        <div class="main-temp">${Math.round(data.tMax)}°</div>
        <div class="condition">${esc(info.d)}</div>
        <div class="temp-range">
          <span class="badge hi"><span class="arr">▲</span> ${Math.round(data.tMax)}°C</span>
          <span class="badge lo"><span class="arr">▼</span> ${Math.round(data.tMin)}°C</span>
        </div>
      </div>
    </section>
    <div class="divider" role="separator"></div>
    <section aria-label="Hourly forecast">
      <div class="hourly-label">Hourly Temperature</div>
      <div class="chart-wrap"><canvas id="hChart"></canvas></div>
    </section>`;

  el.style.display = 'block';
  requestAnimationFrame(() => {
    const c = document.getElementById('hChart');
    if (c) drawChart(c, data.hourly);
  });
}

/* ═══════════════════════════════════════
   Error Display
   ═══════════════════════════════════════ */
function showError(msg) {
  document.getElementById('loadState').style.display = 'none';
  document.getElementById('errState').style.display = 'flex';
  document.getElementById('errMsg').textContent = msg || 'An unexpected error occurred.';
}

/* ═══════════════════════════════════════
   Fetch & Initialize
   ═══════════════════════════════════════ */
(async function init() {
  const url = `${apiBase}?latitude=${lat}&longitude=${lon}` +
    `&daily=temperature_2m_max,temperature_2m_min,weather_code` +
    `&hourly=temperature_2m&timezone=UTC&temperature_unit=celsius` +
    `&start_date=${dateStr}&end_date=${dateStr}`;

  try {
    const res = await fetch(url);
    if (!res.ok) throw new Error('Server returned ' + res.status);
    const json = await res.json();

    if (!json.daily || !json.hourly) throw new Error('Incomplete data received from the server');

    const tMax = json.daily.temperature_2m_max?.[0];
    const tMin = json.daily.temperature_2m_min?.[0];
    const code = json.daily.weather_code?.[0];

    if (tMax == null || tMin == null || code == null) throw new Error('Temperature or weather data is missing for the requested date');

    /* Process hourly */
    const times = json.hourly.time || [];
    const temps = json.hourly.temperature_2m || [];
    const hourly = [];
    for (let i = 0; i < times.length; i++) {
      if (times[i].startsWith(dateStr)) {
        const hr = parseInt(times[i].split('T')[1]?.split(':')[0], 10);
        if (!isNaN(hr)) hourly.push({hour: hr, temp: temps[i]});
      }
    }
    hourly.sort((a,b) => a.hour - b.hour);

    document.getElementById('loadState').style.display = 'none';
    render({tMax, tMin, code, hourly});

  } catch (err) {
    console.error('Weather fetch failed:', err);
    showError(err.message);
  }
})();
</script>
</body>
</html>

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

bytes 总计22,418html / css / js1,032 / 5,365 / 16,021
dom 节点23dom 深度5
css 规则61含 js
brightness27.4contrast11.6
colorfulness14.3留白97.2%

该 slot 的 telemetry

prompt tokens312completion tokens25,698
total tokens26,010wall380.7 s
costrequest id
config.json560 B
{
  "N": 4,
  "auth": {
    "credential_ref": "WCB_BIGMODEL_KEY",
    "method": "api-key"
  },
  "billing": "metered",
  "config_id": "glm-5.1-eff-enabled--api--official--dev",
  "effort": "enabled",
  "family": "glm",
  "m": {
    "min": 4,
    "q": 4
  },
  "model_id": "glm-5.1",
  "protocol": "api",
  "served_model": "glm-5.1",
  "telemetry": {
    "completion_tokens": 208497,
    "cost_usd": null,
    "prompt_tokens": 2464,
    "total_tokens": 210961,
    "wall_ms": 3016367
  },
  "transport": "bigmodel-openai-compat",
  "vendor_sanction_ref": null
}
send-log4.6 KB
{
  "N": 4,
  "batch_id": "2026-07-20--official-glm",
  "config_id": "glm-5.1-eff-enabled--api--official--dev",
  "positions": [
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-07-20T13:10:10.900587+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T13:03:50.221549+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-07-20T13:13:51.653204+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T13:10:15.938632+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-07-20T13:18:54.117343+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T13:13:54.580071+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-07-20T13:27:10.407351+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T13:18:58.236130+00:00"
        }
      ],
      "block_index": 1,
      "model_reaching_attempt_index": 0,
      "slot_index": 1,
      "terminal_state": "valid",
      "variant": "P-q"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-07-20T13:31:36.105847+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T13:27:14.266697+00:00"
        }
      ],
      "block_index": 2,
      "model_reaching_attempt_index": 0,
      "slot_index": 2,
      "terminal_state": "valid",
      "variant": "P-min"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-07-20T13:39:07.763731+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T13:31:39.581048+00:00"
        }
      ],
      "block_index": 2,
      "model_reaching_attempt_index": 0,
      "slot_index": 2,
      "terminal_state": "valid",
      "variant": "P-q"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-07-20T13:50:28.051070+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T13:39:10.778895+00:00"
        }
      ],
      "block_index": 3,
      "model_reaching_attempt_index": 0,
      "slot_index": 3,
      "terminal_state": "valid",
      "variant": "P-q"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-07-20T13:54:32.301184+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T13:50:31.272509+00:00"
        }
      ],
      "block_index": 3,
      "model_reaching_attempt_index": 0,
      "slot_index": 3,
      "terminal_state": "valid",
      "variant": "P-min"
    }
  ],
  "retry_policy": {
    "max_unreachable_retries": 5,
    "rate_limit_backoff": {
      "max_attempts": 4,
      "max_total_ms": 60000
    }
  }
}