{"id":17431,"date":"2026-09-14T12:34:40","date_gmt":"2026-09-14T03:34:40","guid":{"rendered":"https:\/\/f1-lap-time.com\/?page_id=17431"},"modified":"2026-09-14T13:04:24","modified_gmt":"2026-09-14T04:04:24","slug":"%e3%80%90%e3%82%b9%e3%83%9a%e3%82%a4%e3%83%b3gp%e3%80%91%e3%83%a9%e3%83%83%e3%83%97%e3%82%bf%e3%82%a4%e3%83%a0%e3%81%a8%e3%82%ae%e3%83%a3%e3%83%83%e3%83%97","status":"publish","type":"page","link":"https:\/\/f1-lap-time.com\/?page_id=17431","title":{"rendered":"\u3010\u30b9\u30da\u30a4\u30f3GP\u3011\u30e9\u30c3\u30d7\u30bf\u30a4\u30e0\u3068\u30ae\u30e3\u30c3\u30d7"},"content":{"rendered":"\n<!--\nWordPress\u300c\u30ab\u30b9\u30bf\u30e0HTML\u300d\u30d6\u30ed\u30c3\u30af\u306e\u65e2\u5b58\u30b3\u30fc\u30c9\u3092\u3001\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306e\u5168\u6587\u3067\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044\u3002\n\u4e0b\u306e DATA_FILE \u306f\u73fe\u5728\u3068\u540c\u3058\u76f8\u5bfeURL\u3067\u3059\u3002\u5fc5\u8981\u306b\u5fdc\u3058\u3066TSV\u306e\u516c\u958bURL\u3078\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n\u30c9\u30e9\u30a4\u30d0\u30fc\u306e\u4e26\u3073\u30fb\u540d\u524d\u30fb\u914d\u8272\u306f\u5143\u30b3\u30fc\u30c9\u3092\u7dad\u6301\u3057\u3066\u3044\u307e\u3059\u3002\n-->\n<style>\n.race-lap-widget{width:100%;max-width:1200px;background:#fff;color:#000;font-family:\"Times New Roman\",Times,serif;line-height:1.5}\n.race-lap-widget .race-controls{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:12px 0}\n.race-lap-widget .race-drivers{display:flex;flex-wrap:wrap;gap:6px}\n.race-lap-widget button,.race-lap-widget input,.race-lap-widget select{font:inherit;box-sizing:border-box;border:1px solid #aaa;border-radius:4px;box-shadow:none;text-transform:none;letter-spacing:normal;line-height:1.4}\n.race-lap-widget button{padding:6px 10px;background:#f5f5f5;color:#000;cursor:pointer;min-height:36px}\n.race-lap-widget button:disabled{cursor:wait;opacity:.5}\n.race-lap-widget button:focus-visible,.race-lap-widget input:focus-visible,.race-lap-widget select:focus-visible{outline:3px solid #2865c7;outline-offset:2px}\n.race-lap-widget .race-driver{font-weight:bold;border:2px solid transparent;min-width:62px}\n.race-lap-widget .race-driver[aria-pressed=\"true\"]{border-color:#000}\n.race-lap-widget .race-driver .race-check{display:inline-block;width:1em}\n.race-lap-widget label{display:inline-flex;align-items:center;gap:5px;color:#000;font-weight:normal;max-width:100%}\n.race-lap-widget label>span{white-space:nowrap;flex-shrink:0}\n.race-lap-widget .race-reference-label{flex-wrap:wrap;gap:8px}\n.race-lap-widget .race-reference{width:auto;min-width:150px;flex:0 1 auto}\n.race-lap-widget .race-language{justify-content:flex-end}\n.race-lap-widget [data-lang][aria-pressed=\"true\"]{background:#222;color:#fff;border-color:#222}\n.race-lap-widget input{width:105px;padding:6px;background:#fff;color:#000}\n.race-lap-widget select{padding:6px;background:#fff;color:#000;max-width:100%}\n.race-lap-widget .race-chart{width:100%;height:520px}\n.race-lap-widget .race-gap-chart{height:650px}\n.race-lap-widget .race-note{font-size:14px;margin:8px 0;color:#444}\n.race-lap-widget .race-error{color:#a40000;min-height:1.5em;margin:4px 0}\n.race-lap-widget h2{color:#000;margin:24px 0 10px;font-family:inherit}\n@media(max-width:600px){.race-lap-widget .race-chart{height:440px}.race-lap-widget .race-gap-chart{height:510px}}\n<\/style>\n\n<div id=\"raceLapWidget\" class=\"race-lap-widget\" lang=\"ja\">\n  <div class=\"race-controls race-language\" role=\"group\" aria-label=\"Language\"><button type=\"button\" data-lang=\"ja\" aria-pressed=\"true\">\u65e5\u672c\u8a9e<\/button><button type=\"button\" data-lang=\"en\" aria-pressed=\"false\">English<\/button><\/div>\n  <p class=\"race-status\" role=\"status\">\u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059\u2026<\/p>\n  <div class=\"race-interactive\" hidden>\n    <div class=\"race-controls\"><strong>Drivers:<\/strong><button type=\"button\" data-action=\"select\">Select All<\/button><button type=\"button\" data-action=\"clear\">Clear All<\/button><\/div>\n    <div class=\"race-drivers\" data-i18n-aria=\"driversAria\" aria-label=\"\u8868\u793a\u3059\u308b\u30c9\u30e9\u30a4\u30d0\u30fc\"><\/div>\n    <p class=\"race-note\"><span data-i18n=\"driversNote\">\u30c9\u30e9\u30a4\u30d0\u30fc\u3092\u9078\u3076\u3068\u4e21\u30b0\u30e9\u30d5\u306b\u8868\u793a\u3057\u307e\u3059\u3002\u51e1\u4f8b\u306f\u9078\u629e\u3057\u305f\u9806\u306b\u4e26\u3073\u307e\u3059\u3002<\/span><\/p>\n    <form class=\"race-controls\" data-form=\"laps\" novalidate>\n      <strong><span data-i18n=\"laps\">\u8868\u793a\u5468\u56de\uff08\u4e21\u30b0\u30e9\u30d5\u5171\u901a\uff09:<\/span><\/strong>\n      <label><span data-i18n=\"start\">\u958b\u59cb<\/span><input name=\"min\" type=\"number\" min=\"1\" step=\"1\" required><\/label>\n      <label><span data-i18n=\"end\">\u7d42\u4e86<\/span><input name=\"max\" type=\"number\" min=\"1\" step=\"1\" required><\/label>\n      <button type=\"submit\"><span data-i18n=\"apply\">\u9069\u7528<\/span><\/button><button type=\"button\" data-action=\"reset-laps\"><span data-i18n=\"allLaps\">\u5168\u5468\u56de\u306b\u623b\u3059<\/span><\/button>\n    <\/form>\n    <p class=\"race-error\" data-error=\"laps\" role=\"alert\"><\/p>\n    <h2>Lap Times<\/h2>\n    <form class=\"race-controls\" data-form=\"time\" novalidate>\n      <label><span>Fastest<\/span><input name=\"min\" type=\"text\" placeholder=\"1:20.000\" required aria-label=\"Fastest\"><\/label>\n      <label><span>Slowest<\/span><input name=\"max\" type=\"text\" placeholder=\"1:28.000\" required aria-label=\"Slowest\"><\/label>\n      <button type=\"submit\"><span data-i18n=\"apply\">\u9069\u7528<\/span><\/button><button type=\"button\" data-action=\"reset-time\"><span data-i18n=\"reset\">\u521d\u671f\u7bc4\u56f2\u306b\u623b\u3059<\/span><\/button>\n    <\/form>\n    <p class=\"race-note\"><span data-i18n=\"format\">\u30bf\u30a4\u30e0\u306f\u300c1:20.000\u300d\u307e\u305f\u306f\u300c80.000\u300d\u3067\u5165\u529b\u3067\u304d\u307e\u3059\u3002\u901f\u3044\u30bf\u30a4\u30e0\u3092\u4e0a\u306b\u8868\u793a\u3057\u307e\u3059\u3002<\/span><\/p>\n    <p class=\"race-error\" data-error=\"time\" role=\"alert\"><\/p>\n    <div class=\"race-chart race-time-chart\" data-i18n-aria=\"timeAria\" aria-label=\"\u30e9\u30c3\u30d7\u30bf\u30a4\u30e0\u30b0\u30e9\u30d5\"><\/div>\n    <p class=\"race-note\"><span data-i18n=\"white\">\u767d\u4e38\uff1a\u524d\u306e\u30c9\u30e9\u30a4\u30d0\u30fc\u3068\u306e\u5dee\u304c2\u79d2\u4ee5\u5185\u3002<\/span><\/p>\n    <h2 class=\"race-gap-title\">Gap to Leader<\/h2>\n    <div class=\"race-controls\"><label class=\"race-reference-label\"><span data-i18n=\"reference\">\u6bd4\u8f03\u57fa\u6e96<\/span><select class=\"race-reference\"><option value=\"leader\" data-i18n=\"leader\">Leader\uff08\u5404\u5468\u306e\u9996\u4f4d\uff09<\/option><\/select><\/label><\/div>\n    <form class=\"race-controls\" data-form=\"gap\" novalidate>\n      <label><span data-i18n=\"min\">\u6700\u5c0f\u5024\uff08\u79d2\uff09<\/span><input name=\"min\" type=\"number\" step=\"any\" required><\/label>\n      <label><span data-i18n=\"max\">\u6700\u5927\u5024\uff08\u79d2\uff09<\/span><input name=\"max\" type=\"number\" step=\"any\" required><\/label>\n      <button type=\"submit\"><span data-i18n=\"apply\">\u9069\u7528<\/span><\/button><button type=\"button\" data-action=\"reset-gap\"><span data-i18n=\"reset\">\u521d\u671f\u7bc4\u56f2\u306b\u623b\u3059<\/span><\/button>\n    <\/form>\n    <p class=\"race-note\"><span data-i18n=\"gapNote\">\u30d7\u30e9\u30b9\uff1d\u57fa\u6e96\u3088\u308a\u5f8c\u65b9\u3001\u30de\u30a4\u30ca\u30b9\uff1d\u524d\u65b9\u3002\u57fa\u6e96\u3092\u5207\u308a\u66ff\u3048\u308b\u3068\u7e26\u8ef8\u306f\u521d\u671f\u7bc4\u56f2\u306b\u623b\u308a\u307e\u3059\u3002<\/span><\/p>\n    <p class=\"race-error\" data-error=\"gap\" role=\"alert\"><\/p>\n    <div class=\"race-chart race-gap-chart\" data-i18n-aria=\"gapAria\" aria-label=\"\u30ae\u30e3\u30c3\u30d7\u30b0\u30e9\u30d5\"><\/div>\n  <\/div>\n<\/div>\n\n<script src=\"https:\/\/cdn.plot.ly\/plotly-2.26.0.min.js\"><\/script>\n<script>\n(() => {\n  \"use strict\";\n  const root = document.getElementById(\"raceLapWidget\");\n  const DATA_FILE = \"madrid_2026_lap_times.tsv\";\n  \/\/ [\u7565\u79f0, TSV\u306e\u5217\u540d, \u8272]\u3002\u6240\u5c5e\u30fb\u4e26\u3073\u9806\u306f\u5143\u30b3\u30fc\u30c9\u306e\u8a2d\u5b9a\u3092\u7dad\u6301\u3002\n  const driverConfig = [\n    [\"NOR\",\"Lando NORRIS\",\"rgb(255,128,0)\"], [\"PIA\",\"Oscar PIASTRI\",\"rgb(255,192,128)\"],\n    [\"RUS\",\"George RUSSELL\",\"rgb(166,166,166)\"], [\"ANT\",\"Kimi ANTONELLI\",\"rgb(0,176,80)\"],\n    [\"VER\",\"Max VERSTAPPEN\",\"rgb(0,32,96)\"], [\"LAW\",\"Liam LAWSON\",\"rgb(102,255,0)\"],\n    [\"LEC\",\"Charles LECLERC\",\"rgb(255,0,0)\"], [\"HAM\",\"Lewis HAMILTON\",\"rgb(255,192,192)\"],\n    [\"ALB\",\"Alexander ALBON\",\"rgb(192,176,224)\"], [\"SAI\",\"Carlos SAINZ\",\"rgb(0,112,192)\"],\n    [\"TSU\",\"Yuki TSUNODA\",\"rgb(180,198,231)\"], [\"LIN\",\"Arvid LINDBLAD\",\"rgb(112,48,160)\"],\n    [\"ALO\",\"Fernando ALONSO\",\"rgb(0,176,240)\"], [\"STR\",\"Lance STROLL\",\"rgb(0,112,112)\"],\n    [\"OCO\",\"Esteban OCON\",\"rgb(0,0,0)\"], [\"BEA\",\"Oliver BEARMAN\",\"rgb(128,128,128)\"],\n    [\"HUL\",\"Nico HULKENBERG\",\"rgb(255,193,37)\"], [\"BOR\",\"Gabriel BORTOLETO\",\"rgb(192,0,0)\"],\n    [\"GAS\",\"Pierre GASLY\",\"rgb(0,128,255)\"], [\"COL\",\"Franco COLAPINTO\",\"rgb(255,0,255)\"],\n    [\"PER\",\"Sergio PEREZ\",\"rgb(255,140,0)\"], [\"BOT\",\"Valtteri BOTTAS\",\"rgb(0,150,136)\"]\n  ];\n  const WHITE_TEXT = new Set([\"VER\",\"LIN\",\"STR\",\"OCO\",\"BEA\",\"SAI\",\"GAS\",\"BOR\",\"BOT\"]);\n  const $ = selector => root.querySelector(selector);\n  const form = name => $(`[data-form=\"${name}\"]`);\n  const field = (name, key) => form(name).elements.namedItem(key);\n  const error = (name, key = \"\", params = {}) => { errors[name]={key,params}; $(`[data-error=\"${name}\"]`).textContent = key ? t(key,params) : \"\"; };\n  const timeChart = $(\".race-time-chart\");\n  const gapChart = $(\".race-gap-chart\");\n  const status = $(\".race-status\");\n  const messages = {\n  \"ja\": {\n    \"driversNote\": \"\u30c9\u30e9\u30a4\u30d0\u30fc\u3092\u9078\u3076\u3068\u4e21\u30b0\u30e9\u30d5\u306b\u8868\u793a\u3057\u307e\u3059\u3002\u51e1\u4f8b\u306f\u9078\u629e\u3057\u305f\u9806\u306b\u4e26\u3073\u307e\u3059\u3002\",\n    \"laps\": \"\u8868\u793a\u5468\u56de\uff08\u4e21\u30b0\u30e9\u30d5\u5171\u901a\uff09:\",\n    \"start\": \"\u958b\u59cb\",\n    \"end\": \"\u7d42\u4e86\",\n    \"apply\": \"\u9069\u7528\",\n    \"allLaps\": \"\u5168\u5468\u56de\u306b\u623b\u3059\",\n    \"reset\": \"\u521d\u671f\u7bc4\u56f2\u306b\u623b\u3059\",\n    \"format\": \"\u30bf\u30a4\u30e0\u306f\u300c1:20.000\u300d\u307e\u305f\u306f\u300c80.000\u300d\u3067\u5165\u529b\u3067\u304d\u307e\u3059\u3002\u901f\u3044\u30bf\u30a4\u30e0\u3092\u4e0a\u306b\u8868\u793a\u3057\u307e\u3059\u3002\",\n    \"white\": \"\u767d\u4e38\uff1a\u524d\u306e\u30c9\u30e9\u30a4\u30d0\u30fc\u3068\u306e\u5dee\u304c2\u79d2\u4ee5\u5185\u3002\",\n    \"reference\": \"\u6bd4\u8f03\u57fa\u6e96\",\n    \"leader\": \"Leader\uff08\u5404\u5468\u306e\u9996\u4f4d\uff09\",\n    \"min\": \"\u6700\u5c0f\u5024\uff08\u79d2\uff09\",\n    \"max\": \"\u6700\u5927\u5024\uff08\u79d2\uff09\",\n    \"gapNote\": \"\u30d7\u30e9\u30b9\uff1d\u57fa\u6e96\u3088\u308a\u5f8c\u65b9\u3001\u30de\u30a4\u30ca\u30b9\uff1d\u524d\u65b9\u3002\u57fa\u6e96\u3092\u5207\u308a\u66ff\u3048\u308b\u3068\u7e26\u8ef8\u306f\u521d\u671f\u7bc4\u56f2\u306b\u623b\u308a\u307e\u3059\u3002\",\n    \"loading\": \"\u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059\u2026\",\n    \"loadError\": \"\u30b0\u30e9\u30d5\u3092\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30da\u30fc\u30b8\u3092\u518d\u8aad\u307f\u8fbc\u307f\u3057\u3066\u304f\u3060\u3055\u3044\u3002\",\n    \"updateError\": \"\u30b0\u30e9\u30d5\u3092\u66f4\u65b0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30da\u30fc\u30b8\u3092\u518d\u8aad\u307f\u8fbc\u307f\u3057\u3066\u304f\u3060\u3055\u3044\u3002\",\n    \"invalid\": \"\u6709\u52b9\u306a\u6700\u5c0f\u5024\u30fb\u6700\u5927\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\",\n    \"invalidTime\": \"Fastest\u30fbSlowest\u306b\u6709\u52b9\u306a\u30bf\u30a4\u30e0\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\",\n    \"lapError\": \"\u958b\u59cb\u30fb\u7d42\u4e86\u306f{min}\u301c{max}\u306e\u6574\u6570\u3067\u3001\u958b\u59cb\u2266\u7d42\u4e86\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\",\n    \"timeError\": \"Slowest\u306fFastest\u3088\u308a0.001\u79d2\u4ee5\u4e0a\u5927\u304d\u304f\u3057\u3066\u304f\u3060\u3055\u3044\u3002\",\n    \"gapError\": \"\u6700\u5927\u5024\u306f\u6700\u5c0f\u5024\u3088\u308a\u5927\u304d\u304f\u3057\u3066\u304f\u3060\u3055\u3044\u3002\",\n    \"driversAria\": \"\u8868\u793a\u3059\u308b\u30c9\u30e9\u30a4\u30d0\u30fc\",\n    \"timeAria\": \"\u30e9\u30c3\u30d7\u30bf\u30a4\u30e0\u30b0\u30e9\u30d5\",\n    \"gapAria\": \"\u30ae\u30e3\u30c3\u30d7\u30b0\u30e9\u30d5\"\n  },\n  \"en\": {\n    \"driversNote\": \"Select drivers to show them on both charts. The legend follows your selection order.\",\n    \"laps\": \"Lap range (both charts):\",\n    \"start\": \"From\",\n    \"end\": \"To\",\n    \"apply\": \"Apply\",\n    \"allLaps\": \"All Laps\",\n    \"reset\": \"Reset Range\",\n    \"format\": \"Enter a time as 1:20.000 or 80.000 seconds. Faster times appear higher.\",\n    \"white\": \"White circle: within 2 seconds of the driver ahead.\",\n    \"reference\": \"Reference\",\n    \"leader\": \"Leader (each lap)\",\n    \"min\": \"Minimum (s)\",\n    \"max\": \"Maximum (s)\",\n    \"gapNote\": \"Positive = behind the reference driver; negative = ahead. Changing the reference resets the vertical range.\",\n    \"loading\": \"Loading data\u2026\",\n    \"loadError\": \"Unable to load the charts. Please reload the page.\",\n    \"updateError\": \"Unable to update the charts. Please reload the page.\",\n    \"invalid\": \"Enter valid minimum and maximum values.\",\n    \"invalidTime\": \"Enter valid times for Fastest and Slowest.\",\n    \"lapError\": \"Enter whole laps from {min} to {max}, with From no greater than To.\",\n    \"timeError\": \"Slowest must be at least 0.001 seconds greater than Fastest.\",\n    \"gapError\": \"Maximum must be greater than Minimum.\",\n    \"driversAria\": \"Drivers to display\",\n    \"timeAria\": \"Lap time chart\",\n    \"gapAria\": \"Gap chart\"\n  }\n};\n  let language = \"ja\";\n  const t = (key, params = {}) => {\n    let text = messages[language][key] || key;\n    Object.entries(params).forEach(([name,value]) => {text=text.replace(\"{\"+name+\"}\",String(value));});\n    return text;\n  };\n  let statusKey = \"loading\";\n  const errors = {};\n  function setLanguage(next) {\n    language = next === \"en\" ? \"en\" : \"ja\";\n    root.setAttribute(\"lang\",language);\n    root.querySelectorAll(\"[data-i18n]\").forEach(el => {el.textContent=t(el.getAttribute(\"data-i18n\"));});\n    root.querySelectorAll(\"[data-i18n-aria]\").forEach(el => {el.setAttribute(\"aria-label\",t(el.getAttribute(\"data-i18n-aria\")));});\n    root.querySelectorAll(\"[data-lang]\").forEach(el => {el.setAttribute(\"aria-pressed\",String(el.getAttribute(\"data-lang\")===language));});\n    status.textContent=t(statusKey);\n    Object.entries(errors).forEach(([name,entry]) => {$(`[data-error=\"${name}\"]`).textContent=entry.key ? t(entry.key,entry.params) : \"\";});\n  }\n  root.querySelectorAll(\"[data-lang]\").forEach(el => {el.onclick=()=>setLanguage(el.getAttribute(\"data-lang\"));});\n  setLanguage(\"ja\");\n\n  const parseTime = value => {\n    const s = String(value ?? \"\").trim();\n    if (\/^\\d+(?:\\.\\d+)?$\/.test(s)) {\n      const n = Number(s); return Number.isFinite(n) ? n : null;\n    }\n    const match = \/^(\\d+):(\\d{1,2}(?:\\.\\d+)?)$\/.exec(s);\n    if (!match || Number(match[2]) >= 60) return null;\n    const n = Number(match[1]) * 60 + Number(match[2]);\n    return Number.isFinite(n) ? n : null;\n  };\n  const formatTime = seconds => {\n    const ms = Math.round(seconds * 1000);\n    return Math.floor(ms \/ 60000) + \":\" + (Math.floor(ms \/ 1000) % 60).toString().padStart(2,\"0\") + \".\" + (ms % 1000).toString().padStart(3,\"0\");\n  };\n  function timeAxis(min, max) {\n    const target = (max - min) \/ 8;\n    const power = 10 ** Math.floor(Math.log10(target));\n    const step = [1,2,5,10].map(n => n * power).find(n => n >= target);\n    const ticks = [];\n    const start = Math.ceil(min \/ step) * step;\n    for (let i = 0; i < 20; i++) {\n      const v = Number((start + i * step).toPrecision(12));\n      if (v > max + step * 1e-8) break;\n      ticks.push(v);\n    }\n    return {\"yaxis.range\":[max,min], \"yaxis.autorange\":false, \"yaxis.tickmode\":\"array\", \"yaxis.tickvals\":ticks, \"yaxis.ticktext\":ticks.map(formatTime)};\n  }\n  async function init() {\n    if (!root) throw new Error(\"\u30b0\u30e9\u30d5\u306e\u8868\u793a\u9818\u57df\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002\");\n    if (!window.Plotly) throw new Error(\"Plotly\u3092\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3067\u3057\u305f\u3002WordPress\u304cscript\u30bf\u30b0\u3092\u524a\u9664\u3057\u3066\u3044\u306a\u3044\u304b\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002\");\n    const Plotly = window.Plotly;\n    const tsv = await fetch(DATA_FILE).then(response => {\n        if (!response.ok) throw new Error(`TSV\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\uff08HTTP ${response.status}\uff09\u3002DATA_FILE\u306eURL\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002`);\n        return response.text();\n      });\n    const lines = tsv.replace(\/^\\uFEFF\/, \"\").split(\/\\r?\\n\/).filter(line => line.trim() !== \"\");\n    if (lines.length < 2) throw new Error(\"TSV\u306b\u30e9\u30c3\u30d7\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093\u3002\");\n    const headers = lines[0].split(\"\\t\").map(s => s.trim());\n    const columns = driverConfig.map(([,full]) => headers.indexOf(full));\n    if (columns.every(index => index < 0)) throw new Error(\"TSV\u306e\u30c9\u30e9\u30a4\u30d0\u30fc\u5217\u540d\u304c\u8a2d\u5b9a\u3068\u4e00\u81f4\u3057\u307e\u305b\u3093\u3002\");\n    const rows = lines.slice(1).map(line => line.split(\"\\t\"));\n    const laps = rows.map(row => Number(row[0]));\n    if (laps.some((lap,i) => !Number.isInteger(lap) || lap < 1 || (i > 0 ? lap <= laps[i-1] : false))) {\n      throw new Error(\"TSV\u306e\u5468\u56de\u756a\u53f7\u306f\u3001\u91cd\u8907\u306e\u306a\u3044\u6607\u9806\u306e\u6b63\u306e\u6574\u6570\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\");\n    }\n    const times = columns.map(column => rows.map(row => {\n      const raw = column < 0 ? \"\" : (row[column] ?? \"\").trim();\n      const value = parseTime(raw);\n      return value === null ? null : (value > 0 ? value : null);\n    }));\n    let fastest = Infinity;\n    times.forEach(values => values.forEach(v => { if (v !== null) fastest = Math.min(fastest,v); }));\n    if (!Number.isFinite(fastest)) throw new Error(\"\u6709\u52b9\u306a\u30e9\u30c3\u30d7\u30bf\u30a4\u30e0\u304c\u3042\u308a\u307e\u305b\u3093\u3002\");\n    \/\/ \u4e00\u5ea6\u3067\u3082\u6b20\u640d\u3057\u305f\u3089\u3001\u4ee5\u5f8c\u306e\u7d2f\u7a4d\u306f\u4e0d\u660e\u3002\u5468\u56de\u884c\u81ea\u4f53\u306e\u6b20\u843d\u3082\u691c\u51fa\u3059\u308b\u3002\n    const cum = times.map(values => {\n      let total = 0, known = true;\n      return values.map((value,i) => {\n        if (value === null || laps[i] !== (i === 0 ? 1 : laps[i-1]+1)) known = false;\n        if (!known) return null;\n        total += value; return total;\n      });\n    });\n    const within = driverConfig.map(() => laps.map(() => false));\n    const leaderTimes = laps.map((_,i) => {\n      const running = driverConfig.map((_,d) => d).filter(d => cum[d][i] !== null).sort((a,b) => cum[a][i]-cum[b][i]);\n      for (let j=1; j<running.length; j++) {\n        if (cum[running[j]][i]-cum[running[j-1]][i] <= 2) within[running[j]][i] = true;\n      }\n      return running.length ? cum[running[0]][i] : null;\n    });\n    let reference = \"leader\";\n    const gapValues = () => {\n      const base = reference === \"leader\" ? leaderTimes : cum[Number(reference)];\n      return cum.map(values => values.map((v,i) => v === null || base[i] === null ? null : v-base[i]));\n    };\n    const gapDefault = () => reference === \"leader\" ? [0,250] : [-250,250];\n    const gapLabel = () => reference === \"leader\" ? \"Leader\" : driverConfig[Number(reference)][0];\n    const gapHover = () => `%{fullData.name}<br>Lap %{x}<br>Gap to ${gapLabel()}: %{y:+.3f} s<extra><\/extra>`;\n    const initialTime = [Math.floor(fastest),Math.floor(fastest)+8];\n    const wholeLaps = [laps[0],laps[laps.length-1]];\n    const xRange = (min,max) => min === max ? [min-.5,max+.5] : [min,max];\n    const lapTraces = [], gaps = gapValues();\n    const gapTraces = [];\n    driverConfig.forEach(([d,,color],idx) => {\n      lapTraces.push({name:d,x:laps,y:times[idx],customdata:times[idx].map(t => t === null ? \"\" : formatTime(t)),mode:\"lines\",connectgaps:false,line:{color,width:2},visible:false,showlegend:false,hovertemplate:\"%{fullData.name}<br>Lap %{x}<br>Time: %{customdata}<extra><\/extra>\"});\n      lapTraces.push({name:d,x:laps,y:times[idx],mode:\"markers\",marker:{size:6,color:within[idx].map(f => f ? \"#fff\" : color),symbol:\"circle\",line:{color,width:2}},hoverinfo:\"skip\",visible:false,showlegend:false});\n      gapTraces.push({name:d,x:laps,y:gaps[idx],mode:\"lines\",connectgaps:false,line:{color,width:2},visible:false,showlegend:false,hovertemplate:gapHover()});\n    });\n    const font = {family:\"Times New Roman, Times, serif\"};\n    const layout = title => ({font,legend:{itemclick:false,itemdoubleclick:false,orientation:\"h\",y:-.2,x:0},xaxis:{title:{text:\"Lap\"},range:xRange(...wholeLaps),autorange:false,tickformat:\"d\"},yaxis:{title:{text:title},autorange:false,automargin:true},margin:{t:25,r:15,b:85,l:75},hovermode:\"closest\",paper_bgcolor:\"#fff\",plot_bgcolor:\"#fff\"});\n    const lapLayout = layout(\"Time (m:s)\");\n    const axis = timeAxis(...initialTime);\n    Object.entries(axis).forEach(([key,value]) => {lapLayout.yaxis[key.slice(6)] = value;});\n    const gapLayout = layout(\"Gap (s)\"); gapLayout.yaxis.range = gapDefault();\n    $(\".race-interactive\").hidden = false;\n    \/\/ \u521d\u671f\u63cf\u753b\u5b8c\u4e86\u307e\u3067\u3001\u307e\u3060\u30a4\u30d9\u30f3\u30c8\u306e\u306a\u3044\u30b3\u30f3\u30c8\u30ed\u30fc\u30eb\u3092\u64cd\u4f5c\u3055\u305b\u306a\u3044\u3002\n    root.querySelectorAll(\"button,input,select\").forEach(el => {el.disabled=true;});\n    const config = {responsive:true,displaylogo:false,scrollZoom:false,doubleClick:false};\n    await Promise.all([Plotly.newPlot(timeChart,lapTraces,lapLayout,config),Plotly.newPlot(gapChart,gapTraces,gapLayout,config)]);\n    let busy = false;\n    async function run(action) {\n      if (busy) return;\n      busy = true;\n      root.querySelectorAll(\"button,input,select\").forEach(el => {el.disabled=true;});\n      try { await action(); }\n      catch (e) { console.error(e); status.hidden=false; statusKey=\"updateError\"; status.textContent=t(statusKey); }\n      finally {busy=false;root.querySelectorAll(\"button,input,select\").forEach(el => {el.disabled=false;});}\n    }\n    let legendCounter = 0;\n    const ranks = driverConfig.map(() => 0), selected = driverConfig.map(() => false);\n    const buttons = driverConfig.map(([d,,color],idx) => {\n      const button = document.createElement(\"button\");\n      button.type=\"button\";button.className=\"race-driver\";button.style.backgroundColor=color;button.style.color=WHITE_TEXT.has(d)?\"#fff\":\"#000\";\n      button.setAttribute(\"aria-pressed\",\"false\");button.setAttribute(\"aria-label\",d);\n      const check = document.createElement(\"span\");check.className=\"race-check\";check.setAttribute(\"aria-hidden\",\"true\");\n      button.append(check,document.createTextNode(d));\n      button.onclick = () => run(async () => {selected[idx]=!selected[idx];if(selected[idx]) ranks[idx]=++legendCounter;await applySelection();});\n      $(\".race-drivers\").appendChild(button);\n      const option=document.createElement(\"option\");option.value=String(idx);option.textContent=d;$(\".race-reference\").appendChild(option);\n      return button;\n    });\n    function applySelection() {\n      buttons.forEach((button,i) => {button.setAttribute(\"aria-pressed\",String(selected[i]));button.firstChild.textContent=selected[i]?\"\u2713\":\"\";});\n      \/\/ \u5168\u9078\u629e\u30fb\u5168\u89e3\u9664\u3082\u3001\u5404\u30b0\u30e9\u30d5\u306b\u3064\u304d1\u56de\u306e\u66f4\u65b0\u3002\n      return Promise.all([\n        Plotly.restyle(timeChart,{visible:selected.flatMap(v=>[v,v]),showlegend:selected.flatMap(v=>[v,false]),legendrank:ranks.flatMap(v=>[v,v])}),\n        Plotly.restyle(gapChart,{visible:selected,showlegend:selected,legendrank:ranks})\n      ]);\n    }\n    $('[data-action=\"select\"]').onclick=()=>run(async()=>{legendCounter=driverConfig.length;selected.fill(true);ranks.forEach((_,i)=>{ranks[i]=i+1;});await applySelection();});\n    $('[data-action=\"clear\"]').onclick=()=>run(async()=>{legendCounter=0;selected.fill(false);ranks.fill(0);await applySelection();});\n    function setFields(name,range,format=String) {field(name,\"min\").value=format(range[0]);field(name,\"max\").value=format(range[1]);}\n    setFields(\"laps\",wholeLaps);setFields(\"time\",initialTime,formatTime);setFields(\"gap\",gapDefault());\n    async function applyLaps(min,max) {\n      await Promise.all([timeChart,gapChart].map(chart=>Plotly.relayout(chart,{\"xaxis.range\":xRange(min,max),\"xaxis.autorange\":false})));\n      setFields(\"laps\",[min,max]);error(\"laps\");\n    }\n    async function applyTime(min,max) {await Plotly.relayout(timeChart,timeAxis(min,max));setFields(\"time\",[min,max],formatTime);error(\"time\");}\n    async function applyGap(min,max) {await Plotly.relayout(gapChart,{\"yaxis.range\":[min,max],\"yaxis.autorange\":false});setFields(\"gap\",[min,max]);error(\"gap\");}\n    [\"laps\",\"time\",\"gap\"].forEach(name=>{\n      form(name).onsubmit=event=>{\n        event.preventDefault();\n        const rawMin=field(name,\"min\").value.trim(),rawMax=field(name,\"max\").value.trim();\n        const min=name===\"time\"?parseTime(rawMin):Number(rawMin),max=name===\"time\"?parseTime(rawMax):Number(rawMax);\n        if (!rawMin || !rawMax || !Number.isFinite(min) || !Number.isFinite(max)) {error(name,name===\"time\"?\"invalidTime\":\"invalid\");return;}\n        if (name===\"laps\") {\n          if (!Number.isInteger(min)||!Number.isInteger(max)||min>max||min<wholeLaps[0]||max>wholeLaps[1]) {error(name,\"lapError\",{min:wholeLaps[0],max:wholeLaps[1]});return;}\n          run(()=>applyLaps(min,max));\n        } else {\n          if (min>=max || (name===\"time\" ? max-min<.001 : false)) {error(name,name===\"time\"?\"timeError\":\"gapError\");return;}\n          run(()=>name===\"time\"?applyTime(min,max):applyGap(min,max));\n        }\n      };\n    });\n    $('[data-action=\"reset-laps\"]').onclick=()=>run(()=>applyLaps(...wholeLaps));\n    $('[data-action=\"reset-time\"]').onclick=()=>run(()=>applyTime(...initialTime));\n    $('[data-action=\"reset-gap\"]').onclick=()=>run(()=>applyGap(...gapDefault()));\n    $(\".race-reference\").onchange=()=>run(async()=>{\n      reference=$(\".race-reference\").value;\n      await Plotly.update(gapChart,{y:gapValues(),hovertemplate:gapHover()},{\"yaxis.range\":gapDefault(),\"yaxis.autorange\":false});\n      $(\".race-gap-title\").textContent=\"Gap to \"+gapLabel();setFields(\"gap\",gapDefault());error(\"gap\");\n    });\n    root.querySelectorAll(\"button,input,select\").forEach(el=>{el.disabled=false;});\n    status.hidden=true;\n  }\n  init().catch(e=>{console.error(e);$(\".race-interactive\").hidden=true;status.hidden=false;statusKey=\"loadError\";status.textContent=t(statusKey);root.querySelectorAll(\"[data-lang]\").forEach(el=>{el.disabled=false;});});\n})();\n<\/script>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>\u65e5\u672c\u8a9eEnglish \u30c7\u30fc\u30bf\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059\u2026 Drivers:Select AllClear All \u30c9\u30e9\u30a4\u30d0\u30fc\u3092\u9078\u3076\u3068\u4e21\u30b0\u30e9\u30d5\u306b\u8868\u793a\u3057\u307e\u3059\u3002\u51e1\u4f8b\u306f\u9078\u629e\u3057\u305f\u9806\u306b\u4e26\u3073\u307e\u3059\u3002 \u8868\u793a\u5468\u56de\uff08\u4e21\u30b0\u30e9\u30d5\u5171\u901a\uff09: \u958b\u59cb \u7d42\u4e86 \u9069\u7528 [&hellip;]<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":17437,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-17431","page","type-page","status-publish","has-post-thumbnail","hentry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/f1-lap-time.com\/index.php?rest_route=\/wp\/v2\/pages\/17431","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/f1-lap-time.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/f1-lap-time.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/f1-lap-time.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/f1-lap-time.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=17431"}],"version-history":[{"count":4,"href":"https:\/\/f1-lap-time.com\/index.php?rest_route=\/wp\/v2\/pages\/17431\/revisions"}],"predecessor-version":[{"id":17436,"href":"https:\/\/f1-lap-time.com\/index.php?rest_route=\/wp\/v2\/pages\/17431\/revisions\/17436"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/f1-lap-time.com\/index.php?rest_route=\/wp\/v2\/media\/17437"}],"wp:attachment":[{"href":"https:\/\/f1-lap-time.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=17431"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}