{
  "version": 3,
  "sources": ["hourly_chart_legend.js"],
  "sourcesContent": ["/**\n * static/js/hourly_chart_legend.js \u2014 open/close for the hourly chart's legend.\n *\n * The chart itself is server-rendered and completely static: no hover, no\n * tooltip, no scrubber, nothing to boot. It is read like a printed\n * meteogram, and it has to survive being screenshotted into a group chat\n * with nothing lost. This file is the *only* JavaScript the component has,\n * and all it does is show and hide one panel.\n *\n * Consequences worth keeping:\n *\n *   - The chart is fully readable with JS disabled or still loading. The\n *     legend is the one thing that is not, which is the right thing to\n *     lose: it explains the marks, it does not carry the forecast.\n *   - There are no user-facing strings here. Everything the legend says is\n *     rendered by includes/_hourly_chart_legend.html, where makemessages\n *     can see it \u2014 a string built in JS ships as English to every locale.\n *\n * Delegated from the document, so a chart swapped in by HTMX works without\n * re-initialising anything.\n */\n\n(function () {\n  \"use strict\";\n\n  var OPEN = \"[data-hourly-chart-legend-open]\";\n  var CLOSE = \"[data-hourly-chart-legend-close]\";\n  var PANEL = \"[data-hourly-chart-legend]\";\n  var BACKDROP = \"[data-hourly-chart-legend-backdrop]\";\n\n  /** Elements that can hold focus inside the open panel. */\n  var FOCUSABLE = 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n\n  /** The trigger that opened the panel currently showing, if any. */\n  var openTrigger = null;\n\n  /**\n   * Show or hide one chart's legend.\n   *\n   * @param {Element} root The chart root.\n   * @param {boolean} show Whether the panel should be visible.\n   */\n  function setOpen(root, show) {\n    var panel = root.querySelector(PANEL);\n    var backdrop = root.querySelector(BACKDROP);\n    var trigger = root.querySelector(OPEN);\n    if (!panel) return;\n\n    [panel, backdrop].forEach(function (el) {\n      if (!el) return;\n      el.hidden = !show;\n      el.classList.toggle(\"hidden\", !show);\n    });\n    if (trigger) trigger.setAttribute(\"aria-expanded\", show ? \"true\" : \"false\");\n\n    if (show) {\n      openTrigger = trigger;\n      var first = panel.querySelector(FOCUSABLE);\n      if (first) first.focus();\n    } else {\n      if (openTrigger) openTrigger.focus();\n      openTrigger = null;\n    }\n  }\n\n  /** Close every open legend on the page. */\n  function closeAll() {\n    document.querySelectorAll(PANEL).forEach(function (panel) {\n      var root = panel.closest(\"[role='group']\");\n      if (root && !panel.hidden) setOpen(root, false);\n    });\n  }\n\n  document.addEventListener(\"click\", function (event) {\n    var target = event.target;\n    if (!(target instanceof Element)) return;\n\n    var opener = target.closest(OPEN);\n    if (opener) {\n      var root = opener.closest(\"[role='group']\");\n      if (root) setOpen(root, true);\n      return;\n    }\n    if (target.closest(CLOSE) || target.closest(BACKDROP)) closeAll();\n  });\n\n  // Escape closes an open legend and nothing else. Captured on the window,\n  // so it runs before any document listener: a chart inside a map sheet\n  // (SNOW-1101) sits under MapSheet's own Escape-to-close, which would\n  // otherwise shut and empty the sheet before the legend could restore\n  // focus. With no legend open the key passes through untouched.\n  window.addEventListener(\n    \"keydown\",\n    function (event) {\n      if (event.key !== \"Escape\") return;\n      if (!document.querySelector(PANEL + \":not([hidden])\")) return;\n      event.stopPropagation();\n      closeAll();\n    },\n    true,\n  );\n\n  // Keep focus inside an open panel: a modal the keyboard can walk out of\n  // behind is a modal in appearance only.\n  document.addEventListener(\"keydown\", function (event) {\n    if (event.key !== \"Tab\") return;\n    var panel = document.querySelector(PANEL + \":not([hidden])\");\n    if (!panel) return;\n    var items = Array.prototype.slice.call(panel.querySelectorAll(FOCUSABLE));\n    if (!items.length) return;\n    var first = items[0];\n    var last = items[items.length - 1];\n    if (event.shiftKey && document.activeElement === first) {\n      event.preventDefault();\n      last.focus();\n    } else if (!event.shiftKey && document.activeElement === last) {\n      event.preventDefault();\n      first.focus();\n    }\n  });\n})();\n"],
  "mappings": "CAsBC,UAAY,CACX,aAEA,IAAIA,EAAO,kCACPC,EAAQ,mCACRC,EAAQ,6BACRC,EAAW,sCAGXC,EAAY,2EAGZC,EAAc,KAQlB,SAASC,EAAQC,EAAMC,EAAM,CAC3B,IAAIC,EAAQF,EAAK,cAAcL,CAAK,EAChCQ,EAAWH,EAAK,cAAcJ,CAAQ,EACtCQ,EAAUJ,EAAK,cAAcP,CAAI,EACrC,GAAKS,EASL,GAPA,CAACA,EAAOC,CAAQ,EAAE,QAAQ,SAAUE,EAAI,CACjCA,IACLA,EAAG,OAAS,CAACJ,EACbI,EAAG,UAAU,OAAO,SAAU,CAACJ,CAAI,EACrC,CAAC,EACGG,GAASA,EAAQ,aAAa,gBAAiBH,EAAO,OAAS,OAAO,EAEtEA,EAAM,CACRH,EAAcM,EACd,IAAIE,EAAQJ,EAAM,cAAcL,CAAS,EACrCS,GAAOA,EAAM,MAAM,CACzB,MACMR,GAAaA,EAAY,MAAM,EACnCA,EAAc,IAElB,CAGA,SAASS,GAAW,CAClB,SAAS,iBAAiBZ,CAAK,EAAE,QAAQ,SAAUO,EAAO,CACxD,IAAIF,EAAOE,EAAM,QAAQ,gBAAgB,EACrCF,GAAQ,CAACE,EAAM,QAAQH,EAAQC,EAAM,EAAK,CAChD,CAAC,CACH,CAEA,SAAS,iBAAiB,QAAS,SAAUQ,EAAO,CAClD,IAAIC,EAASD,EAAM,OACnB,GAAMC,aAAkB,QAExB,KAAIC,EAASD,EAAO,QAAQhB,CAAI,EAChC,GAAIiB,EAAQ,CACV,IAAIV,EAAOU,EAAO,QAAQ,gBAAgB,EACtCV,GAAMD,EAAQC,EAAM,EAAI,EAC5B,MACF,EACIS,EAAO,QAAQf,CAAK,GAAKe,EAAO,QAAQb,CAAQ,IAAGW,EAAS,EAClE,CAAC,EAOD,OAAO,iBACL,UACA,SAAUC,EAAO,CACXA,EAAM,MAAQ,UACb,SAAS,cAAcb,EAAQ,gBAAgB,IACpDa,EAAM,gBAAgB,EACtBD,EAAS,EACX,EACA,EACF,EAIA,SAAS,iBAAiB,UAAW,SAAUC,EAAO,CACpD,GAAIA,EAAM,MAAQ,MAClB,KAAIN,EAAQ,SAAS,cAAcP,EAAQ,gBAAgB,EAC3D,GAAKO,EACL,KAAIS,EAAQ,MAAM,UAAU,MAAM,KAAKT,EAAM,iBAAiBL,CAAS,CAAC,EACxE,GAAKc,EAAM,OACX,KAAIL,EAAQK,EAAM,CAAC,EACfC,EAAOD,EAAMA,EAAM,OAAS,CAAC,EAC7BH,EAAM,UAAY,SAAS,gBAAkBF,GAC/CE,EAAM,eAAe,EACrBI,EAAK,MAAM,GACF,CAACJ,EAAM,UAAY,SAAS,gBAAkBI,IACvDJ,EAAM,eAAe,EACrBF,EAAM,MAAM,KAEhB,CAAC,CACH,GAAG",
  "names": ["OPEN", "CLOSE", "PANEL", "BACKDROP", "FOCUSABLE", "openTrigger", "setOpen", "root", "show", "panel", "backdrop", "trigger", "el", "first", "closeAll", "event", "target", "opener", "items", "last"]
}
