{"version":3,"file":"js/trends.js","mappings":"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","sources":["webpack://myvue/webpack/runtime/chunk loaded","webpack://myvue/webpack/runtime/create fake namespace object","webpack://myvue/webpack/runtime/load script","webpack://myvue/./src/trends/App.vue?ffc9","webpack://myvue/./src/components/trends/Plots3.vue","webpack://myvue/./src/lib/ApiCom.ts","webpack://myvue/./src/lib/myd3/dom/ElementBuilder.ts","webpack://myvue/./src/lib/myd3/tooltip/Tooltip.ts","webpack://myvue/./src/lib/myd3/core/PlotModel.ts","webpack://myvue/./src/lib/myd3/renderables/TraceRenderable.ts","webpack://myvue/./src/lib/myd3/utils/significance.ts","webpack://myvue/./src/lib/myd3/renderables/TrendRenderables.ts","webpack://myvue/./src/lib/myd3/renderables/RectangleRenderable.ts","webpack://myvue/./src/lib/myd3/renderables/ScatterLinesRenderable.ts","webpack://myvue/./src/lib/myd3/renderables/ChartRenderables.ts","webpack://myvue/./src/lib/myd3/renderables/HeatmapRenderable.ts","webpack://myvue/./src/lib/myd3/renderables/RadialBarsRenderable.ts","webpack://myvue/./src/lib/myd3/handlers/TraceHandler.ts","webpack://myvue/./src/lib/myd3/interaction/ZoomController.ts","webpack://myvue/./src/lib/myd3/MyD3.ts","webpack://myvue/./src/lib/inla/inlaTrendToTraces.ts","webpack://myvue/./src/lib/trends/mergeObsPlots.js","webpack://myvue/./src/store/trends.ts","webpack://myvue/./src/components/trends/MyBase.vue?397c","webpack://myvue/./src/components/trends/MyBase.vue","webpack://myvue/./src/lib/inla/resolvePlotModel.ts","webpack://myvue/./src/components/trends/settings/MyPlotSettings.ts","webpack://myvue/./src/trends/map.ts","webpack://myvue/./src/components/trends/PlotsBase.vue","webpack://myvue/./src/components/trends/PlotsBase.vue?1bcb","webpack://myvue/./src/lib/siteShortcuts.ts","webpack://myvue/./src/components/trends/PlotCard.vue","webpack://myvue/./src/components/trends/PlotContent.vue","webpack://myvue/./src/components/trends/PlotContent.vue?1eaa","webpack://myvue/./src/components/trends/cards/MyTrendCard.vue","webpack://myvue/./src/components/trends/cards/MyTrendCard.vue?d531","webpack://myvue/./src/components/trends/ObsTypeSelect.vue","webpack://myvue/./src/components/trends/ObsTypeSelect.vue?c347","webpack://myvue/./src/components/trends/PlotCard.vue?772d","webpack://myvue/./src/components/trends/cards/TcMap.vue","webpack://myvue/./src/components/trends/cards/TcMap.vue?c1dc","webpack://myvue/./src/components/trends/settings/PlotSettings2.vue","webpack://myvue/./src/components/trends/settings/PlotSettingsBase.vue?cbeb","webpack://myvue/./src/components/trends/settings/PlotSettingsBase.vue","webpack://myvue/./src/components/trends/settings/PlotSettings2.vue?671a","webpack://myvue/./src/components/trends/cards/SpeciesImage.vue","webpack://myvue/./src/components/trends/cards/SpeciesImage.vue?bfa0","webpack://myvue/./src/components/trends/SpeciesImageCarousel.vue","webpack://myvue/./src/components/trends/SpeciesImageCarousel.vue?2c19","webpack://myvue/./src/components/trends/cards/PlotErrorSmall.vue","webpack://myvue/./src/components/trends/cards/PlotErrorSmall.vue?03ac","webpack://myvue/./src/components/trends/cards/TcMore.vue","webpack://myvue/./src/components/trends/cards/ContributorsAccordion.vue","webpack://myvue/./src/components/trends/cards/ContributorsAccordion.vue?55ca","webpack://myvue/./src/components/trends/cards/TrimInfo.vue","webpack://myvue/./src/components/trends/cards/TrimInfo.vue?2d2d","webpack://myvue/./src/components/trends/cards/TimingsInfo.vue","webpack://myvue/./src/components/trends/cards/TimingsInfo.vue?af5b","webpack://myvue/./src/components/trends/cards/DownloadData.vue","webpack://myvue/./src/components/trends/cards/DownloadData.vue?0e0f","webpack://myvue/./src/components/trends/GofDiagnostics.vue","webpack://myvue/./src/components/trends/GofDiagnostics.vue?e1ba","webpack://myvue/./src/components/trends/cards/TcMore.vue?1a25","webpack://myvue/./src/components/trends/cards/InlaComponentCard.vue","webpack://myvue/./src/components/account/admin/InlaSpatialMap.vue","webpack://myvue/./src/components/account/MyBase.vue?86c3","webpack://myvue/./src/components/account/MyBase.vue","webpack://myvue/./src/lib/inla/inverseLink.ts","webpack://myvue/./src/components/account/dashboard/tooltip.js","webpack://myvue/./src/components/account/admin/InlaSpatialMap.vue?305b","webpack://myvue/./src/components/trends/cards/InlaComponentCard.vue?9740","webpack://myvue/./src/components/trends/cards/SpeciesPreviewCarousel.vue","webpack://myvue/./src/components/trends/cards/SpeciesPreviewCarousel.vue?025b","webpack://myvue/./src/components/trends/TrendComponentGAM.vue","webpack://myvue/./src/components/trends/TrendComponentGAM.vue?4466","webpack://myvue/./src/components/trends/Plots3.vue?195d","webpack://myvue/./src/trends/App.vue?2ef3","webpack://myvue/./src/trends/App.vue","webpack://myvue/./src/trends/main.ts","webpack://myvue/./src/account/i18n.ts","webpack://myvue/./src/locales/ lazy ^\\.\\/.*\\.json$ chunkName: locale-[request] namespace object","webpack://myvue/webpack/bootstrap","webpack://myvue/webpack/runtime/compat get default export","webpack://myvue/webpack/runtime/define property getters","webpack://myvue/webpack/runtime/ensure chunk","webpack://myvue/webpack/runtime/get javascript chunk filename","webpack://myvue/webpack/runtime/get mini-css chunk filename","webpack://myvue/webpack/runtime/global","webpack://myvue/webpack/runtime/hasOwnProperty shorthand","webpack://myvue/webpack/runtime/make namespace object","webpack://myvue/webpack/runtime/runtimeId","webpack://myvue/webpack/runtime/publicPath","webpack://myvue/webpack/runtime/jsonp chunk loading","webpack://myvue/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","var getProto = Object.getPrototypeOf ? function(obj) { return Object.getPrototypeOf(obj); } : function(obj) { return obj.__proto__; };\nvar leafPrototypes;\n// create a fake namespace object\n// mode & 1: value is a module id, require it\n// mode & 2: merge all properties of value into the ns\n// mode & 4: return value when already ns object\n// mode & 16: return value when it's Promise-like\n// mode & 8|1: behave like require\n__webpack_require__.t = function(value, mode) {\n\tif(mode & 1) value = this(value);\n\tif(mode & 8) return value;\n\tif(typeof value === 'object' && value) {\n\t\tif((mode & 4) && value.__esModule) return value;\n\t\tif((mode & 16) && typeof value.then === 'function') return value;\n\t}\n\tvar ns = Object.create(null);\n\t__webpack_require__.r(ns);\n\tvar def = {};\n\tleafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];\n\tfor(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) {\n\t\tObject.getOwnPropertyNames(current).forEach(function(key) { def[key] = function() { return value[key]; }; });\n\t}\n\tdef['default'] = function() { return value; };\n\t__webpack_require__.d(ns, def);\n\treturn ns;\n};","var inProgress = {};\nvar dataWebpackPrefix = \"myvue:\";\n// loadScript function to load a script via script tag\n__webpack_require__.l = function(url, done, key, chunkId) {\n\tif(inProgress[url]) { inProgress[url].push(done); return; }\n\tvar script, needAttach;\n\tif(key !== undefined) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tfor(var i = 0; i < scripts.length; i++) {\n\t\t\tvar s = scripts[i];\n\t\t\tif(s.getAttribute(\"src\") == url || s.getAttribute(\"data-webpack\") == dataWebpackPrefix + key) { script = s; break; }\n\t\t}\n\t}\n\tif(!script) {\n\t\tneedAttach = true;\n\t\tscript = document.createElement('script');\n\n\t\tscript.charset = 'utf-8';\n\t\tscript.timeout = 120;\n\t\tif (__webpack_require__.nc) {\n\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n\t\t}\n\t\tscript.setAttribute(\"data-webpack\", dataWebpackPrefix + key);\n\n\t\tscript.src = url;\n\t}\n\tinProgress[url] = [done];\n\tvar onScriptComplete = function(prev, event) {\n\t\t// avoid mem leaks in IE.\n\t\tscript.onerror = script.onload = null;\n\t\tclearTimeout(timeout);\n\t\tvar doneFns = inProgress[url];\n\t\tdelete inProgress[url];\n\t\tscript.parentNode && script.parentNode.removeChild(script);\n\t\tdoneFns && doneFns.forEach(function(fn) { return fn(event); });\n\t\tif(prev) return prev(event);\n\t}\n\tvar timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);\n\tscript.onerror = onScriptComplete.bind(null, script.onerror);\n\tscript.onload = onScriptComplete.bind(null, script.onload);\n\tneedAttach && document.head.appendChild(script);\n};","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock, resolveComponent as _resolveComponent, createVNode as _createVNode, createStaticVNode as _createStaticVNode, Fragment as _Fragment } from \"vue\"\n\nconst _hoisted_1 = {\n  xmlns: \"http://www.w3.org/2000/svg\",\n  style: {\"display\":\"none\"}\n}\nconst _hoisted_2 = /*#__PURE__*/_createStaticVNode(\"<symbol id=\\\"map1\\\" viewBox=\\\"0 0 16 16\\\" fill=\\\"currentColor\\\"><path fill-rule=\\\"evenodd\\\" d=\\\"M15.817.113A.5.5 0 0 1 16 .5v14a.5.5 0 0 1-.402.49l-5 1a.502.502 0 0 1-.196 0L5.5 15.01l-4.902.98A.5.5 0 0 1 0 15.5v-14a.5.5 0 0 1 .402-.49l5-1a.5.5 0 0 1 .196 0L10.5.99l4.902-.98a.5.5 0 0 1 .415.103zM10 1.91l-4-.8v12.98l4 .8V1.91zm1 12.98 4-.8V1.11l-4 .8v12.98zm-6-.8V1.11l-4 .8v12.98l4-.8z\\\"></path></symbol><symbol id=\\\"person-heart\\\" viewBox=\\\"0 0 16 16\\\" fill=\\\"currentColor\\\"><path d=\\\"M9 5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm-9 8c0 1 1 1 1 1h10s1 0 1-1-1-4-6-4-6 3-6 4Zm13.5-8.09c1.387-1.425 4.855 1.07 0 4.277-4.854-3.207-1.387-5.702 0-4.276Z\\\"></path></symbol><symbol id=\\\"bi-1-circle\\\" viewBox=\\\"0 0 16 16\\\" fill=\\\"currentColor\\\"><path d=\\\"M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8Zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM9.283 4.002V12H7.971V5.338h-.065L6.072 6.656V5.385l1.899-1.383h1.312Z\\\"></path></symbol><symbol id=\\\"bi-2-circle\\\" viewBox=\\\"0 0 16 16\\\" fill=\\\"currentColor\\\"><path d=\\\"M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8Zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM6.646 6.24v.07H5.375v-.064c0-1.213.879-2.402 2.637-2.402 1.582 0 2.613.949 2.613 2.215 0 1.002-.6 1.667-1.287 2.43l-.096.107-1.974 2.22v.077h3.498V12H5.422v-.832l2.97-3.293c.434-.475.903-1.008.903-1.705 0-.744-.557-1.236-1.313-1.236-.843 0-1.336.615-1.336 1.306Z\\\"></path></symbol><symbol id=\\\"bi-3-circle\\\" viewBox=\\\"0 0 16 16\\\" fill=\\\"currentColor\\\"><path d=\\\"M7.918 8.414h-.879V7.342h.838c.78 0 1.348-.522 1.342-1.237 0-.709-.563-1.195-1.348-1.195-.79 0-1.312.498-1.348 1.055H5.275c.036-1.137.95-2.115 2.625-2.121 1.594-.012 2.608.885 2.637 2.062.023 1.137-.885 1.776-1.482 1.875v.07c.703.07 1.71.64 1.734 1.917.024 1.459-1.277 2.396-2.93 2.396-1.705 0-2.707-.967-2.754-2.144H6.33c.059.597.68 1.06 1.541 1.066.973.006 1.6-.563 1.588-1.354-.006-.779-.621-1.318-1.541-1.318Z\\\"></path><path d=\\\"M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8Z\\\"></path></symbol><symbol id=\\\"bi-bounding-box\\\" viewBox=\\\"0 0 16 16\\\" fill=\\\"currentColor\\\"><path d=\\\"M5 2V0H0v5h2v6H0v5h5v-2h6v2h5v-5h-2V5h2V0h-5v2H5zm6 1v2h2v6h-2v2H5v-2H3V5h2V3h6zm1-2h3v3h-3V1zm3 11v3h-3v-3h3zM4 15H1v-3h3v3zM1 4V1h3v3H1z\\\"></path></symbol><symbol id=\\\"bi-geo-alt\\\" viewBox=\\\"0 0 16 16\\\" fill=\\\"currentColor\\\"><path d=\\\"M12.166 8.94c-.524 1.062-1.234 2.12-1.96 3.07A31.493 31.493 0 0 1 8 14.58a31.481 31.481 0 0 1-2.206-2.57c-.726-.95-1.436-2.008-1.96-3.07C3.304 7.867 3 6.862 3 6a5 5 0 0 1 10 0c0 .862-.305 1.867-.834 2.94zM8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10z\\\"></path><path d=\\\"M8 8a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0 1a3 3 0 1 0 0-6 3 3 0 0 0 0 6z\\\"></path></symbol><symbol id=\\\"bi-arrows-fullscreen\\\" viewBox=\\\"0 0 16 16\\\" fill=\\\"currentColor\\\"><path fill-rule=\\\"evenodd\\\" d=\\\"M5.828 10.172a.5.5 0 0 0-.707 0l-4.096 4.096V11.5a.5.5 0 0 0-1 0v3.975a.5.5 0 0 0 .5.5H4.5a.5.5 0 0 0 0-1H1.732l4.096-4.096a.5.5 0 0 0 0-.707zm4.344 0a.5.5 0 0 1 .707 0l4.096 4.096V11.5a.5.5 0 1 1 1 0v3.975a.5.5 0 0 1-.5.5H11.5a.5.5 0 0 1 0-1h2.768l-4.096-4.096a.5.5 0 0 1 0-.707zm0-4.344a.5.5 0 0 0 .707 0l4.096-4.096V4.5a.5.5 0 1 0 1 0V.525a.5.5 0 0 0-.5-.5H11.5a.5.5 0 0 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 0 .707zm-4.344 0a.5.5 0 0 1-.707 0L1.025 1.732V4.5a.5.5 0 0 1-1 0V.525a.5.5 0 0 1 .5-.5H4.5a.5.5 0 0 1 0 1H1.732l4.096 4.096a.5.5 0 0 1 0 .707z\\\"></path></symbol><symbol id=\\\"bi-download\\\" viewBox=\\\"0 0 16 16\\\" fill=\\\"currentColor\\\"><path d=\\\"M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z\\\"></path><path d=\\\"M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z\\\"></path></symbol>\", 9)\nconst _hoisted_11 = [\n  _hoisted_2\n]\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n  const _component_PlotsThree = _resolveComponent(\"PlotsThree\")!\n\n  return (_openBlock(), _createElementBlock(_Fragment, null, [\n    (_openBlock(), _createElementBlock(\"svg\", _hoisted_1, _hoisted_11)),\n    _createVNode(_component_PlotsThree)\n  ], 64))\n}","<template>\n  <div>\n    <!-- The spinner -->\n    <MySpinner :working=\"working\" :fatalError=\"fatalError\" :loadingInfoTexts=\"loadingInfoTexts\"></MySpinner>\n    <div class=\"container\">\n      <!-- TOP BAR -->\n      <PlotSettings2 ref=\"settings\" @settingsChanged=\"settingsChanged\" @settingsModify=\"settingsModify\" @mapSettingsChanged=\"mapSettingsChanged\"></PlotSettings2>\n      <!-- START OF ACTUAL CONTENT -->\n\n\n      <div class=\"main-panel\" id=\"mainContainer\">\n        <div v-if=\"species\">\n          <div class=\"species-header\">\n            <div class=\"species-thumb desktop-only\">\n              <SpeciesImageCarousel :species=\"species\" :images=\"species.images\" :bottom-bar=\"false\" :indicators=\"false\" mkey=\"1\"></SpeciesImageCarousel>\n            </div>\n\n            <div class=\"species-meta desktop-only\">\n              <h5 class=\"section-title\">{{ capitalizeAll(species.name) }}</h5>\n              <em class=\"species-latin\">{{ species.latin }}</em>\n              <div v-if=\"species\">\n                <a class=\"info-toggle\" data-bs-toggle=\"collapse\" href=\"#more\" @click=\"toggleMoreInfo()\">\n                  {{ isMoreInfoOpen ? $t('trends.speciesInfoHide') : $t('trends.speciesInfoShow') }}\n                </a>\n              </div>\n            </div>\n\n            <div class=\"species-trend\">\n              <h5 class=\"section-title\">Trend</h5>\n              <PlotErrorSmall :plot-error=\"plotError\"></PlotErrorSmall>\n              <!-- trendPlotData, not plot: the raw INLA plot has no traces (built client-side) -->\n              <TrendComponentGAM :plot=\"trendPlotData\" icon-size=\"16\" icon-size-large=\"64\" :has-enough-data=\"hasEnoughData\"></TrendComponentGAM>\n            </div>\n\n            <div class=\"species-numbers\">\n              <h5 class=\"section-title\">{{ $t('trends.numbers') }}</h5>\n              <div v-if=\"nbCounts\" :class=\"{'text-color-danger': !hasEnoughData}\">\n                <template v-if=\"siteStats && siteStats.has_complete_survey\">\n                  {{$tc('trends.moreCounts1Pos', {n: nbCounts, p: siteStats.nb_rows_positive})}}\n                  {{$tc('trends.moreCounts2', {n: contributors.length})}}\n                  {{$tc('trends.moreCounts3Pos', {n: nbLocations, s: siteStats.nb_sites_positive})}}\n                </template>\n                <template v-else>\n                  {{$tc('trends.moreCounts1', {n: nbCounts})}}\n                  {{$tc('trends.moreCounts2', {n: contributors.length})}}\n                  {{$tc('trends.moreCounts3', {n: nbLocations})}}\n                </template>\n              </div>\n            </div>\n\n            <div class=\"species-meta-mobile mobile-only\">\n              <h5 class=\"section-title\">{{ species.name }}</h5>\n              <em class=\"species-latin\">{{ species.latin }}</em>\n              <div v-if=\"species\">\n                <a class=\"info-toggle\" data-bs-toggle=\"collapse\" href=\"#more\" @click=\"toggleMoreInfo()\">\n                  {{ isMoreInfoOpen ? $t('trends.speciesInfoHide') : $t('trends.speciesInfoShow') }}\n                </a>\n              </div>\n            </div>\n\n          </div>\n        </div>\n\n        <div v-if=\"species\" class=\"collapse\" id=\"more\">\n          <div v-if=\"species.counts\" class=\"info-banner\">\n            LOL\n          </div>\n          <div v-for=\"(sub, subKey) in subSpecies\" :key=\"subKey\">\n            <hr class=\"more-divider\">\n            <h1 class=\"sub-species-title\">{{sub.name}}</h1>\n            <div class=\"more-detail-grid\">\n              <div class=\"more-detail-text\">\n                <div v-for=\"(desc, idx) in sub.desc\" :key=\"'desc_' + idx\">\n                  <h6 v-if=\"idx!='description'\" class=\"desc-heading\">{{speciesTitles[idx]}}</h6>\n                  <div class=\"desc-text\" v-html=\"desc\"></div>\n                </div>\n              </div>\n              <div class=\"more-detail-images desktop-only\">\n                <div v-for=\"(img, idx) in sub.images\" :key=\"idx\">\n                  <SpeciesImage :img=\"img\" class=\"detail-image\"></SpeciesImage>\n                </div>\n              </div>\n            </div>\n          </div>\n          <SpeciesImageCarousel :species=\"species\" :images=\"species.images\" class=\"mobile-only\" mkey=\"2\"></SpeciesImageCarousel>\n<!--          <div class=\"row mt-4\">-->\n<!--            <div class=\"col-xl-6 col-12\">-->\n<!--              <div v-for=\"(desc, idx) in species.desc\" :key=\"'desc_' + idx\">-->\n<!--                <h6 v-if=\"idx!='description'\">{{speciesTitles[idx]}}</h6>-->\n<!--                <div class=\"mb-3 text-muted\" v-html=\"desc\"></div>-->\n<!--              </div>-->\n<!--            </div>-->\n<!--            <div class=\"col-xl-6 col-12 d-none d-xl-block\">-->\n<!--              <div v-for=\"(img, idx) in speciesImages\" :key=\"idx\">-->\n<!--                QWEW {{speciesImages}}-->\n<!--                <SpeciesImage :img=\"img\" class=\"mb-3\"></SpeciesImage>-->\n<!--              </div>-->\n<!--            </div>-->\n<!--          </div>-->\n        </div>\n\n        <div v-else class=\"welcome-section\">\n          <h4 class=\"welcome-title\">{{ $t ('trends.intro.title') }}</h4>\n          <div class=\"welcome-text\">{{ $t ('trends.intro.text1') }}</div>\n          <div class=\"steps-block\">\n            <h4 class=\"steps-title\">{{ $t ('trends.intro.steps') }}</h4>\n\n            <div class=\"step-row\">\n              <svg width=\"20\" height=\"20\" class=\"step-icon step-icon-primary\"><use xlink:href=\"#bi-1-circle\"/></svg>\n              <span class=\"help1\" @click=\"openSpeciesDropdown()\" @mouseenter=\"highlight($event, 1, true)\" @mouseleave=\"highlight($event, 1, false)\">{{ $t ('trends.intro.step1') }}</span>\n            </div>\n            <div class=\"step-row\">\n              <svg width=\"20\" height=\"20\" class=\"step-icon step-icon-muted\"><use xlink:href=\"#bi-2-circle\"/></svg>\n              <span class=\"help2\" @mouseenter=\"highlight($event, 2, true)\" @mouseleave=\"highlight($event, 2, false)\">{{ $t ('trends.intro.step2') }}</span>\n            </div>\n            <div class=\"step-row\">\n              <svg width=\"20\" height=\"20\" class=\"step-icon step-icon-muted\"><use xlink:href=\"#bi-3-circle\"/></svg>\n              <span class=\"help2\" @mouseenter=\"highlight($event, 3, true)\" @mouseleave=\"highlight($event, 3, false)\">{{ $t ('trends.intro.step3') }}</span>\n            </div>\n          </div>\n\n          <div v-if=\"store.plotSettings?.availableCountTypes?.length > 0\">\n            <SpeciesPreviewCarousel @selectSpecies=\"selectSpecies\" :count-types=\"store.plotSettings.availableCountTypes\"></SpeciesPreviewCarousel>\n          </div>\n\n          <div class=\"welcome-text\">{{ $t ('trends.intro.text2') }}</div>\n        </div>\n\n\n      </div>\n      <div class=\"content-grid\">\n        <div v-if=\"isAdminOnlyView\" class=\"admin-only-banner grid-full\">\n          <span class=\"badge-circle badge-admin\"></span>\n          {{ $t('trends.obsTabs.adminOnlyBanner') }}\n        </div>\n        <PlotCard :plot=\"plot\" :plot-error=\"plotError\" plot-id=\"divPlot1\" :working=\"working\"\n                  :obs-plots=\"obsPlots\" :obs-plot-ids=\"obsPlotIds\"\n                  @select-obs-type=\"selectObsType\" :class=\"isGridLayout ? 'grid-full' : 'grid-half'\"></PlotCard>\n        <TcMap :id-map=\"idMap\" class=\"grid-half\"></TcMap>\n        <InlaComponentCard v-if=\"isInla\" :plot=\"plot\" :site-stats=\"siteStats\" class=\"grid-full\" />\n        <TcMore :contributors=\"contributors\" :overall=\"overall\" :summary=\"summary\" :timings=\"timings\" :plot-error=\"plotError\"\n                :gof=\"gof\" :obs-plots=\"obsPlots\" :obs-plot-ids=\"obsPlotIds\"\n                @download=\"download\" @select-sites=\"openSitesShortcut\" class=\"grid-full\"></TcMore>\n      </div>\n\n    </div>\n  </div>\n</template>\n\n<script>\n\nimport \"leaflet/dist/leaflet.css\"\nimport MySpinner from \"@/components/shared/MySpinner.vue\";\nimport PlotsBase from \"@/components/trends/PlotsBase.vue\";\nimport PlotCard from \"@/components/trends/PlotCard.vue\";\nimport TcMap from \"@/components/trends/cards/TcMap.vue\";\nimport PlotSettings2 from \"@/components/trends/settings/PlotSettings2.vue\";\nimport SpeciesImage from \"@/components/trends/cards/SpeciesImage.vue\";\nimport SpeciesImageCarousel from \"@/components/trends/SpeciesImageCarousel.vue\";\nimport PlotErrorSmall from \"@/components/trends/cards/PlotErrorSmall.vue\";\nimport TcMore from \"@/components/trends/cards/TcMore.vue\";\nimport InlaComponentCard from \"@/components/trends/cards/InlaComponentCard.vue\";\nimport SpeciesPreviewCarousel from \"@/components/trends/cards/SpeciesPreviewCarousel.vue\";\nimport TrendComponentGAM from \"@/components/trends/TrendComponentGAM.vue\";\n\n\nexport default {\n  extends: PlotsBase,\n  name: 'PlotsThree',\n  components: {\n    TrendComponentGAM,\n    SpeciesPreviewCarousel,\n    TcMore,\n    InlaComponentCard,\n    PlotErrorSmall,\n    SpeciesImageCarousel,\n    SpeciesImage,\n    PlotSettings2,\n    TcMap, PlotCard, MySpinner\n  },\n  data: function (){\n    return {\n      isMoreInfoOpen: false,\n    };\n  },\n  methods: {\n    highlight(evt, idx, enabled){\n      const elements = [];\n      if (enabled) evt.target.classList.add('help-text');\n      else evt.target.classList.remove('help-text');\n      // console.log(evt);\n      if (idx == 1){\n        elements.push(document.getElementById('nlSpecies'));\n      }\n      else if (idx == 2){\n        elements.push(document.getElementById('nlRegion'));\n      }\n      else if (idx == 3){\n        elements.push(document.getElementById('nlTimespan1'));\n        elements.push(document.getElementById('nlTimespan2'));\n        elements.push(document.getElementById('nlTimespan3'));\n        elements.push(document.getElementById('nlTimespan4'));\n      }\n      for (const el of elements){\n        if (enabled)\n          el.classList.add('highlight');\n        else\n          el.classList.remove('highlight');\n      }\n    },\n    toggleMoreInfo: function () {\n      this.isMoreInfoOpen = !this.isMoreInfoOpen;\n    },\n    /** WTF? I cannot import the function from the utils.js file. If I do, the preview (npm run serve) does not work! */\n    capitalizeAll: function(s){\n      return s.split(' ').map(w => w[0].toUpperCase() + w.substr(1).toLowerCase()).join(' ');\n    },\n    /**\n     * Opens the species dropdown. This code is hacky, but it's the only known way to do it programmatically.\n     */\n    openSpeciesDropdown(){\n      const elm = document.getElementById(\"nlSpecies\");\n      //  this disables the auto closing\n      elm.setAttribute(\"data-bs-auto-close\", \"false\");\n      //  now open the dropdown\n      // eslint-disable-next-line no-undef\n      new bootstrap.Dropdown(elm).show();\n      //  restore the original state\n      elm.removeAttribute(\"data-bs-auto-close\");\n      //  recreate the dropdown to apply the original state.\n      //  without the timeout it does not work (it's not opening).\n      setTimeout(() => {\n        // eslint-disable-next-line no-undef\n        new bootstrap.Dropdown(elm);\n      }, 40);\n    },\n    /** called from the species preview carousel via events */\n    selectSpecies: function (species){\n      this.$refs.settings.selectSpecies(species);\n    },\n    /** the plot card's dropdown picked either an observation type or a layout */\n    selectObsType: function (payload){\n      if (payload?.kind === 'layout'){\n        this.$refs.settings.selectObsLayout(payload.layout);\n        return;\n      }\n      // selectObservationType resets obsLayout to 'single' itself, so this is one refetch.\n      this.$refs.settings.selectObservationType(payload?.obsType);\n    },\n  },\n  computed: {\n    subSpecies(){\n      if (this.species?.counts){\n        const list = [];\n        for (const sub of this.species.counts){\n          list.push(this.store.speciesDict[sub]);\n        }\n        return list;\n      }\n      return [this.species];\n    },\n    /** true when an admin is viewing a non-public observation type */\n    isAdminOnlyView: function (){\n      return this.store?.plotSettings?.observationType?.public === false;\n    },\n    /** side-by-side needs the full row; the map drops below it */\n    isGridLayout: function (){\n      return this.store?.plotSettings?.obsLayout === 'grid';\n    },\n  }\n}\n</script>\n\n<style scoped>\n.main-panel {\n  border: 1px solid #e2e8f0;\n  border-radius: 0 0.625rem 0.625rem 0.625rem;\n  margin-bottom: 1rem;\n  padding: 1rem;\n  position: relative;\n  top: -1px;\n  z-index: 0;\n}\n\n.species-header {\n  display: grid;\n  grid-template-columns: auto 1fr 1fr 1fr;\n  gap: 1rem;\n  align-items: start;\n}\n\n@media (max-width: 1199.98px) {\n  .species-header {\n    grid-template-columns: 1fr 1fr;\n  }\n}\n\n.species-thumb {\n  width: clamp(80px, 10vw, 140px);\n}\n\n.species-meta,\n.species-trend,\n.species-numbers {\n  margin-bottom: 0.75rem;\n}\n\n.section-title {\n  font-size: 1rem;\n  font-weight: 600;\n  color: #1e293b;\n  margin: 0 0 0.375rem;\n}\n\n.species-latin {\n  color: #64748b;\n  font-size: 0.9375rem;\n}\n\n.info-toggle {\n  color: #2563eb;\n  text-decoration: underline;\n  text-underline-offset: 2px;\n  font-size: 0.875rem;\n  cursor: pointer;\n}\n\n.info-toggle:hover {\n  color: #1d4ed8;\n}\n\n.text-color-danger {\n  color: #dc2626;\n}\n\n.desktop-only {\n  display: block;\n}\n\n.mobile-only {\n  display: none;\n}\n\n@media (max-width: 1199.98px) {\n  .desktop-only {\n    display: none;\n  }\n  .mobile-only {\n    display: block;\n  }\n}\n\n.species-meta-mobile {\n  margin-bottom: 0.75rem;\n}\n\n.info-banner {\n  background: rgba(8, 145, 178, 0.08);\n  color: #0891b2;\n  padding: 0.75rem 1rem;\n  border-radius: 0.375rem;\n  font-size: 0.875rem;\n}\n\n.more-divider {\n  border-color: #e2e8f0;\n}\n\n.sub-species-title {\n  font-size: 1.5rem;\n  font-weight: 700;\n  color: #1e293b;\n}\n\n.more-detail-grid {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  gap: 1.5rem;\n  margin-top: 1rem;\n}\n\n@media (max-width: 1199.98px) {\n  .more-detail-grid {\n    grid-template-columns: 1fr;\n  }\n}\n\n.desc-heading {\n  font-size: 0.875rem;\n  font-weight: 600;\n  color: #1e293b;\n  margin: 0.75rem 0 0.25rem;\n}\n\n.desc-text {\n  font-size: 0.875rem;\n  color: #64748b;\n  line-height: 1.6;\n  margin-bottom: 0.75rem;\n}\n\n.detail-image {\n  margin-bottom: 0.75rem;\n}\n\n.welcome-section {\n  font-size: 1.0625rem;\n  color: #64748b;\n  line-height: 1.6;\n}\n\n.welcome-title {\n  font-size: 1.25rem;\n  font-weight: 600;\n  color: #1e293b;\n}\n\n.welcome-text {\n  margin-bottom: 0.5rem;\n}\n\n.steps-block {\n  padding: 1rem;\n  font-size: 1.125rem;\n}\n\n.steps-title {\n  font-size: 1.125rem;\n  font-weight: 600;\n  color: #1e293b;\n  margin-bottom: 0.75rem;\n}\n\n.step-row {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  margin-bottom: 0.25rem;\n}\n\n.step-icon {\n  flex-shrink: 0;\n  margin-right: 0.5rem;\n}\n\n.step-icon-primary {\n  color: #2563eb;\n}\n\n.step-icon-muted {\n  color: #64748b;\n}\n\n.content-grid {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  gap: 1rem;\n}\n\n@media (max-width: 1199.98px) {\n  .content-grid {\n    grid-template-columns: 1fr;\n  }\n}\n\n.grid-half {\n  min-width: 0;\n}\n\n.grid-full {\n  grid-column: 1 / -1;\n}\n\n.admin-only-banner {\n  display: flex;\n  align-items: center;\n  gap: 0.5rem;\n  background: #fef3c7;\n  color: #92400e;\n  border: 1px solid #fde68a;\n  border-radius: 0.5rem;\n  padding: 0.5rem 0.9rem;\n  font-size: 0.8125rem;\n  font-weight: 600;\n}\n\n.help1 {\n  cursor: pointer;\n}\n\n.help2 {\n  cursor: help;\n}\n</style>\n<style>\n.help-text {\n  font-weight: bold;\n}\n</style>","import axios, {AxiosResponse} from \"axios\";\n\nexport interface ApiComRequestDef {\n    method: 'GET' | 'POST';\n    url?: string;\n    data?: any;\n    file?: File;\n    formData?: FormData;\n    download?: boolean;\n    filename?: string;\n    infoText?: string;\n    config?: any;\n    app?: any;\n    responseHandler?: (data: any) => void;\n    errorHandler?: (error: any) => void;\n}\n\nclass ApiCommunication{\n    url: string;\n    private _requestCounts = new WeakMap<object, number>();\n    private _requestInfoTexts = new Map<number, {app: object, text: string}>();\n    private _nextReqId = 0;\n\n    constructor(url: string) {\n        this.url = url;\n        axios.defaults.xsrfCookieName = 'csrftoken';\n        axios.defaults.xsrfHeaderName = 'X-CSRFToken';\n    }\n\n    private _startRequest(app: any, infoText?: string): number {\n        const count = (this._requestCounts.get(app) || 0) + 1;\n        this._requestCounts.set(app, count);\n        const reqId = ++this._nextReqId;\n        if (infoText) {\n            this._requestInfoTexts.set(reqId, {app, text: infoText});\n        }\n        app.working = true;\n        this._updateInfoTexts(app);\n        return reqId;\n    }\n\n    private _endRequest(app: any, reqId: number): void {\n        const count = Math.max(0, (this._requestCounts.get(app) || 1) - 1);\n        this._requestCounts.set(app, count);\n        this._requestInfoTexts.delete(reqId);\n        this._syncWorkingState(app);\n        this._updateInfoTexts(app);\n    }\n\n    private _syncWorkingState(app: any): void {\n        const count = this._requestCounts.get(app) || 0;\n        if (count > 0) {\n            app.working = true;\n        } else if (!app.fatalError && !app.confirm) {\n            app.working = false;\n        }\n    }\n\n    private _updateInfoTexts(app: any): void {\n        if (!app || !('loadingInfoTexts' in app)) return;\n        const texts: string[] = [];\n        this._requestInfoTexts.forEach((entry) => {\n            if (entry.app === app) {\n                texts.push(entry.text);\n            }\n        });\n        app.loadingInfoTexts = texts;\n    }\n\n    getActiveRequestCount(app: any): number {\n        return this._requestCounts.get(app) || 0;\n    }\n\n    private _handleFatalError(app: any, response: AxiosResponse): boolean {\n        if (response.data.fatalError){\n            app.working = true;\n            app.raiseFatalError(\"Fatal Error\", response.data.fatalError.message, 500);\n            return true;\n        }\n        return false;\n    }\n\n    private _handleResponse(app: any, response: AxiosResponse, responseHandler: any, errorHandler: any): void {\n        const contentType = response.headers['content-type'];\n        if (contentType === 'application/json'){\n            if (this._handleFatalError(app, response)){\n                return;\n            }\n        }\n        else {\n            console.warn(\"Non-JSON contentType: \" + contentType);\n        }\n        try {\n            responseHandler(response.data);\n        }\n        catch (e){\n            console.log(e);\n            errorHandler(e);\n        }\n    }\n\n    get(app: any, responseHandler: any, errorHandler: any){\n        this.makeRequest({method: 'GET', app, responseHandler, errorHandler});\n    }\n    post(app: any, data: any, responseHandler: any, errorHandler: any, config?: any){\n        this.makeRequest({method: 'POST', app, data, responseHandler, errorHandler, config});\n    }\n    postFile(app: any, file: any, responseHandler: any, errorHandler: any){\n        this.makeRequest({method: 'POST', app, file, responseHandler, errorHandler});\n    }\n    postFormData(app: any, formData: FormData, responseHandler: any, errorHandler: any){\n        this.makeRequest({method: 'POST', app, formData, responseHandler, errorHandler});\n    }\n\n    static postDownload(url: string, data: any, filename: string|undefined = undefined){\n        axios.post(url, data, {responseType: 'blob'}).then((response: AxiosResponse) => {\n            const blobUrl = window.URL.createObjectURL(new Blob([response.data]));\n            const link = document.createElement('a');\n            link.href = blobUrl;\n            if (filename) {\n                link.setAttribute('download', filename);\n            }\n            document.body.appendChild(link);\n            link.click();\n        });\n    }\n\n    makeRequest(def: ApiComRequestDef): void {\n        const url = def.url || this.url;\n        const app = def.app;\n\n        if (def.download) {\n            const reqId = app ? this._startRequest(app, def.infoText) : null;\n            axios.post(url, def.data, {responseType: 'blob'}).then((response: AxiosResponse) => {\n                const blobUrl = window.URL.createObjectURL(new Blob([response.data]));\n                const link = document.createElement('a');\n                link.href = blobUrl;\n                if (def.filename) {\n                    link.setAttribute('download', def.filename);\n                }\n                document.body.appendChild(link);\n                link.click();\n                if (app && reqId !== null) this._endRequest(app, reqId);\n            }).catch((error) => {\n                if (def.errorHandler) def.errorHandler(error);\n                if (app && reqId !== null) this._endRequest(app, reqId);\n            });\n            return;\n        }\n\n        const reqId = this._startRequest(app, def.infoText);\n        // eslint-disable-next-line @typescript-eslint/no-empty-function\n        const responseHandler = def.responseHandler || (() => {});\n        const errorHandler = def.errorHandler || ((e: any) => console.error(e));\n\n        let requestData = def.data;\n        let config = def.config;\n\n        if (def.file) {\n            const formData = new FormData();\n            formData.append('file', def.file);\n            requestData = formData;\n            config = { ...config, headers: { 'Content-Type': 'multipart/form-data' } };\n        } else if (def.formData) {\n            requestData = def.formData;\n            config = { ...config, headers: { 'Content-Type': 'multipart/form-data' } };\n        }\n\n        const promise = def.method === 'GET'\n            ? axios.get(url)\n            : axios.post(url, requestData, config);\n\n        promise.then((response: AxiosResponse) => {\n            this._handleResponse(app, response, responseHandler, errorHandler);\n            this._endRequest(app, reqId);\n        }).catch((error) => {\n            console.log(error);\n            errorHandler(error);\n            this._endRequest(app, reqId);\n        });\n    }\n}\n\nclass ApiRequestBuilder{\n    actions: any[];\n    constructor(actionId: string, properties: any) {\n        this.actions = [];\n        if (actionId){\n            this.addAction(actionId, properties);\n        }\n    }\n    addAction(actionId: string, properties: any){\n        if (! properties) properties = {};\n        properties.action = actionId;\n        this.actions.push(properties);\n        return this;\n    }\n    build(){\n        return {\n            actions: this.actions\n        };\n    }\n}\n\nconst ApiUtil = {\n    addKeyToMapItemsAsId: function (map: any){\n        for (const id in map) {\n            map[id].id = id;\n        }\n        return map;\n    },\n    listToMapWithIdAsKey: function(l: any){\n        const map = {};\n        let item;\n        for (const idx in l){\n            item = l[idx];\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            map[item.id] = item;\n        }\n        return map;\n    },\n    mapToList: function(map: any){\n        const list = [];\n        for (const id in map){\n            list.push(map[id]);\n        }\n        return list;\n    },\n    listFromIds: function (ids: any, map: any){\n        const l = [];\n        for (const idx in ids){\n            const id = ids[idx];\n            const o = map[id];\n            if (o) l.push(o);\n        }\n        return l;\n    },\n};\n\nexport {ApiCommunication, ApiRequestBuilder, ApiUtil}\n","type AttributeRecord = Record<string, unknown>;\n\n/**\n * Lightweight DOM helper used by the download toolbar.\n * Keeps all DOM mutation logic in a single place so we do not\n * clutter the visualization code with manual element handling.\n */\nclass DomElement {\n    private readonly element: HTMLElement;\n\n    constructor(element: HTMLElement) {\n        this.element = element;\n    }\n\n    el(): HTMLElement {\n        return this.element;\n    }\n\n    attr(key: string, value: unknown): DomElement {\n        if (value === null || value === undefined) {\n            return this;\n        }\n\n        if (key === \"class\" && typeof value === \"object\" && !Array.isArray(value)) {\n            const classList = Object.keys(value)\n                .filter(cls => Boolean((value as Record<string, boolean>)[cls]))\n                .join(\" \");\n            if (classList) {\n                this.element.setAttribute(\"class\", classList);\n            }\n            return this;\n        }\n\n        if (key === \"style\" && typeof value === \"object\" && !Array.isArray(value)) {\n            const styleString = Object.entries(value as Record<string, string | number>)\n                .map(([prop, val]) => `${prop}:${val}`)\n                .join(\";\");\n            if (styleString) {\n                this.element.setAttribute(\"style\", styleString);\n            }\n            return this;\n        }\n\n        this.element.setAttribute(key, String(value));\n        return this;\n    }\n\n    attrs(attributes: AttributeRecord): DomElement {\n        Object.entries(attributes).forEach(([key, val]) => this.attr(key, val));\n        return this;\n    }\n\n    text(content: string): DomElement {\n        this.element.textContent = content;\n        return this;\n    }\n}\n\nexport class ElementBuilder {\n    static create(tag: string, attributes?: AttributeRecord): DomElement {\n        const element = document.createElement(tag);\n        const domElement = new DomElement(element);\n        if (attributes) {\n            domElement.attrs(attributes);\n        }\n        return domElement;\n    }\n\n    static append(parent: HTMLElement | DomElement, tag: string, attributes?: AttributeRecord): DomElement {\n        const domElement = ElementBuilder.create(tag, attributes);\n        if (parent instanceof DomElement) {\n            parent.el().appendChild(domElement.el());\n        } else {\n            parent.appendChild(domElement.el());\n        }\n        return domElement;\n    }\n}\n\nexport type { DomElement };\n\n","/**\n * Reusable tooltip class for displaying HTML content with automatic positioning.\n * Works with D3 selections by appending a foreignObject to the current SVG root.\n */\nclass Tooltip {\n    private readonly container: any;\n    private readonly width: number;\n    private readonly height: number;\n\n    constructor(svg: any, width: number, height: number) {\n        this.width = width;\n        this.height = height;\n        // A div (not xhtml:body) as the foreignObject child: a nested <body> is invalid\n        // and, being tagged `body`, collides with page-wide body selectors in tooling.\n        this.container = svg.append(\"foreignObject\")\n            .attr(\"width\", width)\n            .attr(\"height\", height)\n            .style(\"pointer-events\", \"none\")\n            .append(\"xhtml:div\")\n            .style(\"opacity\", 0)\n            .style(\"position\", \"absolute\")\n            .style(\"pointer-events\", \"none\")\n            .style(\"top\", \"0px\")\n            .style(\"left\", \"0px\");\n    }\n\n    show(htmlContent: string, x: number, y: number) {\n        this.container.html(htmlContent);\n        this.container.style(\"opacity\", 0.85);\n        this.position(x, y);\n    }\n\n    hide() {\n        this.container.style(\"opacity\", 0);\n    }\n\n    private position(x: number, y: number) {\n        const bounds = this.container.node().getBoundingClientRect();\n        const margin = 10;\n        const safeMargin = 5;\n\n        let left = x - bounds.width / 2;\n        let top = y - bounds.height - margin;\n\n        const minLeft = safeMargin;\n        const maxLeft = this.width - bounds.width - safeMargin;\n        const minTop = safeMargin;\n        const maxTop = this.height - bounds.height - safeMargin;\n\n        if (left < minLeft) {\n            left = minLeft;\n        } else if (left > maxLeft) {\n            left = maxLeft;\n        }\n\n        if (top < minTop) {\n            top = y + margin;\n            if (top > maxTop) {\n                top = Math.max(minTop, Math.min(maxTop, y - bounds.height / 2));\n            }\n        } else if (top > maxTop) {\n            top = y - bounds.height - margin;\n            if (top < minTop) {\n                top = Math.max(minTop, Math.min(maxTop, y - bounds.height / 2));\n            }\n        }\n\n        left = Math.max(0, Math.min(this.width - bounds.width, left));\n        top = Math.max(0, Math.min(this.height - bounds.height, top));\n\n        this.container\n            .style(\"left\", `${left}px`)\n            .style(\"top\", `${top}px`);\n    }\n}\n\nexport { Tooltip };\n\n","import type { TraceHandler } from \"../handlers/TraceHandler\";\nimport type { TraceRenderable } from \"../renderables\";\nimport type { MyD3 } from \"../MyD3\";\n\nclass MyPlotVisuals {\n    showLine = true;\n    showMarkers = false;\n    showErrorArea = true;\n    showErrorBars = false;\n    showErrorLines = false;\n    expertMode = false;\n}\n\nclass Plot {\n    traces: Trace[] = [];\n    renderables: TraceRenderable[] = [];\n    xMin = 0;\n    xMax = 0;\n    yMin = 0;\n    yMax = 0;\n    axisXType: \"linear\" | \"categorical\" = \"linear\";\n    axisYType: \"linear\" | \"categorical\" = \"linear\";\n    categoricalXLabels: string[] = [];\n    categoricalYLabels: string[] = [];\n\n    prepare(plot: any, handlers: TraceHandler[]) {\n        if (!plot?.traces || !Array.isArray(plot.traces)) {\n            this.traces = [];\n            return;\n        }\n\n        const prepared: Trace[] = [];\n        for (const jsonTrace of plot.traces) {\n            const handler = handlers.find(item => item.canHandle(jsonTrace));\n            if (!handler) continue;\n            const trace = handler.read(jsonTrace);\n            trace.traceIndex = prepared.length;\n            prepared.push(trace);\n        }\n        this.traces = prepared;\n    }\n\n    prepareBounds(myD3: MyD3) {\n        if (this.traces.length === 0) return;\n\n        const renderables: TraceRenderable[] = [];\n        for (const trace of this.traces) {\n            renderables.push(...trace.traceHandler.yieldRenderables(trace, myD3));\n        }\n        renderables.sort((a, b) => a.sort - b.sort);\n        this.renderables = renderables;\n\n        for (const renderable of this.renderables) {\n            renderable.configureAxes(this);\n        }\n\n        for (const renderable of this.renderables) {\n            renderable.updateBounds();\n        }\n\n        this.xMin = Math.min(...this.traces.map(trace => trace.xMin));\n        this.xMax = Math.max(...this.traces.map(trace => trace.xMax));\n        const { yMin, yMax } = myD3.resolveYBounds(\n            Math.min(...this.traces.map(trace => trace.yMin)),\n            Math.max(...this.traces.map(trace => trace.yMax))\n        );\n        this.yMin = yMin;\n        this.yMax = yMax;\n    }\n}\n\nclass Trace {\n    items: TraceData[] = [];\n    settings: Record<string, any>;\n    title = \"\";\n    traceIndex = 0;\n    xMin = 0;\n    xMax = 0;\n    yMin = 0;\n    yMax = 0;\n    hsva: number[] = [240, 1.0, 1.0, 1.0];\n    colorFull = \"\";\n    colorFullAlpha10 = \"\";\n    colorFullAlpha25 = \"\";\n    colorDesaturated = \"\";\n    colorDark = \"\";\n    colorLight = \"\";\n    colorBarFill = \"\";\n    colorBarStroke = \"\";\n    colorText = \"\";\n    colorTextMuted = \"\";\n    focusMarker: any;\n    traceHandler: TraceHandler;\n    keyX = \"year\";\n    keyY = \"trend\";\n    /** Stroke dash array for dashed lines (e.g., \"5,5\" or \"10,5,2,5\"). Empty string means solid line. */\n    dashArray = \"\";\n\n    constructor(traceJson: any, traceHandler: TraceHandler) {\n        this.traceHandler = traceHandler;\n        this.settings = traceJson.settings || {};\n        this.title = traceJson.title;\n        this.keyX = this.settings.keyX || this.keyX;\n        this.keyY = this.settings.keyY || this.keyY;\n        this.applyStyle();\n    }\n\n    private applyStyle() {\n        const style = this.settings.style;\n        if (style) {\n            this.hsva = style.hsva || this.hsva;\n            this.dashArray = style.dashArray || this.dashArray;\n        }\n        this.applyHsva(this.hsva[0], this.hsva[1], this.hsva[2], this.hsva[3]);\n        // An explicit hex colour (style.color) wins over the hue-derived palette,\n        // so trend/scatter traces can share the cohesive account chart colours.\n        if (style?.color) {\n            this.applyColorHex(style.color);\n        }\n    }\n\n    /**\n     * Override the derived colour set from a single hex (e.g. \"#2563eb\").\n     * Keeps every colour slot in the same family so lines, markers, fills and\n     * tooltip accents stay consistent with the account palette.\n     */\n    applyColorHex(hex: string) {\n        const m = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex.trim());\n        if (!m) return;\n        const r = parseInt(m[1], 16), g = parseInt(m[2], 16), b = parseInt(m[3], 16);\n        const mix = (t: number) => `rgb(${Math.round(r + (255 - r) * t)}, ${Math.round(g + (255 - g) * t)}, ${Math.round(b + (255 - b) * t)})`;\n        const shade = (t: number) => `rgb(${Math.round(r * (1 - t))}, ${Math.round(g * (1 - t))}, ${Math.round(b * (1 - t))})`;\n        const rgba = (a: number) => `rgba(${r}, ${g}, ${b}, ${a})`;\n        this.colorFull = `rgb(${r}, ${g}, ${b})`;\n        this.colorFullAlpha10 = rgba(0.1);\n        this.colorFullAlpha25 = rgba(0.25);\n        this.colorDesaturated = mix(0.45);\n        this.colorDark = shade(0.35);\n        this.colorLight = mix(0.55);\n        this.colorBarFill = rgba(0.5);\n        this.colorBarStroke = shade(0.3);\n        this.colorText = shade(0.1);\n        this.colorTextMuted = mix(0.3);\n    }\n\n    applyHsva(hue: number, saturation = 0.0, brightness = 1.0, alpha = 1.0) {\n        const fn = (h: number, s: number, b: number, a: number) => {\n            return `hsla(${h}, ${Math.round(saturation * s)}%, ${Math.round(brightness * b)}%, ${alpha * a})`;\n        };\n        this.colorFull = fn(hue, 100, 50, 1.0);\n        this.colorFullAlpha10 = fn(hue, 100, 50, 0.1);\n        this.colorFullAlpha25 = fn(hue, 100, 50, 0.25);\n        this.colorDesaturated = fn(hue, 30, 50, 1.0);\n        this.colorDark = fn(hue, 100, 25, 1.0);\n        this.colorLight = fn(hue, 100, 75, 1.0);\n        this.colorBarFill = fn(hue, 70, 40, 0.5);\n        this.colorBarStroke = fn(hue, 70, 20, 0.5);\n        this.colorText = fn(hue, 100, 60, 1.0);\n        this.colorTextMuted = fn(hue, 50, 60, 1.0);\n    }\n}\n\nclass TraceData {\n    data: any;\n\n    constructor(data: any) {\n        this.data = data;\n    }\n}\n\nexport { MyPlotVisuals, Plot, Trace, TraceData };\n\n","import type { MyD3 } from \"../MyD3\";\nimport type { Plot, Trace, TraceData } from \"../core/PlotModel\";\n\n/**\n * Base class for every renderable element that can appear inside a plot.\n * Keeps references to the owning MyD3 instance and the trace it belongs to.\n */\nabstract class TraceRenderable {\n    constructor(\n        protected readonly myD3: MyD3,\n        protected readonly trace: Trace,\n        public readonly sort: number\n    ) {}\n\n    abstract updateBounds(): void;\n\n    abstract render(): void;\n\n    // Allow renderables to override axis configuration if needed (categorical charts, etc.)\n    configureAxes(_plot: Plot): void {\n        // Default implementation - override in subclasses if needed\n        return;\n    }\n\n    static findMinMax(items: TraceData[], keys: string[], currentMin: number, currentMax: number): [number, number] {\n        let min = Number.isFinite(currentMin) ? currentMin : Infinity;\n        let max = Number.isFinite(currentMax) ? currentMax : -Infinity;\n\n        for (const item of items) {\n            for (const key of keys) {\n                const value = item.data[key];\n                if (value === value) { // filters NaN\n                    if (value < min) min = value;\n                    if (value > max) max = value;\n                }\n            }\n        }\n\n        return [min, max];\n    }\n\n    static findMinMax2(\n        items: TraceData[],\n        keysMin: string[],\n        keysMax: string[],\n        currentMin: number,\n        currentMax: number\n    ): [number, number] {\n        let min = Number.isFinite(currentMin) ? currentMin : Infinity;\n        let max = Number.isFinite(currentMax) ? currentMax : -Infinity;\n\n        for (const item of items) {\n            for (const key of keysMin) {\n                const value = item.data[key];\n                if (value === value && value < min) {\n                    min = value;\n                }\n            }\n            for (const key of keysMax) {\n                const value = item.data[key];\n                if (value === value && value > max) {\n                    max = value;\n                }\n            }\n        }\n\n        return [min, max];\n    }\n}\n\nexport { TraceRenderable };\n\n\n","import type { Trace } from \"../core/PlotModel\";\nimport type { SignificanceSegment } from \"../types\";\nimport type { MyD3 } from \"../MyD3\";\n\n// Modern increase/decrease hues, consistent with the site palette. Older cached\n// plots carry neon #00ff00 / #ff0000 baked into their trace settings, so we map\n// those legacy values across here rather than only fixing them at the source.\nconst MODERN_INCREASE = \"#16a34a\";\nconst MODERN_DECREASE = \"#dc2626\";\nconst LEGACY_INCREASE = new Set([\"#00ff00\", \"#0f0\", \"lime\"]);\nconst LEGACY_DECREASE = new Set([\"#ff0000\", \"#f00\", \"red\"]);\n\nfunction modernizeColor(color: string | undefined, modern: string, legacy: Set<string>): string | undefined {\n    if (!color) return color;\n    return legacy.has(color.toLowerCase()) ? modern : color;\n}\n\nfunction getStrokeColor(trace: Trace, significance: number, myD3?: MyD3): string {\n    const colors = trace.settings?.style?.colors;\n    if (myD3?.data?.type === \"TG\") {\n        return significance === 0 ? trace.colorDesaturated : trace.colorFull;\n    }\n    if (significance === 1) {\n        return modernizeColor(colors?.increase, MODERN_INCREASE, LEGACY_INCREASE) || trace.colorDark;\n    }\n    if (significance === 2) {\n        return modernizeColor(colors?.decrease, MODERN_DECREASE, LEGACY_DECREASE) || trace.colorDark;\n    }\n    return trace.colorFull;\n}\n\nfunction getStrokeWidth(myD3?: MyD3): number {\n    if (!myD3) return 1;\n    if (myD3.dlStrokeWidth && myD3.dlStrokeWidthMul) {\n        return myD3.dlStrokeWidth * myD3.dlStrokeWidthMul;\n    }\n    return 1;\n}\n\nfunction createSegmentsBySignificance(trace: Trace, myD3?: MyD3): SignificanceSegment[] {\n    const segments: SignificanceSegment[] = [];\n    let segment: SignificanceSegment | undefined;\n\n    for (let idx = 0; idx < trace.items.length; idx += 1) {\n        const item = trace.items[idx];\n        const significance = item.data.significance;\n        const isNewSegment = !segment || segment.significance !== significance;\n\n        if (isNewSegment) {\n            segment = {\n                significance,\n                stroke: getStrokeColor(trace, significance, myD3),\n                strokeWidth: getStrokeWidth(myD3),\n                x0: idx > 0 ? idx - 1 : 0,\n                x1: idx\n            };\n            segments.push(segment);\n        }\n\n        if (segment) {\n            segment.x1 = idx + 1;\n        }\n    }\n\n    return segments;\n}\n\nfunction stripShortSignificantSegments(segments: SignificanceSegment[], trace: Trace): SignificanceSegment[] {\n    const result: SignificanceSegment[] = [];\n    const threshold = 2 / 3; // 0.6666\n\n    for (let idx = 0; idx < segments.length; idx += 1) {\n        const seg = { ...segments[idx] };\n        const year0 = trace.items[seg.x0]?.data.year;\n        const year1 = trace.items[seg.x1 - 1]?.data.year;\n        const span = year1 - year0;\n\n        if (Number.isFinite(span) && span < threshold) {\n            const prev = result[result.length - 1];\n            const next = segments[idx + 1];\n\n            if (prev) {\n                prev.x1 = seg.x1;\n                if (next && prev.significance === next.significance) {\n                    prev.x1 = next.x1;\n                    idx += 1;\n                }\n                continue;\n            }\n\n            if (next) {\n                next.x0 = seg.x0;\n                continue;\n            }\n        }\n\n        const last = result[result.length - 1];\n        if (last && last.significance === seg.significance && last.x1 === seg.x0) {\n            last.x1 = seg.x1;\n        } else {\n            result.push(seg);\n        }\n    }\n\n    return result;\n}\n\nexport { createSegmentsBySignificance, stripShortSignificantSegments };\n\n\n","import * as d3 from \"d3\";\n\nimport type { Trace } from \"../core/PlotModel\";\nimport type { MyD3 } from \"../MyD3\";\nimport { TraceRenderable } from \"./TraceRenderable\";\nimport { createSegmentsBySignificance } from \"../utils/significance\";\n\n/** Optional smoothing for trend lines/areas via trace.settings.curve. */\nfunction resolveCurve(trace: Trace): d3.CurveFactory | null {\n    return trace.settings?.curve === \"monotoneX\" ? d3.curveMonotoneX : null;\n}\n\nclass LineRenderable extends TraceRenderable {\n    private readonly keyX: string;\n    private readonly keyY: string;\n\n    constructor(myD3: MyD3, trace: Trace, sort: number) {\n        super(myD3, trace, sort);\n        this.keyX = trace.keyX;\n        this.keyY = trace.keyY;\n    }\n\n    updateBounds(): void {\n        const trace = this.trace;\n        const [xMin, xMax] = TraceRenderable.findMinMax(trace.items, [trace.keyX], trace.xMin, trace.xMax);\n        const [yMin, yMax] = TraceRenderable.findMinMax(trace.items, [this.keyY], trace.yMin, trace.yMax);\n        trace.xMin = xMin;\n        trace.xMax = xMax;\n        trace.yMin = yMin;\n        trace.yMax = yMax;\n    }\n\n    render(): void {\n        const trace = this.trace;\n        const svg = this.myD3.svg;\n        const x = this.myD3.axisX;\n        const y = this.myD3.axisY;\n        const segments = createSegmentsBySignificance(trace, this.myD3);\n\n        const curve = resolveCurve(trace);\n        for (const segment of segments) {\n            const items = trace.items.slice(segment.x0, segment.x1);\n            const lineGen = d3.line()\n                .x((d: any) => x(d.data[this.keyX]))\n                .y((d: any) => y(d.data[this.keyY]));\n            if (curve) lineGen.curve(curve);\n            const path = svg.append(\"path\")\n                .datum(items)\n                .attr(\"fill\", \"none\")\n                .attr(\"stroke\", segment.stroke)\n                .attr(\"stroke-width\", segment.strokeWidth || this.myD3.dlStrokeWidthMul * this.myD3.dlStrokeWidth)\n                .attr(\"d\", lineGen);\n            if (trace.dashArray) {\n                path.attr(\"stroke-dasharray\", trace.dashArray);\n            }\n        }\n    }\n}\n\nclass AreaRenderable extends TraceRenderable {\n    private readonly keyY0 = \"ciLow\";\n    private readonly keyY1 = \"ciHigh\";\n\n    updateBounds(): void {\n        const trace = this.trace;\n        const [xMin, xMax] = TraceRenderable.findMinMax(trace.items, [trace.keyX], trace.xMin, trace.xMax);\n        const [yMin, yMax] = TraceRenderable.findMinMax2(\n            trace.items,\n            [this.keyY0],\n            [this.keyY1],\n            trace.yMin,\n            trace.yMax\n        );\n        trace.xMin = xMin;\n        trace.xMax = xMax;\n        trace.yMin = yMin;\n        trace.yMax = yMax;\n    }\n\n    render(): void {\n        const trace = this.trace;\n        // Traces without CI columns (or with the error area toggled off after\n        // construction) must not paint a NaN path.\n        if (!this.myD3.visuals.showErrorArea) return;\n        if (!trace.items.length || trace.items[0].data[this.keyY0] === undefined) return;\n        const svg = this.myD3.svg;\n        const x = this.myD3.axisX;\n        const y = this.myD3.axisY;\n\n        svg.append(\"path\")\n            .datum(trace.items)\n            .attr(\"fill\", trace.colorFullAlpha10)\n            .attr(\"stroke\", \"none\")\n            .attr(\"d\", d3.area()\n                .x((d: any) => x(d.data[trace.keyX]))\n                .y0((d: any) => y(d.data[this.keyY0]))\n                .y1((d: any) => y(d.data[this.keyY1]))\n            );\n    }\n}\n\n// Gradient ids are document-global, so several charts on one page must not collide.\nlet fillAreaGradientSeq = 0;\n\n/**\n * Soft gradient fill between the trend line and the x-axis (trace.settings.fillArea).\n * Unlike AreaRenderable this needs no CI columns — it shades the value itself.\n */\nclass FillAreaRenderable extends TraceRenderable {\n    updateBounds(): void {\n        // The line's own bounds already cover the filled region.\n    }\n\n    render(): void {\n        const trace = this.trace;\n        if (!trace.items.length) return;\n        const svg = this.myD3.svg;\n        const x = this.myD3.axisX;\n        const y = this.myD3.axisY;\n\n        fillAreaGradientSeq += 1;\n        const gradientId = `myd3-fill-area-${fillAreaGradientSeq}`;\n        const gradient = svg.append(\"defs\").append(\"linearGradient\")\n            .attr(\"id\", gradientId)\n            .attr(\"x1\", 0).attr(\"y1\", 0).attr(\"x2\", 0).attr(\"y2\", 1);\n        gradient.append(\"stop\").attr(\"offset\", \"0%\")\n            .attr(\"stop-color\", trace.colorFull).attr(\"stop-opacity\", 0.35);\n        gradient.append(\"stop\").attr(\"offset\", \"100%\")\n            .attr(\"stop-color\", trace.colorFull).attr(\"stop-opacity\", 0.02);\n\n        const baseline = y(Math.max(0, this.myD3.preparedPlot.yMin));\n        const areaGen = d3.area()\n            .x((d: any) => x(d.data[trace.keyX]))\n            .y0(baseline)\n            .y1((d: any) => y(d.data[trace.keyY]));\n        const curve = resolveCurve(trace);\n        if (curve) areaGen.curve(curve);\n\n        svg.append(\"path\")\n            .datum(trace.items)\n            .attr(\"fill\", `url(#${gradientId})`)\n            .attr(\"stroke\", \"none\")\n            .attr(\"d\", areaGen);\n    }\n}\n\nclass FocusMarkerRenderable extends TraceRenderable {\n    updateBounds(): void {\n        // nothing to do\n    }\n\n    render(): void {\n        const trace = this.trace;\n        const svg = this.myD3.svg;\n\n        //  the trace outlives the SVG, so a marker from an earlier draw is detached\n        //  by now (zoom/pan/resize rebuild the chart) — only keep a live one\n        if (trace.focusMarker && trace.focusMarker.node()?.isConnected) {\n            return;\n        }\n\n        const colorFill = trace.colorFull;\n        const marker = svg.append(\"circle\")\n            .style(\"fill\", \"#fff\")\n            .attr(\"stroke\", colorFill)\n            .attr(\"stroke-width\", 2)\n            .attr(\"r\", 5)\n            .style(\"opacity\", 0);\n        trace.focusMarker = marker;\n    }\n}\n\nclass ErrorBarsRenderable extends TraceRenderable {\n    mode: \"bars\" | \"lines\" = \"bars\";\n    keyLow = \"ciLow\";\n    keyHigh = \"ciHigh\";\n    keyValue = \"trend\";\n\n    updateBounds(): void {\n        const trace = this.trace;\n        const [xMin, xMax] = TraceRenderable.findMinMax(trace.items, [trace.keyX], trace.xMin, trace.xMax);\n        const [yMin, yMax] = TraceRenderable.findMinMax2(\n            trace.items,\n            [this.keyLow],\n            [this.keyHigh],\n            trace.yMin,\n            trace.yMax\n        );\n        trace.xMin = xMin;\n        trace.xMax = xMax;\n        trace.yMin = yMin;\n        trace.yMax = yMax;\n    }\n\n    render(): void {\n        if (this.mode === \"lines\") {\n            this.renderLines();\n        } else {\n            this.renderBars();\n        }\n    }\n\n    private renderBars(): void {\n        const trace = this.trace;\n        const svg = this.myD3.svg;\n        const x = this.myD3.axisX;\n        const y = this.myD3.axisY;\n        const barWidth = x(this.myD3.preparedPlot.xMin + 1) * 0.5;\n        const cls = `error-bars-${trace.traceIndex}`;\n\n        svg.selectAll(`rect.${cls}`)\n            .data(trace.items)\n            .enter()\n            .append(\"rect\")\n            .attr(\"class\", cls)\n            .attr(\"x\", (d: any) => x(d.data[trace.keyX]) - barWidth / 2)\n            .attr(\"y\", (d: any) => y(d.data[this.keyHigh]))\n            .attr(\"width\", barWidth)\n            .attr(\"height\", (d: any) => y(d.data[this.keyLow]) - y(d.data[this.keyHigh]))\n            .attr(\"fill\", trace.colorBarFill)\n            .attr(\"stroke\", trace.colorBarStroke);\n    }\n\n    private renderLines(): void {\n        const trace = this.trace;\n        const svg = this.myD3.svg;\n        const x = this.myD3.axisX;\n        const y = this.myD3.axisY;\n        const stroke = trace.colorDark;\n        const clsPoints = `error-points-${trace.traceIndex}`;\n        const clsLines = `error-lines-${trace.traceIndex}`;\n\n        svg.selectAll(`circle.${clsPoints}`)\n            .data(trace.items)\n            .enter()\n            .append(\"circle\")\n            //  myd3-rte-item + data-x let the hover handler dim the RTE items of the\n            //  non-hovered years (deliberately NOT myd3-year-marker — no size jump)\n            .attr(\"class\", `${clsPoints} myd3-rte-item`)\n            .attr(\"data-x\", (d: any) => d.data[trace.keyX])\n            .attr(\"cx\", (d: any) => x(d.data[trace.keyX]))\n            .attr(\"cy\", (d: any) => y(d.data[this.keyValue]))\n            .attr(\"r\", 3)\n            .attr(\"fill\", trace.colorDark);\n\n        svg.selectAll(`line.${clsLines}`)\n            .data(trace.items)\n            .enter()\n            .append(\"line\")\n            .attr(\"class\", `${clsLines} myd3-rte-item`)\n            .attr(\"data-x\", (d: any) => d.data[trace.keyX])\n            .attr(\"x1\", (d: any) => x(d.data[trace.keyX]))\n            .attr(\"y1\", (d: any) => y(d.data[this.keyLow]))\n            .attr(\"x2\", (d: any) => x(d.data[trace.keyX]))\n            .attr(\"y2\", (d: any) => y(d.data[this.keyHigh]))\n            .attr(\"stroke\", stroke)\n            .style(\"stroke-width\", this.myD3.dlStrokeWidthMul);\n    }\n}\n\nclass MarkersRenderable extends TraceRenderable {\n    updateBounds(): void {\n        // nothing to do\n    }\n\n    render(): void {\n        const trace = this.trace;\n        const svg = this.myD3.svg;\n        const x = this.myD3.axisX;\n        const y = this.myD3.axisY;\n        const cls = `marker-points-${trace.traceIndex}`;\n\n        svg.selectAll(`circle.${cls}`)\n            .data(trace.items)\n            .enter()\n            .append(\"circle\")\n            .attr(\"class\", `${cls} myd3-year-marker`)\n            .attr(\"data-x\", (d: any) => d.data[trace.keyX])\n            .attr(\"data-r\", 5)\n            .attr(\"cx\", (d: any) => x(d.data[trace.keyX]))\n            .attr(\"cy\", (d: any) => y(d.data[trace.keyY]))\n            .attr(\"r\", 5)\n            .attr(\"fill\", \"#fff\")\n            .attr(\"stroke\", trace.colorFull);\n    }\n}\n\nexport {\n    LineRenderable,\n    AreaRenderable,\n    FillAreaRenderable,\n    FocusMarkerRenderable,\n    ErrorBarsRenderable,\n    MarkersRenderable\n};\n\n\n","import { TraceRenderable } from \"./TraceRenderable\";\nimport type { Trace } from \"../core/PlotModel\";\nimport type { MyD3 } from \"../MyD3\";\n\nclass RectangleRenderable extends TraceRenderable {\n    constructor(myD3: MyD3, trace: Trace, sort: number) {\n        super(myD3, trace, sort);\n    }\n\n    updateBounds(): void {\n        const trace = this.trace;\n        trace.xMin = Math.min(\n            ...trace.items.map(item => Math.min(item.data.x0, item.data.x1)),\n            trace.xMin\n        );\n        trace.xMax = Math.max(\n            ...trace.items.map(item => Math.max(item.data.x0, item.data.x1)),\n            trace.xMax\n        );\n    }\n\n    render(): void {\n        const myD3 = this.myD3;\n        const svg = myD3.svg;\n        const x = myD3.axisX;\n        const y = myD3.axisY;\n        const baseY = y(myD3.preparedPlot.yMin);\n        const topY = y((myD3.preparedPlot.yMax - myD3.preparedPlot.yMin) * 0.05 + myD3.preparedPlot.yMin);\n\n        for (const item of this.trace.items) {\n            const color = `hsla(${item.data.hue || 1}, 100%, 50%, 0.25)`;\n            svg.append(\"rect\")\n                .attr(\"x\", x(item.data.x0))\n                .attr(\"y\", topY)\n                .attr(\"width\", x(item.data.x1) - x(item.data.x0))\n                .attr(\"height\", baseY - topY)\n                .attr(\"fill\", color);\n        }\n    }\n}\n\nexport { RectangleRenderable };\n\n\n","import * as d3 from \"d3\";\n\nimport type { Trace } from \"../core/PlotModel\";\nimport type { MyD3 } from \"../MyD3\";\nimport { TraceRenderable } from \"./TraceRenderable\";\nimport { Tooltip } from \"../tooltip/Tooltip\";\n\nconst HIT_STROKE_WIDTH = 12;   // invisible hover corridor around each line\nconst HIT_POINT_RADIUS = 10;   // hover radius around markers (covers single-point traces)\nconst NEARBY_PIXELS = 24;      // other lines within this pixel y-distance join the tooltip\nconst DIMMED_OPACITY = 0.25;\n\nconst ESCAPE_MAP: Record<string, string> = {\n    \"&\": \"&amp;\",\n    \"<\": \"&lt;\",\n    \">\": \"&gt;\",\n    '\"': \"&quot;\",\n    \"'\": \"&#39;\"\n};\n\nfunction escapeHtml(value: string): string {\n    return String(value).replace(/[&<>\"']/g, c => ESCAPE_MAP[c]);\n}\n\nfunction resolveCurve(name?: string): d3.CurveFactory {\n    switch (name) {\n        case \"monotoneX\": return d3.curveMonotoneX;\n        case \"catmullRom\": return d3.curveCatmullRom;\n        case \"natural\": return d3.curveNatural;\n        default: return d3.curveLinear;\n    }\n}\n\n/**\n * Shared per-plot hover state for all scatterLines traces of one MyD3 instance:\n * highlights the hovered trace, dims the rest and shows a proximity tooltip.\n * Only used by plots of type \"OTHER\" — the classic rendering path's overlay\n * rect would swallow the per-path mouse events.\n *\n * The svg and scales are snapshotted at render time via sync(): reading them\n * from myD3 at event time would break after an image export, because\n * MyD3.draw(options) re-renders into a detached svg and overwrites\n * myD3.svg/axisX/axisY.\n */\nclass ScatterLinesInteraction {\n    private readonly renderables: ScatterLinesRenderable[] = [];\n    private tooltip?: Tooltip;\n    private svg: any;\n    private x: any;\n    private y: any;\n\n    register(renderable: ScatterLinesRenderable): void {\n        if (!this.renderables.includes(renderable)) this.renderables.push(renderable);\n    }\n\n    sync(svg: any, x: any, y: any): void {\n        if (this.svg && this.svg.node() !== svg.node()) {\n            // the previous svg (and the tooltip's foreignObject in it) is gone\n            this.tooltip = undefined;\n        }\n        this.svg = svg;\n        this.x = x;\n        this.y = y;\n    }\n\n    private ensureTooltip(): void {\n        if (this.tooltip) return;\n        const xRange = this.x.range();\n        const yRange = this.y.range();\n        this.tooltip = new Tooltip(this.svg, xRange[1] - xRange[0], yRange[0] - yRange[1]);\n    }\n\n    onHover(active: ScatterLinesRenderable, event: MouseEvent): void {\n        if (!this.svg) return;\n        const x = this.x;\n        const y = this.y;\n        const mouse = d3.pointer(event, this.svg.node());\n        const mx = mouse[0];\n        const my = mouse[1];\n\n        const activeTrace = active.getTrace();\n        if (activeTrace.items.length === 0) return;\n\n        // nearest data point of the hovered trace, by pixel x\n        let nearest = activeTrace.items[0];\n        let bestDx = Infinity;\n        for (const item of activeTrace.items) {\n            const dx = Math.abs(x(item.data[activeTrace.keyX]) - mx);\n            if (dx < bestDx) {\n                bestDx = dx;\n                nearest = item;\n            }\n        }\n        const year = nearest.data[activeTrace.keyX];\n        const count = nearest.data[activeTrace.keyY];\n\n        for (const renderable of this.renderables) {\n            renderable.setDimmed(renderable !== active);\n            renderable.setHighlighted(renderable === active);\n        }\n\n        // other traces with data at that year that pass close to the cursor\n        const nearby: { title: string; color: string; count: number; dist: number }[] = [];\n        for (const renderable of this.renderables) {\n            if (renderable === active) continue;\n            const trace = renderable.getTrace();\n            const item = trace.items.find(i => i.data[trace.keyX] === year);\n            if (!item) continue;\n            const value = item.data[trace.keyY];\n            if (!Number.isFinite(value)) continue;\n            const dist = Math.abs(y(value) - my);\n            if (dist <= NEARBY_PIXELS) {\n                nearby.push({\n                    title: trace.title,\n                    color: trace.colorText,\n                    count: value,\n                    dist\n                });\n            }\n        }\n        nearby.sort((a, b) => a.dist - b.dist);\n\n        let html = `<div style=\"background: rgba(255,255,255,0.97); border: 1px solid #ddd; padding: 6px 10px; border-radius: 6px; box-shadow: 0 2px 8px rgba(0,0,0,0.15); font-size: 12px; font-family: sans-serif; max-width: 260px;\">`;\n        html += `<div style=\"font-weight: 700; font-size: 13px; color: #333; margin-bottom: 4px;\">${year}</div>`;\n        html += this.buildRow(activeTrace.title, activeTrace.colorText, count, true);\n        for (const n of nearby) {\n            html += this.buildRow(n.title, n.color, n.count, false);\n        }\n        html += `</div>`;\n\n        this.ensureTooltip();\n        this.tooltip!.show(html, x(year), y(count));\n    }\n\n    private buildRow(title: string, color: string, count: number, bold: boolean): string {\n        const countText = Number.isFinite(count) ? count.toLocaleString() : \"–\";\n        return `<div style=\"display: flex; align-items: center; gap: 6px; margin: 2px 0;${bold ? \" font-weight: 700;\" : \"\"}\">` +\n            `<span style=\"width: 8px; height: 8px; border-radius: 50%; background: ${color}; flex-shrink: 0;\"></span>` +\n            `<span style=\"color: #444; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;\">${escapeHtml(title)}</span>` +\n            `<span style=\"color: ${color};\">${countText}</span>` +\n            `</div>`;\n    }\n\n    reset(): void {\n        for (const renderable of this.renderables) {\n            renderable.setDimmed(false);\n            renderable.setHighlighted(false);\n        }\n        this.tooltip?.hide();\n    }\n}\n\nconst interactions = new WeakMap<MyD3, ScatterLinesInteraction>();\n\nfunction getInteraction(myD3: MyD3): ScatterLinesInteraction {\n    let interaction = interactions.get(myD3);\n    if (!interaction) {\n        interaction = new ScatterLinesInteraction();\n        interactions.set(myD3, interaction);\n    }\n    return interaction;\n}\n\n/**\n * One site's line + year markers with per-trace hover. Items are tabular\n * rows with keyX (default \"year\") and keyY (\"count\" via settings). Lines\n * connect straight across years with no observation; markers show exactly\n * which years were surveyed.\n */\nclass ScatterLinesRenderable extends TraceRenderable {\n    private linePath: any;\n    private markers: any;\n    private baseStrokeWidth = 2;\n\n    getTrace(): Trace {\n        return this.trace;\n    }\n\n    updateBounds(): void {\n        const trace = this.trace;\n        if (trace.items.length === 0) return;\n        // NaN seeds: the data alone defines the range (the Trace defaults of\n        // xMin = xMax = 0 would otherwise drag the x-axis down to year 0)\n        const [xMin, xMax] = TraceRenderable.findMinMax(trace.items, [trace.keyX], Number.NaN, Number.NaN);\n        const [yMin, yMax] = TraceRenderable.findMinMax(trace.items, [trace.keyY], Number.NaN, Number.NaN);\n        trace.xMin = xMin;\n        trace.xMax = xMax;\n        trace.yMin = Math.min(0, yMin);\n        trace.yMax = yMax;\n    }\n\n    render(): void {\n        const trace = this.trace;\n        const svg = this.myD3.svg;\n        const x = this.myD3.axisX;\n        const y = this.myD3.axisY;\n        // Image export re-renders every renderable into a detached svg\n        // (MyD3.svgInit). Draw the visuals there too, but keep hit areas and\n        // interaction state bound to the live on-screen svg only.\n        const live = !!(svg.node() as Element).isConnected;\n\n        this.baseStrokeWidth = 2 * this.myD3.dlStrokeWidthMul;\n\n        const lineGen = d3.line()\n            .defined((d: any) => Number.isFinite(d.data[trace.keyY]))\n            .x((d: any) => x(d.data[trace.keyX]))\n            .y((d: any) => y(d.data[trace.keyY]))\n            .curve(resolveCurve(trace.settings?.curve));\n\n        const linePath = svg.append(\"path\")\n            .datum(trace.items)\n            .attr(\"fill\", \"none\")\n            .attr(\"stroke\", trace.colorFull)\n            .attr(\"stroke-width\", this.baseStrokeWidth)\n            .attr(\"d\", lineGen);\n\n        const cls = `scatter-line-markers-${trace.traceIndex}`;\n        const markers = svg.selectAll(`circle.${cls}`)\n            .data(trace.items)\n            .enter()\n            .append(\"circle\")\n            .attr(\"class\", cls)\n            .attr(\"cx\", (d: any) => x(d.data[trace.keyX]))\n            .attr(\"cy\", (d: any) => y(d.data[trace.keyY]))\n            .attr(\"r\", 3.5)\n            .attr(\"fill\", \"#fff\")\n            .attr(\"stroke\", trace.colorFull)\n            .attr(\"stroke-width\", 1.5);\n\n        if (!live) return; // exported image needs no hit areas or hover state\n\n        this.linePath = linePath;\n        this.markers = markers;\n\n        const interaction = getInteraction(this.myD3);\n        interaction.register(this);\n        interaction.sync(svg, x, y);\n\n        // Invisible wide corridor along the line for easy hovering...\n        const hitPath = svg.append(\"path\")\n            .datum(trace.items)\n            .attr(\"fill\", \"none\")\n            .attr(\"stroke\", \"transparent\")\n            .attr(\"stroke-width\", HIT_STROKE_WIDTH)\n            .attr(\"stroke-linecap\", \"round\")\n            .style(\"pointer-events\", \"stroke\")\n            .attr(\"d\", lineGen);\n\n        // ...plus hit circles so single-point traces stay hoverable\n        const hitCls = `scatter-line-hits-${trace.traceIndex}`;\n        const hitCircles = svg.selectAll(`circle.${hitCls}`)\n            .data(trace.items)\n            .enter()\n            .append(\"circle\")\n            .attr(\"class\", hitCls)\n            .attr(\"cx\", (d: any) => x(d.data[trace.keyX]))\n            .attr(\"cy\", (d: any) => y(d.data[trace.keyY]))\n            .attr(\"r\", HIT_POINT_RADIUS)\n            .attr(\"fill\", \"transparent\")\n            .style(\"pointer-events\", \"all\");\n\n        const onMove = (event: MouseEvent) => interaction.onHover(this, event);\n        const onLeave = () => interaction.reset();\n        hitPath.on(\"mousemove\", onMove).on(\"mouseleave\", onLeave);\n        hitCircles.on(\"mousemove\", onMove).on(\"mouseleave\", onLeave);\n    }\n\n    setHighlighted(on: boolean): void {\n        this.linePath?.attr(\"stroke-width\", on ? this.baseStrokeWidth * 2 : this.baseStrokeWidth);\n    }\n\n    setDimmed(on: boolean): void {\n        const opacity = on ? DIMMED_OPACITY : 1;\n        this.linePath?.style(\"opacity\", opacity);\n        this.markers?.style(\"opacity\", opacity);\n    }\n}\n\nexport { ScatterLinesRenderable };\n","import * as d3 from \"d3\";\n\nimport type { Plot, Trace } from \"../core/PlotModel\";\nimport type { MyD3 } from \"../MyD3\";\nimport { TraceRenderable } from \"./TraceRenderable\";\nimport { Tooltip } from \"../tooltip/Tooltip\";\n\nabstract class ChartRenderable extends TraceRenderable {\n    protected tooltip?: Tooltip;\n\n    protected ensureTooltip(): void {\n        if (!this.tooltip) {\n            const xRange = this.myD3.axisX.range();\n            const yRange = this.myD3.axisY.range();\n            const width = xRange[1] - xRange[0];\n            const height = yRange[0] - yRange[1];\n            this.tooltip = new Tooltip(this.myD3.svg, width, height);\n        }\n    }\n\n    protected prepareData(): any[] {\n        return this.trace.items.map(item => ({ ...item.data }));\n    }\n\n    protected getBarFillColor(d: any): string {\n        // An explicit per-item `color` (hex/css) wins over the hue-derived fill.\n        return d.color || `hsl(${d.hue},60%,70%)`;\n    }\n\n    protected getBarStrokeColor(d: any): string {\n        return d.color ? \"#fff\" : `hsl(${d.hue},40%,30%)`;\n    }\n\n    protected getSeriesColor(d: any): string {\n        // Saturated variant for tooltip dots / emphasized text.\n        return d.color || `hsl(${d.hue},60%,50%)`;\n    }\n\n    protected getTextColor(d: any): string {\n        // Labels wear ink, not the series color — the bar itself carries the identity.\n        return d.fg ?? \"#1e293b\";\n    }\n\n    protected calculateTotal(data: any[]): number {\n        return data.reduce((sum, datum) => sum + (typeof datum.value === \"number\" ? datum.value : 0), 0);\n    }\n\n    protected createTooltipContent(d: any, total: number): string {\n        const label = d.label || \"\";\n        const value = d.value || 0;\n        const formattedValue = typeof value === \"number\" ? value.toLocaleString() : value;\n        const percentage = total ? ((value / total) * 100).toFixed(1) : \"0\";\n\n        if (d._isGroupedItem && Array.isArray(d._groupedChildren)) {\n            return this.createGroupedTooltipContent(d, total, label, formattedValue, ` (${percentage}%)`);\n        }\n\n        const dotColor = this.getSeriesColor(d);\n        const labelColor = d.color ? \"#333\" : `hsl(${d.hue},60%,35%)`;\n        const unit = this.trace.settings?.valueLabel ? ` ${this.trace.settings.valueLabel}` : \"\";\n        // Percentages are only meaningful when the bars are parts of one whole\n        // (a ranking/composition); count-per-category charts opt out.\n        const pctHtml = this.trace.settings?.hidePercent\n            ? \"\"\n            : `<span style=\"color: #888;\">${percentage}%</span>`;\n        return `<div style=\"background: rgba(255,255,255,0.97); border: 1px solid #ddd; padding: 6px 10px; border-radius: 6px; box-shadow: 0 2px 8px rgba(0,0,0,0.15); font-size: 12px; font-family: sans-serif;\">\n            <div style=\"display: flex; align-items: center; gap: 6px; margin-bottom: 2px;\">\n                <span style=\"width: 8px; height: 8px; border-radius: 50%; background: ${dotColor}; flex-shrink: 0;\"></span>\n                <span style=\"font-weight: 700; color: ${labelColor};\">${label}</span>\n            </div>\n            <div style=\"display: flex; justify-content: space-between; gap: 12px; color: #444;\">\n                <span>${formattedValue}${unit}</span>\n                ${pctHtml}\n            </div>\n        </div>`;\n    }\n\n    protected createGroupedTooltipContent(d: any, total: number, label: string, formattedValue: string, percentage: string): string {\n        const childrenCount = d._groupedChildren.length;\n        const canvasWidth = this.myD3.dlWidth || 400;\n        const canvasHeight = this.myD3.dlHeight || 300;\n        const maxTooltipWidth = Math.min(350, canvasWidth * 0.8);\n        const maxTooltipHeight = Math.min(250, canvasHeight * 0.6);\n        const headerHeight = 80;\n        const itemHeight = 20;\n        const indicatorHeight = 25;\n        const maxVisibleItems = Math.max(3, Math.floor((maxTooltipHeight - headerHeight - indicatorHeight) / itemHeight));\n\n        let childrenHtml = \"\";\n        const visibleCount = Math.min(childrenCount, maxVisibleItems);\n\n        for (let i = 0; i < visibleCount; i += 1) {\n            const child = d._groupedChildren[i];\n            const childFormattedValue = typeof child.value === \"number\" ? child.value.toLocaleString() : child.value;\n            childrenHtml += `\n                <div style=\"text-align: left; margin: 2px 0; font-size: 11px; color: #666; padding: 1px 0;\">\n                    • ${this.truncateLabel(child.label, maxTooltipWidth - 40)}: ${childFormattedValue} (${child.percentage.toFixed(1)}%)\n                </div>`;\n        }\n\n        if (visibleCount < childrenCount) {\n            const remainingCount = childrenCount - visibleCount;\n            childrenHtml += `\n                <div style=\"text-align: center; margin: 6px 0 2px 0; font-size: 10px; color: #999; font-style: italic; padding: 4px 0; border-top: 1px dotted #ddd; background-color: #f8f9fa;\">\n                    ... and ${remainingCount} more item${remainingCount !== 1 ? \"s\" : \"\"}\n                </div>`;\n        }\n\n        return `<div class=\"fs-6\" style=\"border: 1px solid #ccc; padding: 8px; background-color: #fff; border-radius: 5px; text-align: center; font-family: sans-serif; box-shadow: 0 2px 4px rgba(0,0,0,0.1); max-width: ${maxTooltipWidth}px;\">\n            <strong style=\"color: hsl(${d.hue},50%,40%);\">${this.truncateLabel(label, maxTooltipWidth - 20)}</strong><br/>\n            <span style=\"color: hsl(${d.hue},50%,40%);\">${formattedValue}${percentage}</span><br/>\n            <div style=\"margin-top: 6px; padding-top: 6px; border-top: 1px solid #eee;\">\n                <div style=\"font-size: 10px; color: #888; margin-bottom: 4px;\">Contains ${childrenCount} item${childrenCount !== 1 ? \"s\" : \"\"}:</div>\n                <div>${childrenHtml}</div>\n            </div>\n        </div>`;\n    }\n\n    protected truncateLabel(text: string, maxWidth: number): string {\n        if (!text) return \"\";\n        const maxChars = Math.floor(maxWidth / 7);\n        if (text.length <= maxChars) return text;\n        return `${text.substring(0, Math.max(1, maxChars - 3))}...`;\n    }\n\n    protected showTooltip(event: MouseEvent, data: any, total: number): void {\n        this.ensureTooltip();\n        const mouse = d3.pointer(event, this.myD3.svg.node());\n        const html = this.createTooltipContent(data, total);\n        this.tooltip!.show(html, mouse[0], mouse[1]);\n    }\n\n    protected hideTooltip(): void {\n        this.tooltip?.hide();\n    }\n\n    updateBounds(): void {\n        // Default charts do not affect bounds; specialized charts can override\n        return;\n    }\n}\n\nclass PieRenderable extends ChartRenderable {\n    private readonly LABEL_FONT_SIZE = 11;\n    private readonly MIN_LABEL_ANGLE = Math.PI / 18; // ~10 degrees - minimum arc angle to show label\n\n    protected prepareData(): any[] {\n        return this.myD3.groupSmallItems(\n            super.prepareData(),\n            (item) => item.value || 0,\n            (item) => item.label || \"\",\n            (item, label) => ({ ...item, label }),\n            (item, value) => ({ ...item, value }),\n            this.myD3.customOptions?.groupSmallItems\n        );\n    }\n\n    private getPieSettings(): {\n        showLabels: boolean;\n        labelType: 'label' | 'value' | 'percent' | 'labelValue' | 'labelPercent';\n        minLabelAngle: number;\n        labelPosition: 'inside' | 'outside';\n        innerRadiusRatio: number;\n        keepOrder: boolean;\n        hoverGrow: boolean;\n        onSliceClick?: (item: any) => void;\n        centerText?: { value: string; label?: string; sub?: string | string[] };\n    } {\n        const settings = this.trace.settings || {};\n        return {\n            showLabels: settings.showLabels !== false, // default true\n            labelType: settings.labelType || 'label',\n            minLabelAngle: settings.minLabelAngle ?? this.MIN_LABEL_ANGLE,\n            labelPosition: settings.labelPosition || 'inside',\n            // 0 = classic pie; > 0 = donut (hole radius as a fraction of the outer radius)\n            innerRadiusRatio: settings.innerRadiusRatio ?? 0,\n            // true = slices follow data order (d3 default re-sorts by value)\n            keepOrder: settings.keepOrder === true,\n            hoverGrow: settings.hoverGrow === true,\n            onSliceClick: typeof settings.onSliceClick === \"function\" ? settings.onSliceClick : undefined,\n            centerText: settings.centerText,\n        };\n    }\n\n    private formatLabel(d: any, total: number, labelType: string): string {\n        const label = d.data?.label || d.label || \"\";\n        const value = d.data?.value ?? d.value ?? 0;\n        const percent = total > 0 ? ((value / total) * 100).toFixed(1) : \"0\";\n\n        switch (labelType) {\n            case 'value':\n                return value.toLocaleString();\n            case 'percent':\n                return `${percent}%`;\n            case 'labelValue':\n                return `${label}: ${value.toLocaleString()}`;\n            case 'labelPercent':\n                return `${label} (${percent}%)`;\n            case 'label':\n            default:\n                return label;\n        }\n    }\n\n    private getLabelColor(d: any): string {\n        // Slices with an explicit hex fill wear neutral ink (the white text-shadow\n        // halo keeps it legible on any colour); hue-based slices keep the dark tint.\n        if (d.data?.color ?? d.color) return \"#1e293b\";\n        const hue = d.data?.hue ?? d.hue ?? 0;\n        return `hsl(${hue}, 80%, 20%)`;\n    }\n\n    render(): void {\n        const data = this.prepareData();\n        const total = this.calculateTotal(data);\n        const pieSettings = this.getPieSettings();\n\n        const xRange = this.myD3.axisX.range();\n        const yRange = this.myD3.axisY.range();\n        const width = xRange[1] - xRange[0];\n        const height = yRange[0] - yRange[1];\n        const radius = Math.min(width, height) / 2;\n        const innerRadius = radius * pieSettings.innerRadiusRatio;\n\n        const group = this.myD3.svg.append(\"g\")\n            .attr(\"transform\", `translate(${width / 2},${height / 2})`);\n\n        const pieGen = d3.pie<any>().value((d: any) => d.value);\n        if (pieSettings.keepOrder) pieGen.sort(null);\n        // Donuts leave a sliver of headroom so the hover-grow effect stays inside the plot.\n        const restRadius = pieSettings.hoverGrow ? radius * 0.98 : radius;\n        const arcGen = d3.arc<any>().innerRadius(innerRadius).outerRadius(restRadius);\n        const arcGrown = d3.arc<any>().innerRadius(innerRadius).outerRadius(radius);\n        const arcs = pieGen(data);\n\n        // Draw pie segments\n        const paths = group.selectAll(\"path\")\n            .data(arcs)\n            .enter()\n            .append(\"path\")\n            .attr(\"d\", arcGen as any)\n            .attr(\"fill\", (d: any) => this.getBarFillColor(d.data))\n            .attr(\"stroke\", (d: any) => this.getBarStrokeColor(d.data))\n            .attr(\"stroke-width\", pieSettings.innerRadiusRatio > 0 ? 2 : 1)\n            .on(\"mouseenter\", (event: MouseEvent, d: any) => {\n                this.showTooltip(event, d.data, total);\n                if (pieSettings.hoverGrow) {\n                    d3.select(event.currentTarget as any).transition().duration(120).attr(\"d\", arcGrown as any);\n                    paths.style(\"opacity\", (a: any) => (a === d ? 1 : 0.55));\n                }\n            })\n            .on(\"mousemove\", (event: MouseEvent, d: any) => this.showTooltip(event, d.data, total))\n            .on(\"mouseleave\", (event: MouseEvent) => {\n                this.hideTooltip();\n                if (pieSettings.hoverGrow) {\n                    d3.select(event.currentTarget as any).transition().duration(120).attr(\"d\", arcGen as any);\n                    paths.style(\"opacity\", 1);\n                }\n            });\n\n        if (pieSettings.onSliceClick) {\n            paths.style(\"cursor\", \"pointer\")\n                .on(\"click\", (_event: MouseEvent, d: any) => pieSettings.onSliceClick!(d.data));\n        }\n\n        if (pieSettings.centerText && innerRadius > 0) {\n            this.renderCenterText(group, innerRadius, pieSettings.centerText);\n        }\n\n        // Draw labels if enabled\n        if (pieSettings.showLabels) {\n            this.renderLabels(group, arcs, arcGen, radius, total, pieSettings);\n        }\n    }\n\n    /** Total + caption inside a donut hole, sized to fit the hole. */\n    private renderCenterText(group: any, innerRadius: number, centerText: { value: string; label?: string; sub?: string | string[] }): void {\n        const valueSize = Math.max(14, Math.min(26, innerRadius * 0.42));\n        group.append(\"text\")\n            .attr(\"text-anchor\", \"middle\")\n            .attr(\"dy\", centerText.label ? \"-0.1em\" : \"0.35em\")\n            .style(\"font-size\", `${valueSize}px`)\n            .style(\"font-weight\", \"700\")\n            .style(\"fill\", \"#1e293b\")\n            .style(\"font-variant-numeric\", \"tabular-nums\")\n            .style(\"pointer-events\", \"none\")\n            .text(centerText.value);\n        if (centerText.label) {\n            group.append(\"text\")\n                .attr(\"text-anchor\", \"middle\")\n                .attr(\"dy\", \"1.5em\")\n                .style(\"font-size\", `${Math.max(9, valueSize * 0.45)}px`)\n                .style(\"letter-spacing\", \"0.04em\")\n                .style(\"text-transform\", \"uppercase\")\n                .style(\"fill\", \"#64748b\")\n                .style(\"pointer-events\", \"none\")\n                .text(centerText.label);\n        }\n        if (centerText.sub) {\n            // sub may be a single string or several stacked lines (used when the\n            // caption is too wide to fit the hole on one line, e.g. in German).\n            const subLines = Array.isArray(centerText.sub) ? centerText.sub : [centerText.sub];\n            const baseDy = centerText.label ? 2.7 : 1.6;\n            subLines.forEach((line, i) => {\n                group.append(\"text\")\n                    .attr(\"text-anchor\", \"middle\")\n                    .attr(\"dy\", `${baseDy + i * 1.15}em`)\n                    .style(\"font-size\", `${Math.max(8, valueSize * 0.34)}px`)\n                    .style(\"letter-spacing\", \"0.05em\")\n                    .style(\"text-transform\", \"uppercase\")\n                    .style(\"fill\", \"#94a3b8\")\n                    .style(\"pointer-events\", \"none\")\n                    .text(line);\n            });\n        }\n    }\n\n    private renderLabels(\n        group: any,\n        arcs: d3.PieArcDatum<any>[],\n        arcGen: d3.Arc<any, d3.DefaultArcObject>,\n        radius: number,\n        total: number,\n        settings: ReturnType<typeof this.getPieSettings>\n    ): void {\n        const labelArcGen = settings.labelPosition === 'outside'\n            ? d3.arc<any>().innerRadius(radius * 0.7).outerRadius(radius * 1.1)\n            : d3.arc<any>().innerRadius(radius * 0.4).outerRadius(radius * 0.7);\n\n        const labels = group.selectAll(\"text.pie-label\")\n            .data(arcs)\n            .enter()\n            .append(\"text\")\n            .attr(\"class\", \"pie-label\")\n            .attr(\"transform\", (d: any) => `translate(${labelArcGen.centroid(d)})`)\n            .attr(\"text-anchor\", \"middle\")\n            .attr(\"dominant-baseline\", \"middle\")\n            .style(\"font-size\", `${this.LABEL_FONT_SIZE}px`)\n            .style(\"font-family\", \"sans-serif\")\n            .style(\"font-weight\", \"600\")\n            .style(\"fill\", (d: any) => this.getLabelColor(d))\n            .style(\"pointer-events\", \"none\")\n            .style(\"text-shadow\", \"0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff\")\n            .text((d: any) => {\n                // Only show label if segment is large enough\n                const arcAngle = d.endAngle - d.startAngle;\n                if (arcAngle < settings.minLabelAngle) return \"\";\n                return this.formatLabel(d, total, settings.labelType);\n            });\n\n        // Truncate labels that are too long for their segment\n        labels.each(function(this: SVGTextElement, d: any) {\n            const arcAngle = d.endAngle - d.startAngle;\n            const arcLength = arcAngle * radius * 0.5; // approximate chord length at label position\n            const maxChars = Math.floor(arcLength / 6); // rough estimate of chars that fit\n\n            const text = d3.select(this);\n            const originalText = text.text();\n            if (originalText.length > maxChars && maxChars > 3) {\n                text.text(originalText.substring(0, maxChars - 2) + \"…\");\n            }\n        });\n    }\n}\n\nclass BarsRenderable extends ChartRenderable {\n    private readonly BAR_SPACE_RATIO = 0.8;\n    private readonly FONT_SIZE = \"12px\";\n    private readonly STROKE_WIDTH = 1;\n\n    protected prepareData(): any[] {\n        return this.myD3.groupSmallItems(\n            super.prepareData(),\n            (item) => item.value || 0,\n            (item) => item.label || \"\",\n            (item, label) => ({ ...item, label }),\n            (item, value) => ({ ...item, value }),\n            this.myD3.customOptions?.groupSmallItems\n        );\n    }\n\n    configureAxes(plot: Plot): void {\n        const data = this.prepareData();\n        if (data.length === 0) return;\n\n        const labels = data.map(d => d.label || \"\");\n        if (this.isHorizontalOrientation()) {\n            plot.axisYType = \"categorical\";\n            plot.categoricalYLabels = labels;\n        } else {\n            plot.axisXType = \"categorical\";\n            plot.categoricalXLabels = labels;\n        }\n    }\n\n    updateBounds(): void {\n        const data = this.prepareData();\n        if (data.length === 0) return;\n\n        const trace = this.trace;\n        const isHorizontal = this.isHorizontalOrientation();\n        const values = data.map(d => d.value || 0);\n        const minValue = Math.min(...values);\n        const maxValue = Math.max(...values);\n\n        if (isHorizontal) {\n            trace.xMin = Math.min(trace.xMin, Math.min(0, minValue));\n            trace.xMax = Math.max(trace.xMax, maxValue);\n            trace.yMin = Math.min(trace.yMin, 0);\n            trace.yMax = Math.max(trace.yMax, data.length);\n        } else {\n            trace.yMin = Math.min(trace.yMin, Math.min(0, minValue));\n            trace.yMax = Math.max(trace.yMax, maxValue);\n            trace.xMin = Math.min(trace.xMin, 0);\n            trace.xMax = Math.max(trace.xMax, data.length);\n        }\n    }\n\n    render(): void {\n        const data = this.prepareData();\n        if (data.length === 0) return;\n        const maxValue = Math.max(...data.map(d => d.value || 0));\n        if (maxValue === 0) return;\n\n        const dimensions = this.getChartDimensions();\n        const g = this.myD3.svg.append(\"g\");\n\n        if (this.isHorizontalOrientation()) {\n            this.renderHorizontalBars(g, data, dimensions.height);\n        } else {\n            this.renderVerticalBars(g, data, dimensions.width);\n        }\n    }\n\n    private isHorizontalOrientation(): boolean {\n        return this.trace.settings?.orientation === \"horizontal\";\n    }\n\n    private getChartDimensions(): { width: number; height: number } {\n        const xRange = this.myD3.axisX.range();\n        const yRange = this.myD3.axisY.range();\n        return {\n            width: xRange[1] - xRange[0],\n            height: yRange[0] - yRange[1]\n        };\n    }\n\n    private renderVerticalBars(group: any, data: any[], width: number): void {\n        const total = this.calculateTotal(data);\n        const axisY = this.myD3.axisY;\n        const barSpacing = width / data.length;\n        const barWidth = barSpacing * this.BAR_SPACE_RATIO;\n        const bars = this.createVerticalBarRects(group, data, axisY, barSpacing, barWidth);\n        if (this.myD3.shouldRenderBarLabels(barWidth, parseFloat(this.FONT_SIZE) + 2)) {\n            this.createVerticalBarLabels(group, data, axisY, barSpacing);\n        }\n        this.attachTooltips(bars, total);\n    }\n\n    private createVerticalBarRects(group: any, data: any[], axisY: any, barSpacing: number, barWidth: number) {\n        const axisX = this.myD3.axisX;\n        const plot = this.myD3.preparedPlot;\n\n        return group.selectAll(\"rect.vertical-bar\")\n            .data(data)\n            .enter()\n            .append(\"rect\")\n            .attr(\"class\", \"vertical-bar\")\n            .attr(\"x\", (d: any, index: number) => {\n                if (plot.axisXType === \"categorical\" && axisX.bandwidth) {\n                    const bandScale = d3.scaleBand()\n                        .domain(plot.categoricalXLabels.map((_, idx) => idx.toString()))\n                        .range(axisX.range())\n                        .padding(0.1);\n                    return bandScale(index.toString()) || 0;\n                }\n                return index * barSpacing + (barSpacing - barWidth) / 2;\n            })\n            .attr(\"y\", (d: any) => Math.min(axisY(0), axisY(d.value || 0)))\n            .attr(\"width\", (d: any, index: number) => {\n                if (plot.axisXType === \"categorical\" && axisX.bandwidth) {\n                    const bandScale = d3.scaleBand()\n                        .domain(plot.categoricalXLabels.map((_, idx) => idx.toString()))\n                        .range(axisX.range())\n                        .padding(0.1);\n                    return bandScale.bandwidth();\n                }\n                return barWidth;\n            })\n            .attr(\"height\", (d: any) => Math.abs(axisY(0) - axisY(d.value || 0)))\n            .attr(\"fill\", (d: any) => this.getBarFillColor(d))\n            .attr(\"stroke\", (d: any) => this.getBarStrokeColor(d))\n            .attr(\"stroke-width\", this.STROKE_WIDTH);\n    }\n\n    private createVerticalBarLabels(group: any, data: any[], axisY: any, barSpacing: number): void {\n        const axisX = this.myD3.axisX;\n        const plot = this.myD3.preparedPlot;\n        const fontSize = parseFloat(this.FONT_SIZE);\n        const xRange = axisX.range();\n        const yRange = axisY.range();\n        const plotBounds = { left: xRange[0], right: xRange[1], top: yRange[1], bottom: yRange[0] };\n        const alignment = this.myD3.getBarLabelAlignment(true);\n\n        const labels = group.selectAll(\"text.vertical-label\")\n            .data(data)\n            .enter()\n            .append(\"text\")\n            .attr(\"class\", \"vertical-label\")\n            .attr(\"x\", (_: any, index: number) => {\n                if (plot.axisXType === \"categorical\" && axisX.bandwidth) {\n                    const bandScale = d3.scaleBand()\n                        .domain(plot.categoricalXLabels.map((_, idx) => idx.toString()))\n                        .range(axisX.range())\n                        .padding(0.1);\n                    return (bandScale(index.toString()) || 0) + bandScale.bandwidth() / 2;\n                }\n                return index * barSpacing + barSpacing / 2;\n            })\n            .attr(\"y\", (d: any, index: number) => {\n                const barHeight = Math.abs(axisY(0) - axisY(d.value || 0));\n                const barTop = Math.min(axisY(0), axisY(d.value || 0));\n                const barBottom = Math.max(axisY(0), axisY(d.value || 0));\n\n                let barCenterX: number;\n                if (plot.axisXType === \"categorical\" && axisX.bandwidth) {\n                    const bandScale = d3.scaleBand()\n                        .domain(plot.categoricalXLabels.map((_, idx) => idx.toString()))\n                        .range(axisX.range())\n                        .padding(0.1);\n                    barCenterX = (bandScale(index.toString()) || 0) + bandScale.bandwidth() / 2;\n                } else {\n                    barCenterX = index * barSpacing + barSpacing / 2;\n                }\n\n                const barBounds = {\n                    left: barCenterX - barSpacing * 0.4,\n                    right: barCenterX + barSpacing * 0.4,\n                    top: barTop,\n                    bottom: barBottom,\n                    center: { x: barCenterX, y: barTop + barHeight / 2 }\n                };\n\n                const label = d.label || \"\";\n                const textBounds = {\n                    width: label.length * fontSize * 0.6,\n                    height: fontSize\n                };\n\n                const position = this.myD3.calculateBarLabelPosition(barBounds, plotBounds, textBounds, true);\n                return position.y;\n            })\n            .attr(\"text-anchor\", alignment.textAnchor)\n            .attr(\"dominant-baseline\", alignment.dominantBaseline)\n            .attr(\"transform\", (d: any, index: number) => {\n                let x: number;\n                if (plot.axisXType === \"categorical\" && axisX.bandwidth) {\n                    const bandScale = d3.scaleBand()\n                        .domain(plot.categoricalXLabels.map((_, idx) => idx.toString()))\n                        .range(axisX.range())\n                        .padding(0.1);\n                    x = (bandScale(index.toString()) || 0) + bandScale.bandwidth() / 2;\n                } else {\n                    x = index * barSpacing + barSpacing / 2;\n                }\n\n                const barHeight = Math.abs(axisY(0) - axisY(d.value || 0));\n                const barTop = Math.min(axisY(0), axisY(d.value || 0));\n                const barBottom = Math.max(axisY(0), axisY(d.value || 0));\n\n                const barBounds = {\n                    left: x - barSpacing * 0.4,\n                    right: x + barSpacing * 0.4,\n                    top: barTop,\n                    bottom: barBottom,\n                    center: { x, y: barTop + barHeight / 2 }\n                };\n\n                const label = d.label || \"\";\n                const textBounds = { width: label.length * fontSize * 0.6, height: fontSize };\n                const position = this.myD3.calculateBarLabelPosition(barBounds, plotBounds, textBounds, true);\n                return `rotate(-90, ${position.x}, ${position.y})`;\n            })\n            .style(\"font-size\", this.FONT_SIZE)\n            .style(\"font-family\", \"sans-serif\")\n            .style(\"fill\", (d: any) => this.getTextColor(d))\n            .text((d: any) => {\n                const label = d.label || \"\";\n                const maxTextWidth = plotBounds.bottom - plotBounds.top - 20;\n                return this.myD3.truncateTextWithEllipsis(label, maxTextWidth, fontSize);\n            });\n\n        this.myD3.applyBarLabelStyling(labels);\n        const total = this.calculateTotal(data);\n        this.attachTooltips(labels, total);\n    }\n\n    private renderHorizontalBars(group: any, data: any[], height: number): void {\n        const total = this.calculateTotal(data);\n        const axisX = this.myD3.axisX;\n        const barSpacing = height / data.length;\n        const barHeight = barSpacing * this.BAR_SPACE_RATIO;\n        const bars = this.createHorizontalBarRects(group, data, axisX, barSpacing, barHeight);\n        if (this.myD3.shouldRenderBarLabels(barHeight, parseFloat(this.FONT_SIZE))) {\n            this.createHorizontalBarLabels(group, data, axisX, barSpacing);\n        }\n        this.attachTooltips(bars, total);\n    }\n\n    private createHorizontalBarRects(group: any, data: any[], axisX: any, barSpacing: number, barHeight: number) {\n        const axisY = this.myD3.axisY;\n        const plot = this.myD3.preparedPlot;\n\n        return group.selectAll(\"rect.horizontal-bar\")\n            .data(data)\n            .enter()\n            .append(\"rect\")\n            .attr(\"class\", \"horizontal-bar\")\n            .attr(\"x\", (d: any) => Math.min(axisX(0), axisX(d.value || 0)))\n            .attr(\"y\", (_: any, index: number) => {\n                if (plot.axisYType === \"categorical\" && axisY.bandwidth) {\n                    const bandScale = d3.scaleBand()\n                        .domain(plot.categoricalYLabels.map((_, idx) => idx.toString()))\n                        .range(axisY.range())\n                        .padding(0.1);\n                    return bandScale(index.toString()) || 0;\n                }\n                return index * barSpacing + (barSpacing - barHeight) / 2;\n            })\n            .attr(\"width\", (d: any) => Math.abs(axisX(0) - axisX(d.value || 0)))\n            .attr(\"height\", (_: any, index: number) => {\n                if (plot.axisYType === \"categorical\" && axisY.bandwidth) {\n                    const bandScale = d3.scaleBand()\n                        .domain(plot.categoricalYLabels.map((_, idx) => idx.toString()))\n                        .range(axisY.range())\n                        .padding(0.1);\n                    return bandScale.bandwidth();\n                }\n                return barHeight;\n            })\n            .attr(\"fill\", (d: any) => this.getBarFillColor(d))\n            .attr(\"stroke\", (d: any) => this.getBarStrokeColor(d))\n            .attr(\"stroke-width\", this.STROKE_WIDTH);\n    }\n\n    private createHorizontalBarLabels(group: any, data: any[], axisX: any, barSpacing: number): void {\n        const axisY = this.myD3.axisY;\n        const plot = this.myD3.preparedPlot;\n        const fontSize = parseFloat(this.FONT_SIZE);\n        const xRange = axisX.range();\n        const yRange = axisY.range();\n        const plotBounds = { left: xRange[0], right: xRange[1], top: yRange[1], bottom: yRange[0] };\n        const alignment = this.myD3.getBarLabelAlignment(false);\n\n        const labels = group.selectAll(\"text.horizontal-label\")\n            .data(data)\n            .enter()\n            .append(\"text\")\n            .attr(\"class\", \"horizontal-label\")\n            .attr(\"x\", (d: any) => {\n                const barWidth = Math.abs(axisX(0) - axisX(d.value || 0));\n                const barLeft = Math.min(axisX(0), axisX(d.value || 0));\n                const barRight = Math.max(axisX(0), axisX(d.value || 0));\n                const barBounds = {\n                    left: barLeft,\n                    right: barRight,\n                    top: 0,\n                    bottom: 0,\n                    center: { x: barLeft + barWidth / 2, y: 0 }\n                };\n\n                const label = d.label || \"\";\n                const textBounds = { width: label.length * fontSize * 0.6, height: fontSize };\n                const position = this.myD3.calculateBarLabelPosition(barBounds, plotBounds, textBounds, false);\n                return position.x;\n            })\n            .attr(\"y\", (_: any, index: number) => {\n                if (plot.axisYType === \"categorical\" && axisY.bandwidth) {\n                    const bandScale = d3.scaleBand()\n                        .domain(plot.categoricalYLabels.map((_, idx) => idx.toString()))\n                        .range(axisY.range())\n                        .padding(0.1);\n                    return (bandScale(index.toString()) || 0) + bandScale.bandwidth() / 2;\n                }\n                return index * barSpacing + barSpacing / 2;\n            })\n            .attr(\"dy\", \"0.35em\")\n            .attr(\"text-anchor\", alignment.textAnchor)\n            .attr(\"dominant-baseline\", alignment.dominantBaseline)\n            .style(\"font-size\", this.FONT_SIZE)\n            .style(\"font-family\", \"sans-serif\")\n            .style(\"fill\", (d: any) => this.getTextColor(d))\n            .text((d: any) => {\n                const label = d.label || \"\";\n                const maxTextWidth = plotBounds.right - plotBounds.left - 20;\n                return this.myD3.truncateTextWithEllipsis(label, maxTextWidth, fontSize);\n            });\n\n        this.myD3.applyBarLabelStyling(labels);\n        const total = this.calculateTotal(data);\n        this.attachTooltips(labels, total);\n    }\n\n    private attachTooltips(selection: any, total: number): void {\n        selection\n            .on(\"mouseenter\", (event: MouseEvent, d: any) => this.showTooltip(event, d, total))\n            .on(\"mousemove\", (event: MouseEvent, d: any) => this.showTooltip(event, d, total))\n            .on(\"mouseleave\", () => this.hideTooltip());\n    }\n}\n\n/**\n * StackedBarsRenderable - Renders stacked bar charts with multiple series per category.\n * \n * Data format expected in trace.settings.stacks:\n * {\n *   categories: string[],           // e.g., ['2020', '2021', '2022'] - the x-axis labels\n *   series: Array<{\n *     id: string,                   // unique identifier for the series\n *     label: string,                // display name\n *     hue: number,                  // HSL hue value for coloring\n *     values: Map<string, number>   // category -> value mapping\n *   }>\n * }\n * \n * Settings:\n * - showLabels: boolean - whether to show value labels on segments (default: false)\n * - labelMinHeight: number - minimum segment height in pixels to show label (default: 20)\n */\nclass StackedBarsRenderable extends ChartRenderable {\n    private readonly BAR_SPACE_RATIO = 0.8;\n    private readonly FONT_SIZE = 11;\n    private readonly STROKE_WIDTH = 1;\n\n    private getStackSettings(): {\n        showLabels: boolean;\n        labelMinHeight: number;\n    } {\n        const settings = this.trace.settings || {};\n        return {\n            showLabels: settings.showLabels === true,\n            labelMinHeight: settings.labelMinHeight ?? 20,\n        };\n    }\n\n    configureAxes(plot: any): void {\n        const stacks = this.trace.settings?.stacks;\n        if (!stacks || !stacks.categories) return;\n\n        plot.axisXType = \"categorical\";\n        plot.categoricalXLabels = stacks.categories.map(String);\n    }\n\n    updateBounds(): void {\n        const stacks = this.trace.settings?.stacks;\n        if (!stacks) return;\n\n        const { categories, series } = stacks;\n        if (!categories || !series || series.length === 0) return;\n\n        // Calculate max stack height for each category\n        let maxStackHeight = 0;\n        for (const category of categories) {\n            let stackTotal = 0;\n            for (const s of series) {\n                const value = s.values?.get?.(String(category)) ?? s.values?.[String(category)] ?? 0;\n                stackTotal += value;\n            }\n            maxStackHeight = Math.max(maxStackHeight, stackTotal);\n        }\n\n        this.trace.yMin = 0;\n        this.trace.yMax = Math.max(this.trace.yMax, maxStackHeight * 1.05); // 5% padding\n        this.trace.xMin = 0;\n        this.trace.xMax = categories.length;\n    }\n\n    render(): void {\n        const stacks = this.trace.settings?.stacks;\n        if (!stacks) return;\n\n        const { categories, series } = stacks;\n        if (!categories || categories.length === 0 || !series || series.length === 0) return;\n\n        const xRange = this.myD3.axisX.range();\n        const axisY = this.myD3.axisY;\n        const width = xRange[1] - xRange[0];\n        const baselineY = axisY(0);\n\n        const group = this.myD3.svg.append(\"g\").attr(\"class\", \"stacked-bars\");\n\n        // Create band scale for categories\n        const bandScale = d3.scaleBand<string>()\n            .domain(categories.map(String))\n            .range([0, width])\n            .padding(1 - this.BAR_SPACE_RATIO);\n\n        const stackSettings = this.getStackSettings();\n\n        // For each category, draw stacked bars\n        for (const category of categories) {\n            const catStr = String(category);\n            const x = bandScale(catStr) ?? 0;\n            const barWidth = bandScale.bandwidth();\n\n            let cumulativeValue = 0; // Track cumulative value for stacking\n\n            // Stack series from bottom to top\n            for (const s of series) {\n                const value = s.values?.get?.(catStr) ?? s.values?.[catStr] ?? 0;\n                if (value <= 0) continue;\n\n                const segmentBottom = axisY(cumulativeValue);\n                const segmentTop = axisY(cumulativeValue + value);\n                const segmentHeight = Math.abs(segmentBottom - segmentTop);\n\n                // Draw the bar segment. An explicit series `color` (hex) wins\n                // over the hue-derived fill, keeping stacks on the shared palette.\n                const rect = group.append(\"rect\")\n                    .attr(\"class\", \"stacked-bar-segment\")\n                    .attr(\"x\", x)\n                    .attr(\"y\", segmentTop)\n                    .attr(\"width\", barWidth)\n                    .attr(\"height\", segmentHeight)\n                    .attr(\"fill\", s.color || `hsl(${s.hue}, 60%, 70%)`)\n                    .attr(\"stroke\", s.color ? \"#fff\" : `hsl(${s.hue}, 40%, 30%)`)\n                    .attr(\"stroke-width\", this.STROKE_WIDTH);\n\n                // Add tooltip\n                this.attachSegmentTooltip(rect, s, value, category);\n\n                // Add label if enabled and segment is tall enough\n                if (stackSettings.showLabels && segmentHeight >= stackSettings.labelMinHeight) {\n                    group.append(\"text\")\n                        .attr(\"class\", \"stacked-bar-label\")\n                        .attr(\"x\", x + barWidth / 2)\n                        .attr(\"y\", segmentTop + segmentHeight / 2)\n                        .attr(\"text-anchor\", \"middle\")\n                        .attr(\"dominant-baseline\", \"middle\")\n                        .style(\"font-size\", `${this.FONT_SIZE}px`)\n                        .style(\"font-family\", \"sans-serif\")\n                        .style(\"font-weight\", \"600\")\n                        .style(\"fill\", s.color || `hsl(${s.hue}, 80%, 20%)`)\n                        .style(\"pointer-events\", \"none\")\n                        .style(\"text-shadow\", \"0 0 2px #fff, 0 0 2px #fff\")\n                        .text(value.toLocaleString());\n                }\n\n                cumulativeValue += value;\n            }\n        }\n    }\n\n    private attachSegmentTooltip(selection: any, series: any, value: number, category: any): void {\n        const total = this.calculateStackTotal(category);\n        const percentage = total > 0 ? ((value / total) * 100).toFixed(1) : \"0\";\n\n        const dot = series.color || `hsl(${series.hue},60%,50%)`;\n        const emph = series.color || `hsl(${series.hue},60%,40%)`;\n        const buildTooltipHtml = () => {\n            return `<div style=\"background: rgba(255,255,255,0.97); border: 1px solid #ddd; padding: 6px 10px; border-radius: 6px; box-shadow: 0 2px 8px rgba(0,0,0,0.15); font-size: 12px; font-family: sans-serif; max-width: 180px;\">\n                <div style=\"font-weight: 700; font-size: 13px; color: #333; margin-bottom: 4px;\">${category}</div>\n                <div style=\"display: flex; align-items: center; gap: 6px; margin: 2px 0;\">\n                    <span style=\"width: 8px; height: 8px; border-radius: 50%; background: ${dot}; flex-shrink: 0;\"></span>\n                    <span style=\"color: #444; flex: 1;\">${series.label || series.id}</span>\n                    <span style=\"font-weight: 600; color: ${emph};\">${value.toLocaleString()}</span>\n                </div>\n                <div style=\"color: #888; font-size: 11px; margin-top: 2px;\">${percentage}% of year</div>\n                <div style=\"border-top: 1px solid #eee; margin-top: 4px; padding-top: 4px; display: flex; justify-content: space-between; font-weight: 600; color: #333;\">\n                    <span>Year Total</span><span>${total.toLocaleString()}</span>\n                </div>\n            </div>`;\n        };\n\n        selection\n            .on(\"mouseenter\", (event: MouseEvent) => {\n                this.ensureTooltip();\n                const mouse = d3.pointer(event, this.myD3.svg.node());\n                this.tooltip!.show(buildTooltipHtml(), mouse[0], mouse[1]);\n            })\n            .on(\"mousemove\", (event: MouseEvent) => {\n                const mouse = d3.pointer(event, this.myD3.svg.node());\n                this.tooltip!.show(buildTooltipHtml(), mouse[0], mouse[1]);\n            })\n            .on(\"mouseleave\", () => this.hideTooltip());\n    }\n\n    private calculateStackTotal(category: any): number {\n        const stacks = this.trace.settings?.stacks;\n        if (!stacks) return 0;\n\n        const catStr = String(category);\n        let total = 0;\n        for (const s of stacks.series) {\n            const value = s.values?.get?.(catStr) ?? s.values?.[catStr] ?? 0;\n            total += value;\n        }\n        return total;\n    }\n}\n\nexport { ChartRenderable, PieRenderable, BarsRenderable, StackedBarsRenderable };\n\n\n","import * as d3 from \"d3\";\nimport type { Plot } from \"../core/PlotModel\";\nimport { ChartRenderable } from \"./ChartRenderables\";\n\n/**\n * HeatmapRenderable — a categorical grid of value-shaded cells (site x year).\n *\n * Data lives in trace.settings.grid:\n *   xLabels: string[]            // columns\n *   yLabels: string[]            // rows; yLabels[0] renders at the TOP (categorical Y's band\n *                                 // scale runs top-down, so lists read in data order)\n *   values: (number|null)[][]    // values[row][col]; null/0 = empty cell\n *\n * Cells use the same YlOrRd sqrt ramp as the dashboard heatmap (SpeciesYearHeatmap).\n */\nclass HeatmapRenderable extends ChartRenderable {\n    private getGrid(): any {\n        return this.trace.settings?.grid;\n    }\n\n    configureAxes(plot: Plot): void {\n        const grid = this.getGrid();\n        if (!grid?.xLabels?.length || !grid?.yLabels?.length) return;\n        plot.axisXType = \"categorical\";\n        plot.categoricalXLabels = grid.xLabels.map(String);\n        plot.axisYType = \"categorical\";\n        plot.categoricalYLabels = grid.yLabels.map(String);\n    }\n\n    updateBounds(): void {\n        const grid = this.getGrid();\n        if (!grid) return;\n        this.trace.xMin = 0;\n        this.trace.xMax = grid.xLabels?.length || 0;\n        this.trace.yMin = 0;\n        this.trace.yMax = grid.yLabels?.length || 0;\n    }\n\n    render(): void {\n        const grid = this.getGrid();\n        if (!grid?.xLabels?.length || !grid?.yLabels?.length) return;\n\n        // Band scales replicated with the padding the dashboard heatmap uses,\n        // aligned to MyD3's categorical axes so cells sit under the tick labels.\n        const bandX = d3.scaleBand<string>()\n            .domain(grid.xLabels.map((_: any, i: number) => i.toString()))\n            .range(this.myD3.axisX.range())\n            .padding(0.06);\n        const bandY = d3.scaleBand<string>()\n            .domain(grid.yLabels.map((_: any, i: number) => i.toString()))\n            .range(this.myD3.axisY.range())\n            .padding(0.06);\n\n        let maxValue = 0;\n        for (const row of grid.values || []) {\n            for (const v of row || []) if (v && v > maxValue) maxValue = v;\n        }\n        const color = d3.scaleSequential(d3.interpolateYlOrRd).domain([0, Math.sqrt(maxValue || 1)]);\n\n        const g = this.myD3.svg.append(\"g\").attr(\"class\", \"heatmap\");\n        // Round corners only as far as the smaller cell dimension allows (thin cells turn\n        // into pills otherwise).\n        const rx = Math.min(2, bandX.bandwidth() * 0.3, bandY.bandwidth() * 0.3);\n        for (let r = 0; r < grid.yLabels.length; r += 1) {\n            for (let c = 0; c < grid.xLabels.length; c += 1) {\n                const value = grid.values?.[r]?.[c] ?? null;\n                const rect = g.append(\"rect\")\n                    .attr(\"x\", bandX(c.toString()) ?? 0)\n                    .attr(\"y\", bandY(r.toString()) ?? 0)\n                    .attr(\"width\", bandX.bandwidth())\n                    .attr(\"height\", bandY.bandwidth())\n                    .attr(\"rx\", rx)\n                    .attr(\"fill\", value ? color(Math.sqrt(value)) : \"#f1f5f9\");\n                this.attachCellTooltip(rect, grid.yLabels[r], grid.xLabels[c], value);\n            }\n        }\n    }\n\n    private attachCellTooltip(selection: any, rowLabel: string, colLabel: string, value: number | null): void {\n        // Optional unit after the value (e.g. \"1,234 Visits\")\n        const unit = this.trace.settings?.valueLabel ? ` ${this.trace.settings.valueLabel}` : \"\";\n        const html = `<div style=\"background: rgba(255,255,255,0.97); border: 1px solid #ddd; padding: 6px 10px; border-radius: 6px; box-shadow: 0 2px 8px rgba(0,0,0,0.15); font-size: 12px; font-family: sans-serif; max-width: 220px;\">\n            <div style=\"font-weight: 700; color: #333;\">${rowLabel}</div>\n            <div style=\"display: flex; justify-content: space-between; gap: 12px; color: #444;\">\n                <span>${colLabel}</span>\n                <span style=\"font-weight: 600; color: #1e293b;\">${value ? value.toLocaleString() + unit : \"–\"}</span>\n            </div>\n        </div>`;\n        selection\n            .on(\"mouseenter\", (event: MouseEvent) => {\n                this.ensureTooltip();\n                const mouse = d3.pointer(event, this.myD3.svg.node());\n                this.tooltip!.show(html, mouse[0], mouse[1]);\n            })\n            .on(\"mousemove\", (event: MouseEvent) => {\n                const mouse = d3.pointer(event, this.myD3.svg.node());\n                this.tooltip!.show(html, mouse[0], mouse[1]);\n            })\n            .on(\"mouseleave\", () => this.hideTooltip());\n    }\n}\n\nexport { HeatmapRenderable };\n","import * as d3 from \"d3\";\nimport { ChartRenderable } from \"./ChartRenderables\";\n\n/**\n * RadialBarsRenderable — bars arranged in a ring (e.g. the dashboard's seasonality\n * clock: one bar per month, bar length = value).\n *\n * Items are tabular rows with `label`, `value` and either an explicit `color`\n * or a `hue` (same color rules as pie/bars). Settings (`trace.settings`):\n *   innerRadiusRatio: number   // hole size as fraction of outer radius (default 0.35)\n *   showLabels: boolean        // ring of category labels (default true)\n *   centerText: { value, label? }  // text inside the hole\n *   valueLabel: string         // unit appended to the tooltip value\n *\n * Best drawn with customOptions.hideAxes = { x: true, y: true } — the ring\n * defines its own coordinate system.\n */\nclass RadialBarsRenderable extends ChartRenderable {\n    render(): void {\n        const data = this.prepareData();\n        if (!data.length) return;\n        const total = this.calculateTotal(data);\n        const settings = this.trace.settings || {};\n\n        const xRange = this.myD3.axisX.range();\n        const yRange = this.myD3.axisY.range();\n        const width = xRange[1] - xRange[0];\n        const height = yRange[0] - yRange[1];\n        const showLabels = settings.showLabels !== false;\n        const labelSpace = showLabels ? 22 : 4;\n        const radius = Math.min(width, height) / 2 - labelSpace;\n        if (radius <= 0) return;\n        const inner = radius * (settings.innerRadiusRatio ?? 0.35);\n\n        const group = this.myD3.svg.append(\"g\")\n            .attr(\"transform\", `translate(${width / 2},${height / 2})`);\n\n        const angle = d3.scaleBand<string>()\n            .domain(data.map((_: any, i: number) => i.toString()))\n            .range([0, 2 * Math.PI])\n            .align(0);\n        const maxValue = d3.max(data, (d: any) => d.value || 0) || 1;\n        const radial = d3.scaleRadial().domain([0, maxValue]).range([inner, radius]);\n\n        const arcGen = d3.arc<any>()\n            .innerRadius(inner)\n            .outerRadius((d: any) => radial(d.value || 0))\n            .startAngle((_d: any, i: number) => angle(i.toString()) || 0)\n            .endAngle((_d: any, i: number) => (angle(i.toString()) || 0) + angle.bandwidth())\n            .padAngle(0.03)\n            .padRadius(inner);\n\n        group.selectAll(\"path.radial-bar\")\n            .data(data)\n            .enter()\n            .append(\"path\")\n            .attr(\"class\", \"radial-bar\")\n            .attr(\"fill\", (d: any) => this.getBarFillColor(d))\n            .attr(\"d\", arcGen as any)\n            .on(\"mouseenter\", (event: MouseEvent, d: any) => {\n                d3.select(event.currentTarget as any).attr(\"opacity\", 0.8);\n                this.showTooltip(event, d, total);\n            })\n            .on(\"mousemove\", (event: MouseEvent, d: any) => this.showTooltip(event, d, total))\n            .on(\"mouseleave\", (event: MouseEvent) => {\n                d3.select(event.currentTarget as any).attr(\"opacity\", 1);\n                this.hideTooltip();\n            });\n\n        if (showLabels) {\n            group.selectAll(\"text.radial-label\")\n                .data(data)\n                .enter()\n                .append(\"text\")\n                .attr(\"class\", \"radial-label\")\n                .attr(\"text-anchor\", \"middle\")\n                .attr(\"dominant-baseline\", \"middle\")\n                .attr(\"transform\", (_d: any, i: number) => {\n                    const a = (angle(i.toString()) || 0) + angle.bandwidth() / 2 - Math.PI / 2;\n                    const r = radius + 14;\n                    return `translate(${Math.cos(a) * r},${Math.sin(a) * r})`;\n                })\n                .style(\"font-size\", \"10px\")\n                .style(\"font-family\", \"sans-serif\")\n                .style(\"fill\", \"#64748b\")\n                .text((d: any) => d.label || \"\");\n        }\n\n        const centerText = settings.centerText;\n        if (centerText && inner > 0) {\n            const valueSize = Math.max(12, Math.min(22, inner * 0.5));\n            group.append(\"text\")\n                .attr(\"text-anchor\", \"middle\")\n                .attr(\"dy\", centerText.label ? \"-0.1em\" : \"0.35em\")\n                .style(\"font-size\", `${valueSize}px`)\n                .style(\"font-weight\", \"700\")\n                .style(\"fill\", \"#1e293b\")\n                .style(\"font-variant-numeric\", \"tabular-nums\")\n                .style(\"pointer-events\", \"none\")\n                .text(centerText.value);\n            if (centerText.label) {\n                group.append(\"text\")\n                    .attr(\"text-anchor\", \"middle\")\n                    .attr(\"dy\", \"1.6em\")\n                    .style(\"font-size\", `${Math.max(8, valueSize * 0.45)}px`)\n                    .style(\"letter-spacing\", \"0.05em\")\n                    .style(\"text-transform\", \"uppercase\")\n                    .style(\"fill\", \"#94a3b8\")\n                    .style(\"pointer-events\", \"none\")\n                    .text(centerText.label);\n            }\n            if (centerText.sub) {\n                // sub may be a single string or several stacked lines (used when the\n                // caption is too wide to fit the hole on one line, e.g. in German).\n                const subLines = Array.isArray(centerText.sub) ? centerText.sub : [centerText.sub];\n                const baseDy = centerText.label ? 2.8 : 1.6;\n                subLines.forEach((line: string, i: number) => {\n                    group.append(\"text\")\n                        .attr(\"text-anchor\", \"middle\")\n                        .attr(\"dy\", `${baseDy + i * 1.15}em`)\n                        .style(\"font-size\", `${Math.max(8, valueSize * 0.34)}px`)\n                        .style(\"letter-spacing\", \"0.05em\")\n                        .style(\"text-transform\", \"uppercase\")\n                        .style(\"fill\", \"#94a3b8\")\n                        .style(\"pointer-events\", \"none\")\n                        .text(line);\n                });\n            }\n        }\n    }\n}\n\nexport { RadialBarsRenderable };\n","import type { MyD3 } from \"../MyD3\";\nimport { Trace, TraceData } from \"../core/PlotModel\";\nimport {\n    AreaRenderable,\n    BarsRenderable,\n    ErrorBarsRenderable,\n    FillAreaRenderable,\n    FocusMarkerRenderable,\n    HeatmapRenderable,\n    LineRenderable,\n    MarkersRenderable,\n    PieRenderable,\n    RadialBarsRenderable,\n    RectangleRenderable,\n    ScatterLinesRenderable,\n    StackedBarsRenderable,\n    TraceRenderable\n} from \"../renderables\";\n\nabstract class TraceHandler {\n    protected readItemsTabular(jsonTrace: any): TraceData[] {\n        const table = jsonTrace.items;\n        const header = table?.h || [];\n        const rows = table?.r || [];\n        const items: TraceData[] = [];\n\n        for (const row of rows) {\n            const values: Record<string, any> = {};\n            for (let idx = 0; idx < header.length; idx += 1) {\n                const key = header[idx];\n                values[key] = row[idx];\n            }\n            items.push(new TraceData(values));\n        }\n\n        return items;\n    }\n\n    read(jsonTrace: Record<string, any>): Trace {\n        return this.doRead(jsonTrace);\n    }\n\n    abstract canHandle(jsonTrace: any): boolean;\n    abstract doRead(jsonTrace: any): Trace;\n    abstract yieldRenderables(trace: Trace, myD3: MyD3): TraceRenderable[];\n}\n\nclass TrendHandler extends TraceHandler {\n    canHandle(jsonTrace: any): boolean {\n        return jsonTrace.settings?.type === \"trend\";\n    }\n\n    doRead(jsonTrace: any): Trace {\n        const items = this.readItemsTabular(jsonTrace);\n        const trace = new Trace(jsonTrace, this);\n        trace.items = items;\n        trace.xMin = Math.min(...trace.items.map(item => item.data[trace.keyX]));\n        trace.xMax = Math.max(...trace.items.map(item => item.data[trace.keyX]));\n        // Data extent only — the 0/2 trend-index frame is applied per plot in\n        // MyD3.resolveYBounds (customOptions.yIncludeValues), not per trace.\n        trace.yMin = Math.min(...trace.items.map(item => item.data[trace.keyY]));\n        trace.yMax = Math.max(...trace.items.map(item => item.data[trace.keyY]));\n        return trace;\n    }\n\n    yieldRenderables(trace: Trace, myD3: MyD3): TraceRenderable[] {\n        const renderables: TraceRenderable[] = [];\n        const settings = trace.settings;\n\n        if (settings.hideGraph !== true) {\n            if (myD3.visuals.showErrorArea) {\n                renderables.push(new AreaRenderable(myD3, trace, 10));\n            }\n            if (settings.fillArea === true) {\n                renderables.push(new FillAreaRenderable(myD3, trace, 15));\n            }\n            if (myD3.visuals.showLine) {\n                renderables.push(new LineRenderable(myD3, trace, 20));\n            }\n        }\n\n        if (settings?.hideFocus !== true) {\n            renderables.push(new FocusMarkerRenderable(myD3, trace, 30));\n            if (myD3.visuals.showMarkers) {\n                renderables.push(new MarkersRenderable(myD3, trace, 21));\n            }\n            if (myD3.visuals.showErrorBars) {\n                renderables.push(new ErrorBarsRenderable(myD3, trace, 19));\n            }\n            if (settings.keyRteLow && settings.keyRteHigh) {\n                const hasValues = trace.items.length > 0 &&\n                    trace.items[0].data[settings.keyRteLow] !== undefined &&\n                    trace.items[0].data[settings.keyRteHigh] !== undefined;\n\n                if (hasValues) {\n                    const renderable = new ErrorBarsRenderable(myD3, trace, 19);\n                    renderable.mode = \"lines\";\n                    renderable.keyValue = \"rteVal\";\n                    renderable.keyLow = \"rteLow\";\n                    renderable.keyHigh = \"rteHigh\";\n                    renderables.push(renderable);\n                }\n            }\n        }\n\n        return renderables;\n    }\n}\n\nclass RectangleHandler extends TraceHandler {\n    canHandle(jsonTrace: any): boolean {\n        return jsonTrace.settings?.type === \"rect\";\n    }\n\n    doRead(jsonTrace: any): Trace {\n        const trace = new Trace(jsonTrace, this);\n        for (const item of jsonTrace.items || []) {\n            trace.items.push(new TraceData(item));\n        }\n        return trace;\n    }\n\n    yieldRenderables(trace: Trace, myD3: MyD3): TraceRenderable[] {\n        return [new RectangleRenderable(myD3, trace, 0)];\n    }\n}\n\nclass PieHandler extends TraceHandler {\n    canHandle(jsonTrace: any): boolean {\n        return jsonTrace.settings?.type === \"pie\";\n    }\n\n    doRead(jsonTrace: any): Trace {\n        const items = this.readItemsTabular(jsonTrace);\n        const trace = new Trace(jsonTrace, this);\n        trace.items = items;\n        return trace;\n    }\n\n    yieldRenderables(trace: Trace, myD3: MyD3): TraceRenderable[] {\n        return [new PieRenderable(myD3, trace, 0)];\n    }\n}\n\nclass BarsHandler extends TraceHandler {\n    canHandle(jsonTrace: any): boolean {\n        return jsonTrace.settings?.type === \"bars\";\n    }\n\n    doRead(jsonTrace: any): Trace {\n        const items = this.readItemsTabular(jsonTrace);\n        const trace = new Trace(jsonTrace, this);\n        trace.items = items;\n        return trace;\n    }\n\n    yieldRenderables(trace: Trace, myD3: MyD3): TraceRenderable[] {\n        return [new BarsRenderable(myD3, trace, 0)];\n    }\n}\n\nclass StackedBarsHandler extends TraceHandler {\n    canHandle(jsonTrace: any): boolean {\n        return jsonTrace.settings?.type === \"stackedBars\";\n    }\n\n    doRead(jsonTrace: any): Trace {\n        const trace = new Trace(jsonTrace, this);\n        // Stacked bars don't use traditional items - data is in settings.stacks\n        return trace;\n    }\n\n    yieldRenderables(trace: Trace, myD3: MyD3): TraceRenderable[] {\n        return [new StackedBarsRenderable(myD3, trace, 0)];\n    }\n}\n\nclass ScatterLinesHandler extends TraceHandler {\n    canHandle(jsonTrace: any): boolean {\n        return jsonTrace.settings?.type === \"scatterLines\";\n    }\n\n    doRead(jsonTrace: any): Trace {\n        const trace = new Trace(jsonTrace, this);\n        trace.items = this.readItemsTabular(jsonTrace);\n        // bounds are derived from the items by ScatterLinesRenderable.updateBounds()\n        return trace;\n    }\n\n    yieldRenderables(trace: Trace, myD3: MyD3): TraceRenderable[] {\n        return [new ScatterLinesRenderable(myD3, trace, 20)];\n    }\n}\n\nclass RadialBarsHandler extends TraceHandler {\n    canHandle(jsonTrace: any): boolean {\n        return jsonTrace.settings?.type === \"radialBars\";\n    }\n\n    doRead(jsonTrace: any): Trace {\n        const trace = new Trace(jsonTrace, this);\n        trace.items = this.readItemsTabular(jsonTrace);\n        return trace;\n    }\n\n    yieldRenderables(trace: Trace, myD3: MyD3): TraceRenderable[] {\n        return [new RadialBarsRenderable(myD3, trace, 0)];\n    }\n}\n\nclass HeatmapHandler extends TraceHandler {\n    canHandle(jsonTrace: any): boolean {\n        return jsonTrace.settings?.type === \"heatmap\";\n    }\n\n    doRead(jsonTrace: any): Trace {\n        // Heatmaps don't use traditional items — the grid lives in settings.grid\n        return new Trace(jsonTrace, this);\n    }\n\n    yieldRenderables(trace: Trace, myD3: MyD3): TraceRenderable[] {\n        return [new HeatmapRenderable(myD3, trace, 0)];\n    }\n}\n\nconst defaultHandlers: TraceHandler[] = [\n    new RectangleHandler(),\n    new TrendHandler(),\n    new PieHandler(),\n    new BarsHandler(),\n    new StackedBarsHandler(),\n    new ScatterLinesHandler(),\n    new RadialBarsHandler(),\n    new HeatmapHandler()\n];\n\nfunction getTraceHandlers(): TraceHandler[] {\n    return defaultHandlers;\n}\n\nexport {\n    TraceHandler,\n    TrendHandler,\n    RectangleHandler,\n    PieHandler,\n    BarsHandler,\n    StackedBarsHandler,\n    ScatterLinesHandler,\n    RadialBarsHandler,\n    HeatmapHandler,\n    getTraceHandlers\n};\n\n\n","import * as d3 from \"d3\";\nimport { ElementBuilder } from \"../dom/ElementBuilder\";\nimport type { MyD3ZoomOptions } from \"../types\";\n\ninterface ViewWindow {\n    xMin: number;\n    xMax: number;\n}\n\ninterface ZoomAttachContext {\n    /** d3 selection of the root <svg>. */\n    svgRoot: any;\n    /** DOM node of the margin-translated <g> — the plot-area coordinate origin. */\n    gNode: SVGGElement;\n    /** d3 selection of a topmost overlay <g> (pointer-events: none) for the selection band. */\n    overlay: any;\n    /** Plot area size in px. */\n    width: number;\n    height: number;\n    /** The linear x scale of the current draw (must have .invert). */\n    xScale: any;\n}\n\n/** Smallest allowed view span, as a fraction of the full extent. */\nconst MIN_SPAN_DIVISOR = 50;\n/** Drags shorter than this many px count as clicks and are ignored. */\nconst MIN_DRAG_PX = 5;\n/** Wheel zoom factor per scroll notch (deltaY of 100). */\nconst WHEEL_FACTOR = 1.25;\n\n//  Bootstrap Icons (search / arrows-move / arrow-counterclockwise), inlined so the\n//  library does not depend on the Django-served sprite.\nconst ICONS: Record<string, string> = {\n    zoom: '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\"><path d=\"M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0\"/></svg>',\n    pan: '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\"><path fill-rule=\"evenodd\" d=\"M7.646.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 1.707V5.5a.5.5 0 0 1-1 0V1.707L6.354 2.854a.5.5 0 1 1-.708-.708zM8 10a.5.5 0 0 1 .5.5v3.793l1.146-1.147a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 0 1 .708-.708L7.5 14.293V10.5A.5.5 0 0 1 8 10M.146 8.354a.5.5 0 0 1 0-.708l2-2a.5.5 0 1 1 .708.708L1.707 7.5H5.5a.5.5 0 0 1 0 1H1.707l1.147 1.146a.5.5 0 0 1-.708.708zM10 8a.5.5 0 0 1 .5-.5h3.793l-1.147-1.146a.5.5 0 0 1 .708-.708l2 2a.5.5 0 0 1 0 .708l-2 2a.5.5 0 0 1-.708-.708L14.293 8.5H10.5A.5.5 0 0 1 10 8\"/></svg>',\n    reset: '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\"><path fill-rule=\"evenodd\" d=\"M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2z\"/><path d=\"M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466\"/></svg>'\n};\n\n//  English fallbacks for MyD3 consumers constructed without a translate fn.\nconst LABEL_FALLBACKS: Record<string, string> = {\n    \"trends.zoom.zoomMode\": \"Zoom mode: drag to select a time range\",\n    \"trends.zoom.panMode\": \"Pan mode: drag to move the visible range\",\n    \"trends.zoom.reset\": \"Reset zoom\"\n};\n\n/**\n * Owns the zoom/pan state of one MyD3 chart: the current view window, the\n * interaction mode, all event wiring and the toolbar controls. The controller\n * survives redraws (MyD3 keeps it like the toolbar container); `attach` is\n * re-called after every draw with the fresh SVG.\n */\nclass ZoomController {\n    mode: \"zoom\" | \"pan\";\n    view: ViewWindow | null = null;\n\n    private readonly full: ViewWindow;\n    private readonly opts: MyD3ZoomOptions;\n    private readonly requestRedraw: () => void;\n    private readonly translate?: (key: string, params?: any) => string;\n\n    private ctx?: ZoomAttachContext;\n    private rafPending = false;\n    private panDragActive = false;\n    private controlsBuilt = false;\n    private zoomBtn?: HTMLButtonElement;\n    private panBtn?: HTMLButtonElement;\n    private resetBtn?: HTMLButtonElement;\n\n    constructor(\n        fullExtent: ViewWindow,\n        opts: MyD3ZoomOptions,\n        requestRedraw: () => void,\n        translate?: (key: string, params?: any) => string\n    ) {\n        this.full = { ...fullExtent };\n        this.opts = opts;\n        this.requestRedraw = requestRedraw;\n        this.translate = translate;\n        //  pan is the default: dragging moves the visible range, which is what users\n        //  expect from a chart; zoom-by-selection is opt-in via the toolbar\n        this.mode = this.panEnabled() ? \"pan\" : \"zoom\";\n    }\n\n    /** Merge precedence: component customOptions > backend plot settings > defaults (all on). */\n    static resolveOptions(backend?: MyD3ZoomOptions, custom?: MyD3ZoomOptions): MyD3ZoomOptions {\n        return { enabled: true, wheel: true, drag: true, pan: true, ...(backend || {}), ...(custom || {}) };\n    }\n\n    //  ---- window math ----\n\n    static clampWindow(win: ViewWindow, full: ViewWindow, minSpan: number): ViewWindow {\n        const fullSpan = full.xMax - full.xMin;\n        let span = Math.max(minSpan, win.xMax - win.xMin);\n        span = Math.min(span, fullSpan);\n        //  if the span was grown to minSpan, keep the window centered where it was\n        let xMin = win.xMin;\n        if (win.xMax - win.xMin < span) {\n            xMin = (win.xMin + win.xMax) / 2 - span / 2;\n        }\n        xMin = Math.max(full.xMin, Math.min(xMin, full.xMax - span));\n        return { xMin, xMax: xMin + span };\n    }\n\n    private minSpan(): number {\n        return (this.full.xMax - this.full.xMin) / MIN_SPAN_DIVISOR;\n    }\n\n    /** Zoom by `factor` keeping the domain value `cx` fixed. factor > 1 zooms in. */\n    zoomAt(cx: number, factor: number) {\n        const cur = this.view ?? this.full;\n        const span = (cur.xMax - cur.xMin) / factor;\n        if (span >= this.full.xMax - this.full.xMin) {\n            //  zoomed all the way out: snap back to the full extent\n            this.setView(null);\n            return;\n        }\n        const rel = (cx - cur.xMin) / (cur.xMax - cur.xMin);\n        const xMin = cx - rel * span;\n        this.setView(ZoomController.clampWindow({ xMin, xMax: xMin + span }, this.full, this.minSpan()));\n    }\n\n    /** Zoom into the [x0, x1] domain range (any order). */\n    zoomTo(x0: number, x1: number) {\n        //  a degenerate full extent (xMin === xMax, e.g. a single-x-value chart) has\n        //  no meaningful span to clamp into — clampWindow would divide a zero minSpan\n        //  and produce a zero-width, stuck view.\n        if (this.full.xMax <= this.full.xMin) return;\n        this.setView(ZoomController.clampWindow(\n            { xMin: Math.min(x0, x1), xMax: Math.max(x0, x1) }, this.full, this.minSpan()));\n    }\n\n    /** Shift `startView` by a domain-space delta, clamped to the full extent. */\n    panTo(startView: ViewWindow, domainDx: number) {\n        if (this.full.xMax <= this.full.xMin) return;\n        const span = startView.xMax - startView.xMin;\n        const xMin = Math.max(this.full.xMin, Math.min(startView.xMin + domainDx, this.full.xMax - span));\n        this.setView({ xMin, xMax: xMin + span });\n    }\n\n    reset() {\n        this.setView(null);\n    }\n\n    private setView(view: ViewWindow | null) {\n        this.view = view;\n        this.updateControls();\n        //  panning becomes available (or stops being) with the first/last zoom step\n        this.applyCursor(this.panDragActive);\n        this.scheduleRedraw();\n    }\n\n    private scheduleRedraw() {\n        if (this.rafPending) return;\n        this.rafPending = true;\n        requestAnimationFrame(() => {\n            this.rafPending = false;\n            this.requestRedraw();\n        });\n    }\n\n    //  ---- event wiring (re-called on every draw with the fresh SVG) ----\n\n    attach(ctx: ZoomAttachContext) {\n        this.ctx = ctx;\n        const svgNode = ctx.svgRoot.node() as SVGSVGElement;\n        if (this.opts.wheel !== false) {\n            svgNode.addEventListener(\"wheel\", (e: WheelEvent) => this.onWheel(e), { passive: false });\n        }\n        if (this.dragEnabled() || this.panEnabled()) {\n            svgNode.addEventListener(\"mousedown\", (e: MouseEvent) => this.onMouseDown(e));\n        }\n        svgNode.addEventListener(\"dblclick\", () => this.reset());\n        //  a redraw can land mid-pan-drag; keep the drag visuals consistent on the fresh SVG\n        if (this.panDragActive) ctx.svgRoot.style(\"pointer-events\", \"none\");\n        this.applyCursor(this.panDragActive);\n    }\n\n    private dragEnabled(): boolean {\n        return this.opts.drag !== false;\n    }\n\n    private panEnabled(): boolean {\n        return this.opts.pan !== false;\n    }\n\n    /**\n     * Panning needs something to pan into view — at the full extent there is\n     * nothing off-screen, so dragging falls back to zoom-by-selection.\n     */\n    private canPan(): boolean {\n        return this.panEnabled() && this.view !== null;\n    }\n\n    /** The effective mode: forced when only one drag interaction is possible. */\n    activeMode(): \"zoom\" | \"pan\" {\n        if (!this.canPan()) return \"zoom\";\n        if (!this.dragEnabled()) return \"pan\";\n        return this.mode;\n    }\n\n    private applyCursor(dragging: boolean) {\n        if (!this.ctx) return;\n        const mode = this.activeMode();\n        let cursor = \"default\";\n        if (mode === \"pan\") {\n            cursor = dragging ? \"grabbing\" : \"grab\";\n        }\n        else if (this.dragEnabled()) {\n            cursor = \"crosshair\";\n        }\n        this.ctx.svgRoot.style(\"cursor\", cursor);\n    }\n\n    /** Pointer x in plot-area px (handles the viewBox scaling via getScreenCTM). */\n    private pointerX(e: MouseEvent): number {\n        return d3.pointer(e, this.ctx!.gNode)[0];\n    }\n\n    private onWheel(e: WheelEvent) {\n        if (!this.ctx) return;\n        e.preventDefault();\n        const px = Math.max(0, Math.min(this.ctx.width, this.pointerX(e)));\n        const factor = Math.pow(WHEEL_FACTOR, -e.deltaY / 100);\n        this.zoomAt(this.ctx.xScale.invert(px), factor);\n    }\n\n    private onMouseDown(e: MouseEvent) {\n        if (e.button !== 0 || !this.ctx) return;\n        if (this.activeMode() === \"zoom\" && this.dragEnabled()) {\n            this.startSelection(e);\n        } else if (this.activeMode() === \"pan\") {\n            this.startPan(e);\n        }\n    }\n\n    private startSelection(e: MouseEvent) {\n        const ctx = this.ctx!;\n        e.preventDefault();\n        const startPx = Math.max(0, Math.min(ctx.width, this.pointerX(e)));\n        let lastPx = startPx;\n        const band = ctx.overlay.append(\"rect\")\n            .attr(\"y\", 0)\n            .attr(\"height\", ctx.height)\n            .attr(\"x\", startPx)\n            .attr(\"width\", 0)\n            .attr(\"fill\", \"rgba(100,116,139,0.15)\")\n            .attr(\"stroke\", \"#64748b\")\n            .attr(\"stroke-dasharray\", \"4,3\");\n        //  freeze the crosshair/tooltip underneath while selecting\n        ctx.svgRoot.style(\"pointer-events\", \"none\");\n        const onMove = (ev: MouseEvent) => {\n            lastPx = Math.max(0, Math.min(ctx.width, this.pointerX(ev)));\n            band.attr(\"x\", Math.min(startPx, lastPx)).attr(\"width\", Math.abs(lastPx - startPx));\n        };\n        const onUp = () => {\n            window.removeEventListener(\"mousemove\", onMove);\n            window.removeEventListener(\"mouseup\", onUp);\n            ctx.svgRoot.style(\"pointer-events\", null);\n            band.remove();\n            if (Math.abs(lastPx - startPx) >= MIN_DRAG_PX) {\n                this.zoomTo(ctx.xScale.invert(startPx), ctx.xScale.invert(lastPx));\n            }\n        };\n        window.addEventListener(\"mousemove\", onMove);\n        window.addEventListener(\"mouseup\", onUp);\n    }\n\n    private startPan(e: MouseEvent) {\n        const ctx = this.ctx!;\n        e.preventDefault();\n        const startPx = this.pointerX(e);\n        //  anchor in domain space: the value under the cursor at drag start. Each\n        //  mousemove re-derives the window so this same domain value tracks the\n        //  cursor, instead of a fixed span-per-px measured against the draw-time\n        //  gNode — margin.left is recomputed every redraw from y tick-label widths,\n        //  which shift while panning a count chart (y auto-fit), so a fixed px→domain\n        //  factor drifts. This is self-correcting: it reads the CURRENT view window\n        //  and CURRENT ctx.width on every move.\n        const anchorDomain = ctx.xScale.invert(startPx);\n        this.panDragActive = true;\n        ctx.svgRoot.style(\"pointer-events\", \"none\");\n        this.applyCursor(true);\n        const onMove = (ev: MouseEvent) => {\n            if (!this.ctx) return;\n            const px = this.pointerX(ev);\n            const cur = this.view ?? this.full;\n            const domainUnderCursorNow = cur.xMin + (px / this.ctx.width) * (cur.xMax - cur.xMin);\n            //  shift the current window (constant span, clamped) so anchorDomain\n            //  lands back under the cursor\n            this.panTo(cur, anchorDomain - domainUnderCursorNow);\n        };\n        const onUp = () => {\n            window.removeEventListener(\"mousemove\", onMove);\n            window.removeEventListener(\"mouseup\", onUp);\n            this.panDragActive = false;\n            //  this.ctx (not the captured ctx): redraws during the pan replaced the SVG\n            if (this.ctx) {\n                this.ctx.svgRoot.style(\"pointer-events\", null);\n            }\n            this.applyCursor(false);\n        };\n        window.addEventListener(\"mousemove\", onMove);\n        window.addEventListener(\"mouseup\", onUp);\n    }\n\n    //  ---- toolbar controls ----\n\n    private t(key: string): string {\n        const fallback = LABEL_FALLBACKS[key] || key;\n        if (!this.translate) return fallback;\n        const s = this.translate(key);\n        //  vue-i18n returns the key itself for missing translations\n        return s && s !== key ? s : fallback;\n    }\n\n    /** Build the button group once (into the MyD3 toolbar container), then keep it updated. */\n    ensureControls(toolbar: HTMLElement) {\n        if (this.controlsBuilt) {\n            this.updateControls();\n            return;\n        }\n        this.controlsBuilt = true;\n        const group = ElementBuilder.create(\"div\", { class: \"btn-group me-1\" }).el();\n        const mkButton = (icon: string, labelKey: string, onClick: () => void): HTMLButtonElement => {\n            const btn = ElementBuilder.append(group, \"button\", {\n                type: \"button\",\n                class: \"btn btn-sm btn-outline-secondary\",\n                title: this.t(labelKey)\n            }).el() as HTMLButtonElement;\n            btn.innerHTML = icon;\n            btn.onclick = onClick;\n            return btn;\n        };\n        if (this.dragEnabled() && this.panEnabled()) {\n            this.panBtn = mkButton(ICONS.pan, \"trends.zoom.panMode\", () => {\n                this.mode = \"pan\";\n                this.updateControls();\n                this.applyCursor(false);\n            });\n            this.zoomBtn = mkButton(ICONS.zoom, \"trends.zoom.zoomMode\", () => {\n                this.mode = \"zoom\";\n                this.updateControls();\n                this.applyCursor(false);\n            });\n        }\n        this.resetBtn = mkButton(ICONS.reset, \"trends.zoom.reset\", () => this.reset());\n        toolbar.insertBefore(group, toolbar.firstChild);\n        this.updateControls();\n    }\n\n    private updateControls() {\n        const setActive = (btn: HTMLButtonElement | undefined, active: boolean) => {\n            if (!btn) return;\n            btn.className = active ? \"btn btn-sm btn-secondary\" : \"btn btn-sm btn-outline-secondary\";\n        };\n        const mode = this.activeMode();\n        setActive(this.zoomBtn, mode === \"zoom\");\n        setActive(this.panBtn, mode === \"pan\");\n        //  nothing to pan while the whole extent is visible\n        if (this.panBtn) this.panBtn.disabled = !this.canPan();\n        if (this.resetBtn) this.resetBtn.style.display = this.view ? \"\" : \"none\";\n    }\n}\n\nexport { ZoomController };\nexport type { ViewWindow, ZoomAttachContext };\n","import * as d3 from \"d3\";\nimport { ElementBuilder } from \"./dom/ElementBuilder\";\nimport { Tooltip } from \"./tooltip/Tooltip\";\nimport type { Trace } from \"./core/PlotModel\";\nimport { MyPlotVisuals, Plot } from \"./core/PlotModel\";\nimport type { TraceHandler } from \"./handlers/TraceHandler\";\nimport { getTraceHandlers } from \"./handlers/TraceHandler\";\nimport { ZoomController } from \"./interaction/ZoomController\";\nimport {\n    createSegmentsBySignificance as buildSignificanceSegments,\n    stripShortSignificantSegments as collapseShortSegments\n} from \"./utils/significance\";\nimport type {\n    TooltipContext,\n    TooltipTraceData,\n    MyD3CustomOptions,\n    MyD3ZoomOptions,\n    SignificanceSegment,\n    RenderContext,\n    PlotData\n} from \"./types\";\n\n/**\n * Containers waiting to be redrawn once they have a usable size, keyed by container.\n * At most one entry per element: a later draw into the same container supersedes the\n * earlier one, so a superseded instance can never repaint stale data over fresh.\n */\nconst pendingResizeRedraws = new WeakMap<HTMLElement, ResizeObserver>();\n\nfunction cancelResizeRedraw(elm: HTMLElement | undefined | null) {\n    if (!elm) return;\n    const observer = pendingResizeRedraws.get(elm);\n    if (!observer) return;\n    observer.disconnect();\n    pendingResizeRedraws.delete(elm);\n}\n\nclass MyD3 {\n    private _plotElementId?: string;\n    private _plotElement?: HTMLElement;\n    private readonly handlers: TraceHandler[];\n    customOptions?: MyD3CustomOptions;\n    visuals: MyPlotVisuals = new MyPlotVisuals();\n    data: any;\n    vueTranslation: any;\n    message: any;\n    preparedPlot: Plot;\n    svg: any;\n    axisX: any;\n    axisY: any;\n\n    toolbarContainer: any;\n    /** The download dialog, mounted on <body> while open (null otherwise). */\n    popupContainer: any;\n    popupBackdrop: any;\n    private popupKeyHandler?: (e: KeyboardEvent) => void;\n    private popupWatchTimer?: number;\n    zoomController?: ZoomController;\n    /** Hover crosshair lines: opt-in, the markers alone carry the read-out by default. */\n    crosshairEnabled = false;\n    private crosshairParts: any[] = [];\n    private zoomOptions: MyD3ZoomOptions = {};\n    /** clipPath ids are document-global; sequence them per draw so charts don't collide. */\n    private static clipSeq = 0;\n    /** form-control ids must be unique across every chart on the page. */\n    private static dlSeq = 0;\n    dlWidth = 1024;\n    dlHeight = 768;\n    dlFontSizeMul = 1.0;\n    dlStrokeWidth = 3.0;\n    dlStrokeWidthMul = 1.0;\n    dlTitle = \"\";\n    dlSubtitle = \"\";\n\n    public static getPreparedPlot(data: PlotData, handlers: TraceHandler[] = getTraceHandlers()): Plot {\n        const prepared = new Plot();\n        prepared.prepare(data, handlers);\n        return prepared;\n    }\n\n    public static createSegmentsBySignificance(trace: Trace, myD3?: MyD3): SignificanceSegment[] {\n        return buildSignificanceSegments(trace, myD3);\n    }\n\n    public static stripShortSignificantSegments(segments: SignificanceSegment[], trace: Trace): SignificanceSegment[] {\n        return collapseShortSegments(segments, trace);\n    }\n\n    constructor(\n        plotIdOrElement: string | HTMLElement,\n        data: PlotData,\n        customOptionsOrTranslate?: MyD3CustomOptions | ((key: string, params?: any) => string),\n        vueTranslation?: any,\n        handlers: TraceHandler[] = getTraceHandlers()\n    ) {\n        if (typeof plotIdOrElement === \"string\") {\n            this._plotElementId = plotIdOrElement;\n        } else {\n            this._plotElement = plotIdOrElement;\n        }\n\n        this.handlers = handlers;\n        this.data = data;\n\n        if (typeof customOptionsOrTranslate === \"function\") {\n            this.customOptions = {};\n            this.vueTranslation = customOptionsOrTranslate;\n        } else {\n            this.customOptions = customOptionsOrTranslate;\n            this.vueTranslation = vueTranslation;\n        }\n        this.customOptions = this.customOptions || {};\n\n        this.preparedPlot = MyD3.getPreparedPlot(data, this.handlers);\n        this.preparedPlot.prepareBounds(this);\n\n        //  merge zoom config: component customOptions > backend plot-level settings > defaults\n        this.zoomOptions = ZoomController.resolveOptions((data as any)?.settings?.zoom, this.customOptions?.zoom);\n    }\n\n    private get plotElement(): HTMLElement {\n        if (this._plotElement) return this._plotElement;\n        if (this._plotElementId) return document.getElementById(this._plotElementId) as HTMLElement;\n        throw new Error(\"Plot element not found. Please provide a valid plotId or plotElement.\");\n    }\n\n    /**\n     * Default tooltip builder - creates the standard tooltip HTML\n     * This method encapsulates the default tooltip building logic\n     *\n     * @param context Complete context for building the tooltip\n     * @returns HTML string for the tooltip\n     */\n    private buildDefaultTooltip(context: TooltipContext): string {\n        const fmt = (n: number) => n.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 });\n\n        // The x header (year). Every trace shares the same selX (bestX), so read it\n        // from the first entry — this used to hinge on `isFirst` (idx === 0), which\n        // silently dropped the header whenever the first trace was a hideFocus trend.\n        const header = context.traces.find(t => t.selX !== undefined)?.selX;\n\n        let rows = \"\";\n        for (const traceData of context.traces) {\n            const { trace, selectedData, selY, hasData } = traceData;\n\n            let body: string;\n            if (hasData && selY !== undefined && selectedData) {\n                const ci = (selectedData.data.ciLow !== undefined && selectedData.data.ciHigh !== undefined)\n                    ? ` <span style=\"color:#94a3b8\">(${fmt(selectedData.data.ciLow)} – ${fmt(selectedData.data.ciHigh)})</span>`\n                    : \"\";\n                body = `<span style=\"font-weight:600; color:${trace.colorText}\">${fmt(selY)}</span>${ci}`;\n                if (selectedData.data.nbSites !== undefined && context.customOptions?.ttShowSitesAtBottom === false) {\n                    body += `<span style=\"color:#94a3b8\">, ${context.translate('trends.nbSites', { n: selectedData.data.nbSites })}</span>`;\n                }\n            } else {\n                body = `<span style=\"color:#94a3b8\">N/A</span>`;\n            }\n\n            const label = context.dataType === 'TG'\n                ? `<span style=\"color:${trace.colorText}; font-weight:600\">${trace.title}</span> `\n                : \"\";\n            rows += `<div style=\"margin:1px 0\">${label}${body}</div>`;\n        }\n\n        // Optional slope-significance badge (opt-in via customOptions.ttShowSignificance).\n        // Read from the first trace with data at the hovered year; colours mirror the\n        // significance line palette (increase green / decrease red / flat slate).\n        let sigHtml = \"\";\n        if (context.customOptions?.ttShowSignificance) {\n            const primary = context.traces.find(t => t.hasData && t.selectedData);\n            const sig = primary?.selectedData?.data?.significance;\n            if (sig !== undefined) {\n                const map: Record<number, [string, string]> = {\n                    1: [\"increasing\", \"#16a34a\"],\n                    2: [\"decreasing\", \"#dc2626\"],\n                    0: [\"not significant\", \"#64748b\"],\n                };\n                const [label, color] = map[sig] ?? map[0];\n                sigHtml = `<div style=\"margin-top:4px\"><span style=\"display:inline-block; ` +\n                    `padding:1px 8px; border-radius:999px; background:${color}1a; color:${color}; ` +\n                    `font-weight:600; font-size:11px; letter-spacing:.01em\">${label}</span></div>`;\n            }\n        }\n\n        let footer = \"\";\n        if (context.customOptions?.ttShowSitesAtBottom !== false && context.nbSites >= 0) {\n            footer = `<div style=\"color:#94a3b8; margin-top:2px\">${context.translate('trends.nbSites', { n: context.nbSites })}</div>`;\n        }\n\n        // Numeric x headers (e.g. a fine year grid) can carry long fractions; show at most\n        // one decimal and drop a trailing .0 so integer years still read as \"2015\".\n        const headerLabel = typeof header === \"number\"\n            ? (Number.isInteger(header) ? String(header) : header.toFixed(1))\n            : header;\n        const headerHtml = header !== undefined\n            ? `<div style=\"font-weight:700; color:#1e293b; margin-bottom:3px\">${headerLabel}</div>`\n            : \"\";\n\n        return `<div style=\"border:1px solid #e2e8f0; padding:7px 11px; background:rgba(255,255,255,0.98); ` +\n            `border-radius:8px; box-shadow:0 4px 12px rgba(15,23,42,0.12); text-align:center; ` +\n            `white-space:nowrap; font-family:sans-serif; font-size:12.5px; line-height:1.35;\">` +\n            `${headerHtml}${rows}${sigHtml}${footer}</div>`;\n    }\n\n    /**\n     * Axis tick font size in px. Explicit customOptions.axisFontSize wins; otherwise the\n     * height-proportional base is clamped to a readable range (categorical labels tighter,\n     * since they sit next to dense bands).\n     */\n    private axisTickFontSize(baseFontSize: number, axisType: 'linear' | 'categorical'): number {\n        const explicit = this.customOptions?.axisFontSize;\n        if (explicit) return explicit * this.dlFontSizeMul;\n        const max = axisType === 'categorical' ? 13 : 16;\n        return Math.max(10, Math.min(max, baseFontSize));\n    }\n\n    /**\n     * Layout for categorical X tick labels: rotation angle plus a thinning step so only\n     * every step-th label is rendered when they cannot all fit. Short labels (years, codes)\n     * prefer sparse horizontal ticks over rotation.\n     */\n    private resolveCategoricalXLayout(labels: string[], availableSpace: number, fontSize: number): { rotation: number; step: number } {\n        if (labels.length === 0 || availableSpace <= 0) return { rotation: 0, step: 1 };\n\n        const avgCharWidth = fontSize * 0.6;\n        const maxLabelWidth = Math.max(...labels.map(label => label.length)) * avgCharWidth;\n        const spacePerLabel = availableSpace / labels.length;\n\n        let rotation: number;\n        const explicit = this.customOptions?.labelsRotationAngle;\n        if (explicit !== undefined) {\n            rotation = explicit;\n        } else if (maxLabelWidth <= spacePerLabel * 0.9 || maxLabelWidth <= 6 * avgCharWidth) {\n            rotation = 0;\n        } else if (maxLabelWidth <= spacePerLabel * 1.5) {\n            rotation = -45;\n        } else {\n            rotation = -90;\n        }\n\n        // Horizontal footprint of one rendered label (rotated labels stack almost vertically).\n        const perLabel = rotation === 0 ? maxLabelWidth + avgCharWidth : fontSize * 1.6;\n        const step = Math.max(1, Math.ceil(perLabel / spacePerLabel));\n        return { rotation, step };\n    }\n\n    /**\n     * Apply rotation and proper alignment to axis labels\n     * @param textSelection D3 selection of text elements\n     * @param angle Rotation angle in degrees\n     * @param axis 'x' or 'y' axis\n     * @param fontSize Font size in pixels\n     */\n    private applyLabelRotation(textSelection: any, angle: number, axis: 'x' | 'y', fontSize: number): void {\n        if (angle === 0) {\n            // No rotation - use default alignment\n            if (axis === 'x') {\n                textSelection.style(\"text-anchor\", \"middle\");\n            }\n            return;\n        }\n\n        if (axis === 'x') {\n            // X-axis label rotation\n            textSelection\n                .style(\"text-anchor\", angle < 0 ? \"end\" : \"start\")\n                .attr(\"dx\", angle < 0 ? \"-0.5em\" : \"0.5em\")\n                .attr(\"dy\", \"0.15em\")\n                .attr(\"transform\", `rotate(${angle})`);\n        } else {\n            // Y-axis label rotation\n            textSelection\n                .style(\"text-anchor\", angle === 0 ? \"end\" : \"middle\")\n                .attr(\"dx\", angle === 0 ? \"-0.5em\" : \"0\")\n                .attr(\"dy\", angle === 0 ? \"0.35em\" : \"0.35em\")\n                .attr(\"transform\", `rotate(${angle})`);\n        }\n    }\n\n    private calcTextSize(preparedData: Plot, fontSize: number): { width: number, height: number } {\n        //  hidden rendering to estimate the text size\n        // When the Y labels are hidden they take no space, so don't measure them.\n        if (this.shouldHideYAxisLabels()) {\n            return { width: 0, height: Math.round(fontSize * 1.2) };\n        }\n\n        // Calculate the maximum width needed for y-axis labels by checking both min and max values\n        const yValues = [preparedData.yMin, preparedData.yMax];\n\n        // Also check some intermediate values to ensure we account for labels that might be wider\n        const range = preparedData.yMax - preparedData.yMin;\n        const step = range / 4;\n        for (let i = 1; i < 4; i++) {\n            yValues.push(preparedData.yMin + (step * i));\n        }\n\n        let maxWidth = 0;\n        let maxHeight = 0;\n\n        const hiddenSVG = d3.select(\"body\")\n            .append(\"svg\")\n            .style(\"position\", \"absolute\")\n            .style(\"left\", \"-9999px\")\n            .style(\"top\", \"-9999px\");\n\n        const measure = (str: string, size: number) => {\n            const text = hiddenSVG.append(\"text\").style(\"font-size\", `${size}px`).text(str);\n            const bbox = text.node()?.getBBox() || new DOMRect();\n            maxWidth = Math.max(maxWidth, bbox.width);\n            maxHeight = Math.max(maxHeight, bbox.height);\n            text.remove();\n        };\n\n        if (preparedData.axisYType === 'categorical') {\n            const size = this.axisTickFontSize(fontSize, 'categorical');\n            for (const label of preparedData.categoricalYLabels) measure(label, size);\n        } else {\n            const size = this.axisTickFontSize(fontSize, 'linear');\n            for (const value of yValues) measure(value.toFixed(2), size);\n        }\n\n        hiddenSVG.remove(); // Clean up the temporary SVG\n\n        return { width: Math.round(maxWidth), height: Math.round(maxHeight) };\n    }\n\n    /**\n     * Final linear y-domain for a data extent. The domain is widened to contain\n     * every `yIncludeValues` entry (default [0, 2] — the classic trend-index\n     * frame), then `yPadTopRatio` of the span is added above a data-driven\n     * maximum. Shared by the full-plot bounds (Plot.prepareBounds) and the zoom\n     * window (computeViewYBounds) so both honour the same conventions.\n     */\n    resolveYBounds(dataMin: number, dataMax: number): { yMin: number; yMax: number } {\n        const include = this.customOptions?.yIncludeValues ?? [0.0, 2.0];\n        const yMin = Math.min(dataMin, ...include);\n        let yMax = Math.max(dataMax, ...include);\n        const pad = this.customOptions?.yPadTopRatio ?? 0;\n        if (pad > 0 && yMax === dataMax && yMax > yMin) {\n            yMax += (yMax - yMin) * pad;\n        }\n        return { yMin, yMax };\n    }\n\n    /**\n     * Y bounds of the data visible inside the zoom window (value + CI columns),\n     * with the same domain rules as Plot.prepareBounds so the axis keeps its\n     * conventions. Falls back to the full bounds when the window holds no data.\n     */\n    private computeViewYBounds(view: { xMin: number; xMax: number }): { yMin: number; yMax: number } {\n        let lo = Infinity, hi = -Infinity;\n        for (const trace of this.preparedPlot.traces) {\n            for (const item of trace.items) {\n                const xv = item.data[trace.keyX];\n                if (typeof xv !== \"number\" || xv < view.xMin || xv > view.xMax) continue;\n                for (const yv of [item.data[trace.keyY], item.data.ciLow, item.data.ciHigh]) {\n                    if (typeof yv === \"number\" && isFinite(yv)) {\n                        lo = Math.min(lo, yv);\n                        hi = Math.max(hi, yv);\n                    }\n                }\n            }\n        }\n        if (!isFinite(lo) || !isFinite(hi)) {\n            return { yMin: this.preparedPlot.yMin, yMax: this.preparedPlot.yMax };\n        }\n        return this.resolveYBounds(lo, hi);\n    }\n\n    /**\n     * Calculate additional margin needed for rotated X-axis labels\n     * @param labels Array of categorical labels\n     * @param fontSize Font size in pixels\n     * @param width Available width\n     * @param maxHeight Maximum height available for labels (based on chart height and maxLabelSpaceRatio)\n     * @returns Additional bottom margin needed, clamped to maxHeight\n     */\n    private calcRotatedXLabelMargin(labels: string[], fontSize: number, width: number, maxHeight?: number): number {\n        if (labels.length === 0 || this.shouldHideXAxisLabels()) return 0;\n\n        // Check if labels should be rendered at all\n        const maxLabelSpaceRatio = this.customOptions?.maxLabelSpaceRatio ?? 0.25;\n        if (maxLabelSpaceRatio <= 0.0) return 0;\n\n        const rotationAngle = this.resolveCategoricalXLayout(labels, width, fontSize).rotation;\n        if (rotationAngle === 0) return 0;\n\n        // Estimate the height needed for rotated labels\n        const avgCharWidth = fontSize * 0.6;\n        const maxLabelLength = Math.max(...labels.map(label => label.length));\n        const maxLabelWidth = maxLabelLength * avgCharWidth;\n\n        // Calculate the vertical space needed based on rotation angle\n        const radians = Math.abs(rotationAngle) * Math.PI / 180;\n        const additionalHeight = maxLabelWidth * Math.sin(radians);\n\n        // Clamp to maximum allowed height if specified\n        const clampedHeight = maxHeight ? Math.min(additionalHeight, maxHeight) : additionalHeight;\n\n        return Math.round(clampedHeight);\n    }\n\n    /**\n     * Calculate maximum allowed margin for Y-axis labels\n     * @param totalWidth Total chart width\n     * @returns Maximum width allowed for Y-axis labels\n     */\n    private calcMaxYLabelMargin(totalWidth: number): number {\n        const maxLabelSpaceRatio = this.customOptions?.maxLabelSpaceRatio ?? 0.25; // Reduced from 0.5 to 0.25\n        if (maxLabelSpaceRatio <= 0.0) return 0;\n\n        return totalWidth * maxLabelSpaceRatio;\n    }\n\n    /**\n     * Check if labels should be rendered based on maxLabelSpaceRatio\n     */\n    private shouldRenderLabels(): boolean {\n        const maxLabelSpaceRatio = this.customOptions?.maxLabelSpaceRatio ?? 0.25; // Reduced from 0.5 to 0.25\n        return maxLabelSpaceRatio > 0.0;\n    }\n\n    private shouldHideXAxisLabels(): boolean {\n        return this.customOptions?.hideAxisLabels?.x === true || this.shouldHideXAxis();\n    }\n\n    private shouldHideYAxisLabels(): boolean {\n        return this.customOptions?.hideAxisLabels?.y === true || this.shouldHideYAxis();\n    }\n\n    private shouldHideXAxis(): boolean {\n        return this.customOptions?.hideAxes?.x === true;\n    }\n\n    private isZoomEligible(): boolean {\n        //  a categorical y-axis (e.g. horizontal bar charts) is not the temporal\n        //  chart zoom targets — the x-domain there is a value range, not a timeline,\n        //  and wheel/drag zoom would just trap the mouse over an unrelated chart.\n        return this.zoomOptions.enabled !== false\n            && this.preparedPlot.axisXType === \"linear\"\n            && this.preparedPlot.axisYType !== \"categorical\"\n            && !this.shouldHideXAxis();\n    }\n\n    private shouldHideYAxis(): boolean {\n        return this.customOptions?.hideAxes?.y === true;\n    }\n\n    /**\n     * Repaint once the container actually has a size.\n     *\n     * Callers draw once and never retry, so a draw that bailed on an unsized\n     * container would leave an empty <svg> for the life of the page. Watch the\n     * container and redraw on the first resize that gives it usable dimensions.\n     */\n    private redrawWhenSized(options?: any) {\n        if (typeof ResizeObserver === \"undefined\") return;\n        const elm = this.plotElement;\n        if (!elm) return;\n        cancelResizeRedraw(elm);\n        // Fires once on observe(), so an element sized between the bail and here\n        // still gets its redraw rather than waiting for a resize that never comes.\n        const observer = new ResizeObserver(() => {\n            if (elm.clientWidth <= 0 || elm.clientHeight <= 0) return;\n            cancelResizeRedraw(elm);\n            this.draw(options);\n        });\n        observer.observe(elm);\n        pendingResizeRedraws.set(elm, observer);\n    }\n\n    /**\n     * Draw the plot\n     */\n    draw(options?: any) {\n        const drawToAlt = (options && options.svg);\n        let svgRoot: any, width: number, height: number, margin;\n        const preparedPlot = this.preparedPlot;\n\n        let fontSize: any;\n        {\n            //  setup font size etc.\n            let cw, ch; //store the w/h\n            if (drawToAlt) {\n                cw = options.width;\n                ch = options.height;\n            }\n            else {\n                const plotElm: any = this.plotElement;\n                cw = plotElm.clientWidth;\n                ch = plotElm.clientHeight;\n                this.dlWidth = cw;\n                this.dlHeight = ch;\n            }\n            // Use a percentage of the smaller dimension for font size\n            const fontSizeBase = ch * 0.025 * this.dlFontSizeMul;\n            // fontSize = Math.max(12, fontSizeBase);\n            fontSize = fontSizeBase;\n        }\n        const fsAxisX = this.axisTickFontSize(fontSize, preparedPlot.axisXType);\n        const fsAxisY = this.axisTickFontSize(fontSize, preparedPlot.axisYType);\n\n\n        if (drawToAlt) {\n            //  this means drawing to a hidden svg for image export or download\n            //  TODO: this is untested after many code changes...\n            const cw = options.width;\n            const ch = options.height;\n            const cs = Math.min(cw, ch);\n\n            // Calculate text size for export to ensure proper margins\n            const baseTextSize = this.calcTextSize(preparedPlot, fontSize);\n\n            // Calculate maximum allowed space for labels in export\n            const maxYLabelWidth = this.calcMaxYLabelMargin(cw);\n            const maxXLabelHeight = this.shouldRenderLabels() ? ch * (this.customOptions?.maxLabelSpaceRatio ?? 0.25) : 0;\n\n            const m = Math.min(40, cs * 0.1);\n            const leftMargin = this.shouldHideYAxisLabels()\n                ? 12\n                : Math.min(Math.max(baseTextSize.width + 10, fsAxisY * 2 + 12), maxYLabelWidth);\n\n            // Calculate additional bottom margin for rotated X-axis labels in export with height limit\n            const additionalBottomMargin = preparedPlot.axisXType === 'categorical'\n                ? this.calcRotatedXLabelMargin(preparedPlot.categoricalXLabels, fsAxisX, cw - leftMargin - m, maxXLabelHeight - fsAxisX - 12)\n                : 0;\n\n            margin = {\n                left: leftMargin,\n                right: m,\n                top: Math.max(baseTextSize.height, m),\n                bottom: fsAxisX * 1 + 12 + additionalBottomMargin\n            };\n\n            width = cw - margin.left - margin.right;\n            height = ch - margin.top - margin.bottom;\n\n            svgRoot = options.svg;\n            svgRoot.attr(\n                \"viewBox\",\n                `0 0 ${width + margin.left + margin.right} ${height + margin.top + margin.bottom}`);\n        }\n        else {\n            const baseTextSize = this.calcTextSize(preparedPlot, fontSize);\n            //  regular drawing on website\n            const plotElm: any = this.plotElement\n            // Use the calculated text width for left margin to ensure y-axis labels are fully visible\n            // Add some padding (10px) to ensure labels don't touch the edge\n\n            // Calculate maximum allowed space for labels\n            const maxYLabelWidth = this.calcMaxYLabelMargin(plotElm.clientWidth);\n            const maxXLabelHeight = this.shouldRenderLabels() ? plotElm.clientHeight * (this.customOptions?.maxLabelSpaceRatio ?? 0.25) : 0;\n\n            // Calculate efficient left margin - use actual text width but don't exceed reasonable limits\n            const minLeftMargin = Math.max(baseTextSize.width + 10, fsAxisY + 20); // Minimum reasonable margin\n            const leftMargin = this.shouldHideYAxisLabels() ? 12 : Math.min(minLeftMargin, maxYLabelWidth);\n\n            // Calculate additional bottom margin for rotated X-axis labels with height limit\n            const additionalBottomMargin = preparedPlot.axisXType === 'categorical'\n                ? this.calcRotatedXLabelMargin(preparedPlot.categoricalXLabels, fsAxisX, plotElm.clientWidth - leftMargin - 20, maxXLabelHeight - fsAxisX - 12)\n                : 0;\n\n            margin = {\n                left: leftMargin,\n                right: 20,\n                top: baseTextSize.height,\n                bottom: fsAxisX * 1 + 12 + additionalBottomMargin\n            };\n\n            plotElm.innerHTML = '';\n            width = plotElm.clientWidth - margin.left - margin.right;\n            height = plotElm.clientHeight - margin.top - margin.bottom;\n\n            svgRoot = d3.select(this.plotElement).append(\"svg\").attr(\"viewBox\", `0 0 ${plotElm.clientWidth} ${plotElm.clientHeight}`);\n        }\n\n        // Before the container is laid out (initial mount / hidden tab / stylesheet\n        // still in flight) the inner plot area can compute to zero or negative height\n        // once margins are removed. Rendering then throws \"negative attribute\" errors\n        // on <rect>/<foreignObject>; bail and redraw ourselves once it has a real size.\n        if (width <= 0 || height <= 0) {\n            if (!drawToAlt) this.redrawWhenSized(options);\n            return;\n        }\n        if (!drawToAlt) cancelResizeRedraw(this.plotElement);\n\n        svgRoot.append(\"rect\")\n            .attr(\"width\", \"100%\")\n            .attr(\"height\", \"100%\")\n            .attr(\"fill\", \"white\");\n        const svg = svgRoot.append(\"g\")\n            .attr(\"transform\", \"translate(\" + margin.left + \",\" + margin.top + \")\");\n        this.svg = svg;\n\n        // first add title / subtitle\n        const fsTitle = fontSize * 2;\n        if (this.dlTitle) {\n            svg.append(\"text\")\n                .attr(\"x\", width / 2)\n                .attr(\"y\", 0)\n                .attr(\"text-anchor\", \"middle\")\n                .style(\"font-size\", fsTitle + \"px\")\n                .style(\"font-family\", \"sans-serif\")\n                .text(this.dlTitle);\n        }\n        if (this.dlSubtitle) {\n            svg.append(\"text\")\n                .attr(\"x\", width / 2)\n                .attr(\"y\", fsTitle)\n                .attr(\"text-anchor\", \"middle\")\n                .style(\"font-size\", (fontSize * 1.5) + \"px\")\n                .style(\"font-family\", \"sans-serif\")\n                .style(\"fill\", \"#999\")\n                .text(this.dlSubtitle);\n        }\n\n\n        const zoomView = this.isZoomEligible() ? (this.zoomController?.view ?? null) : null;\n\n        // Add X axis - either linear or categorical\n        let x: any;\n        if (preparedPlot.axisXType === 'categorical') {\n            x = d3.scaleBand()\n                .domain(preparedPlot.categoricalXLabels.map((_, i) => i.toString()))\n                .range([0, width])\n                .padding(0.1);\n\n            // Only show axis if there are labels, they should be rendered, and X-axis labels are not hidden\n            if (preparedPlot.categoricalXLabels.length > 0 && preparedPlot.categoricalXLabels.some(label => label.trim() !== '') && this.shouldRenderLabels() && !this.shouldHideXAxisLabels()) {\n                const layout = this.resolveCategoricalXLayout(preparedPlot.categoricalXLabels, width, fsAxisX);\n\n                // Calculate available space per label for truncation\n                const spacePerLabel = x.bandwidth ? x.bandwidth() : width / preparedPlot.categoricalXLabels.length;\n                const maxLabelWidth = layout.rotation === 0\n                    ? spacePerLabel * layout.step // thinned labels may use the skipped bands' space\n                    : spacePerLabel * 2; // More space for rotated labels\n\n                // Render only every step-th tick so dense categorical axes stay readable\n                const tickValues = preparedPlot.categoricalXLabels\n                    .map((_, i) => i)\n                    .filter(i => i % layout.step === 0)\n                    .map(i => i.toString());\n\n                const xAxisGroup = svg.append(\"g\")\n                    .attr(\"transform\", \"translate(0,\" + height + \")\")\n                    .call(d3.axisBottom(x)\n                        .tickValues(tickValues)\n                        .tickFormat((d: any, i: number) => {\n                            const originalLabel = preparedPlot.categoricalXLabels[parseInt(d)] || '';\n                            return this.truncateTextWithEllipsis(originalLabel, maxLabelWidth, fsAxisX);\n                        })\n                    );\n\n                // Apply rotation to X-axis labels\n                const xAxisLabels = xAxisGroup.selectAll(\"text\")\n                    .style(\"font-size\", fsAxisX + \"px\");\n\n                this.applyLabelRotation(xAxisLabels, layout.rotation, 'x', fsAxisX);\n            } else if (preparedPlot.categoricalXLabels.length > 0 && (!this.shouldRenderLabels() || this.shouldHideXAxisLabels()) && !this.shouldHideXAxis()) {\n                // Show a bare axis line (no labels, no tick stubs) when labels are hidden\n                svg.append(\"g\")\n                    .attr(\"transform\", \"translate(0,\" + height + \")\")\n                    .call(d3.axisBottom(x)\n                        .tickFormat(() => '')\n                        .tickSize(0)\n                    );\n            }\n\n            // Create a mapping function for categorical to pixel coordinates\n            const xCategorical = x;\n            x = (d: any) => {\n                if (typeof d === 'number') {\n                    // For numeric indices, map to band center\n                    return xCategorical(d.toString()) + xCategorical.bandwidth() / 2;\n                }\n                return xCategorical(d);\n            };\n            // Copy bandwidth and other scale properties\n            x.bandwidth = () => xCategorical.bandwidth();\n            x.range = () => xCategorical.range();\n            x.domain = () => xCategorical.domain();\n        } else {\n            x = d3.scaleLinear()\n                .domain(zoomView ? [zoomView.xMin, zoomView.xMax] : [preparedPlot.xMin, preparedPlot.xMax])\n                .range([0, width]);\n\n            if (this.shouldHideXAxis()) {\n                // No axis at all (pie/radial charts define their own geometry)\n            } else if (this.shouldHideXAxisLabels()) {\n                // Show a bare axis line (no labels, no tick stubs) when labels are hidden\n                svg.append(\"g\")\n                    .attr(\"transform\", \"translate(0,\" + height + \")\")\n                    .call(d3.axisBottom(x)\n                        .tickFormat(() => '')\n                        .tickSize(0)\n                    );\n            } else {\n                // Show axis with labels\n                svg.append(\"g\")\n                    .attr(\"transform\", \"translate(0,\" + height + \")\")\n                    .call(d3.axisBottom(x)\n                        .tickFormat(function (d: any, i: any) {\n                            return d;\n                        })\n                        .ticks(Math.max(5, Math.floor(width / (fsAxisX * 5))))\n                    )\n                    .selectAll(\"text\")\n                    .style(\"font-size\", fsAxisX + \"px\");\n            }\n        }\n\n        // Add Y axis - either linear or categorical\n        let y: any;\n        if (preparedPlot.axisYType === 'categorical') {\n            // Index 0 renders at the TOP (like a list), so descending data reads top-down.\n            y = d3.scaleBand()\n                .domain(preparedPlot.categoricalYLabels.map((_, i) => i.toString()))\n                .range([0, height])\n                .padding(0.1);\n\n            // Only show axis if there are labels, they should be rendered, and Y-axis labels are not hidden\n            if (preparedPlot.categoricalYLabels.length > 0 && preparedPlot.categoricalYLabels.some(label => label.trim() !== '') && this.shouldRenderLabels() && !this.shouldHideYAxisLabels()) {\n                // Horizontal labels, truncated to the margin; thinned when rows are denser than the font\n                const bandHeight = y.bandwidth ? y.bandwidth() : height / preparedPlot.categoricalYLabels.length;\n                const maxLabelWidth = margin.left - 10; // Use available left margin space\n                const yStep = Math.max(1, Math.ceil((fsAxisY * 1.2) / Math.max(1, bandHeight)));\n                const tickValues = preparedPlot.categoricalYLabels\n                    .map((_, i) => i)\n                    .filter(i => i % yStep === 0)\n                    .map(i => i.toString());\n\n                svg.append(\"g\")\n                    .call(d3.axisLeft(y)\n                        .tickValues(tickValues)\n                        .tickFormat((d: any, i: number) => {\n                            const originalLabel = preparedPlot.categoricalYLabels[parseInt(d)] || '';\n                            return this.truncateTextWithEllipsis(originalLabel, maxLabelWidth, fsAxisY);\n                        })\n                    )\n                    .selectAll(\"text\")\n                    .style(\"font-size\", fsAxisY + \"px\");\n            } else if (preparedPlot.categoricalYLabels.length > 0 && (!this.shouldRenderLabels() || this.shouldHideYAxisLabels()) && !this.shouldHideYAxis()) {\n                // Show a bare axis line (no labels, no tick stubs) when labels are hidden\n                svg.append(\"g\")\n                    .call(d3.axisLeft(y)\n                        .tickFormat(() => '')\n                        .tickSize(0)\n                    );\n            }\n\n            // Create a mapping function for categorical to pixel coordinates\n            const yCategorical = y;\n            y = (d: any) => {\n                if (typeof d === 'number') {\n                    // For numeric indices, map to band center\n                    return yCategorical(d.toString()) + yCategorical.bandwidth() / 2;\n                }\n                return yCategorical(d);\n            };\n            // Copy bandwidth and other scale properties\n            y.bandwidth = () => yCategorical.bandwidth();\n            y.range = () => yCategorical.range();\n            y.domain = () => yCategorical.domain();\n        } else {\n            let yLo = preparedPlot.yMin, yHi = preparedPlot.yMax;\n            if (zoomView) {\n                const fitted = this.computeViewYBounds(zoomView);\n                yLo = fitted.yMin;\n                yHi = fitted.yMax;\n            }\n            y = d3.scaleLinear()\n                .domain([yLo, yHi])\n                .range([height, 0]);\n\n            if (this.shouldHideYAxis()) {\n                // No axis at all (pie/radial charts define their own geometry)\n            } else if (this.shouldHideYAxisLabels()) {\n                // Show a bare axis line (no labels, no tick stubs) when labels are hidden\n                svg.append(\"g\")\n                    .call(d3.axisLeft(y)\n                        .tickFormat(() => '')\n                        .tickSize(0)\n                    );\n            } else {\n                // Show axis with labels\n                svg.append(\"g\")\n                    .call(d3.axisLeft(y)\n                        .ticks(Math.max(5, Math.floor(height / (fsAxisY * 4))))\n                    )\n                    .selectAll(\"text\")\n                    .style(\"font-size\", fsAxisY + \"px\");\n            }\n        }\n\n        this.axisX = x;\n        this.axisY = y;\n\n        // Optional light horizontal gridlines (opt-in; keeps other plots untouched).\n        // Drawn before the data renderables so they sit behind the lines/markers.\n        if (this.customOptions?.showGridlines && preparedPlot.axisYType === 'linear' && !this.shouldHideYAxis()) {\n            const ticks = y.ticks(Math.max(4, Math.floor(height / (fsAxisY * 4))));\n            svg.append(\"g\")\n                .attr(\"class\", \"myd3-gridlines\")\n                .selectAll(\"line\")\n                .data(ticks)\n                .enter()\n                .append(\"line\")\n                .attr(\"x1\", 0)\n                .attr(\"x2\", width)\n                .attr(\"y1\", (d: number) => y(d))\n                .attr(\"y2\", (d: number) => y(d))\n                .attr(\"stroke\", \"#eef2f6\")\n                .attr(\"stroke-width\", 1);\n        }\n\n        //  render data into a clipped layer so zoomed content cannot spill past the axes\n        let dataLayer = svg;\n        if (this.isZoomEligible()) {\n            const clipId = `myd3-clip-${++MyD3.clipSeq}`;\n            svg.append(\"defs\").append(\"clipPath\").attr(\"id\", clipId)\n                .append(\"rect\")\n                .attr(\"x\", 0)\n                .attr(\"y\", -5)               //  small headroom so edge markers aren't half-clipped\n                .attr(\"width\", width)\n                .attr(\"height\", height + 10);\n            dataLayer = svg.append(\"g\").attr(\"clip-path\", `url(#${clipId})`);\n        }\n        this.svg = dataLayer;\n        for (const renderable of this.preparedPlot.renderables) {\n            renderable.render();\n        }\n        this.svg = svg;\n\n        if (this.data.type === \"OTHER\") {\n            //  more flexible rendering. the legacy code won't be executed here.\n        }\n        else {\n            this.classicPostRendering({\n                width: width,\n                height: height,\n            });\n        }\n\n\n        if (!drawToAlt) {\n            this.addUI(svgRoot, svg, width, height);\n            if (this.isZoomEligible()) {\n                if (!this.zoomController) {\n                    this.zoomController = new ZoomController(\n                        { xMin: preparedPlot.xMin, xMax: preparedPlot.xMax },\n                        this.zoomOptions,\n                        () => this.draw(),\n                        this.vueTranslation\n                    );\n                }\n                //  topmost overlay for the selection band; never intercepts events\n                const overlay = svg.append(\"g\").attr(\"pointer-events\", \"none\");\n                this.zoomController.attach({\n                    svgRoot,\n                    gNode: svg.node(),\n                    overlay,\n                    width,\n                    height,\n                    xScale: x\n                });\n                if (this.toolbarContainer) {\n                    this.zoomController.ensureControls(this.toolbarContainer);\n                }\n            }\n        }\n    }\n\n    private classicPostRendering(renderContext: RenderContext) {\n        const svg = this.svg;\n        const width = renderContext.width;\n        const height = renderContext.height;\n        const axisX = this.axisX;\n        const axisY = this.axisY;\n        const preparedPlot = this.preparedPlot;\n\n        // horizontal line at 1.0 (the trend-index baseline; count charts opt out).\n        // Skipped when zooming has pushed 1.0 outside the visible y domain.\n        const [yd0, yd1] = axisY.domain();\n        const unityVisible = 1.0 >= Math.min(yd0, yd1) && 1.0 <= Math.max(yd0, yd1);\n        if (!this.customOptions?.hideUnityLine && unityVisible) {\n            svg.append('line')\n                .style(\"stroke\", \"#999\")\n                .style(\"stroke-width\", 1.0)// * this.dlStrokeWidthMul)\n                .attr(\"x1\", 0)\n                .attr(\"y1\", axisY(1.0))\n                .attr(\"x2\", width)\n                .attr(\"y2\", axisY(1.0))\n                .style(\"stroke-dasharray\", (\"3, 3\"));\n        }\n\n        //MYLINE (the lines that move with the mouse)\n        const myLine = svg.append('line')\n            .style(\"stroke\", \"#999\")\n            .style(\"stroke-width\", 1.0 * this.dlStrokeWidthMul)\n            .attr(\"x1\", 0)\n            .attr(\"y1\", 0)\n            .attr(\"x2\", 0)\n            .attr(\"y2\", height)\n            .style(\"opacity\", 0);\n        const myLine2 = svg.append('line')\n            .style(\"stroke\", \"#999\")\n            .style(\"stroke-width\", 1.0 * this.dlStrokeWidthMul)\n            .attr(\"x1\", 0)\n            .attr(\"y1\", 0)\n            .attr(\"x2\", width)\n            .attr(\"y2\", 0)\n            .style(\"opacity\", 0);\n        const myLine2Text = svg.append(\"text\")\n            .attr(\"x\", axisX(preparedPlot.xMin) + 3) // x-coordinate of the text\n            .attr(\"y\", axisY(preparedPlot.yMin)) // y-coordinate of the text\n            .attr(\"text-anchor\", \"start\") // alignment of the text\n            .attr(\"fill\", \"#999\").attr(\"font-size\", \"12px\")\n            .text(\"\"); // the text content\n\n        const allFocusMarkers: any[] = [];\n        for (const trace of preparedPlot.traces) {\n            if (trace.focusMarker) allFocusMarkers.push(trace.focusMarker);\n        }\n\n        // Create tooltip using the Tooltip class\n        const myTooltip = new Tooltip(svg, width, height);\n\n        if (this.message) {\n            const cx = width / 2;\n            const cy = height / 2;\n\n            const rw = cx;\n            const rh = 60;\n            const myRect = svg.append(\"rect\")\n                .attr(\"width\", \"\" + rw + \"px\")\n                .attr(\"height\", \"\" + rh + \"px\")\n                .attr(\"x\", cx - rw / 2)\n                .attr(\"y\", cy - rh / 2)\n                .attr(\"fill\", \"rgba(248,215,218,0.75)\")\n                .attr(\"stroke\", \"#842029\");\n\n            const myTest = svg\n                .append('text')\n                .attr(\"x\", cx)\n                .attr(\"y\", cy)\n                .attr(\"text-anchor\", \"middle\")\n                .attr(\"dominant-baseline\", \"central\")\n                .style(\"fill\", \"#842029\")\n                .text(this.message.text);\n        }\n\n\n\n        //THE mouse reactive rect on top\n        const myRect = svg.append(\"rect\")\n            .style(\"pointer-events\", \"all\")\n            .attr(\"width\", \"\" + width + \"px\")\n            .attr(\"height\", \"\" + height + \"px\")\n            .attr(\"fill\", \"none\");\n\n\n\n\n\n        this.crosshairParts = [myLine, myLine2, myLine2Text];\n        //  every per-year data point of this draw, so the hovered year can be emphasized\n        const yearMarkers = svg.selectAll(\"circle.myd3-year-marker\");\n        const rteItems = svg.selectAll(\".myd3-rte-item\");\n        const hideAndShow = [...allFocusMarkers];\n        const vueTranslation = this.vueTranslation;\n        myRect.on(\"mouseover\", (e: any) => {\n            for (const idx in hideAndShow) {\n                hideAndShow[idx].style(\"opacity\", 1);\n            }\n        })\n            .on(\"mousemove\", (e: any) => {\n                const mouse = d3.pointer(e);\n                const mx = mouse[0];\n                const my = mouse[1];\n                const x0 = axisX.invert(mx);\n\n                myLine.attr(\"x1\", mx).attr(\"x2\", mx);\n                myLine2.attr(\"y1\", my).attr(\"y2\", my);\n                myLine2Text.attr(\"y\", my - 3).text(axisY.invert(my).toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 }));\n                //  applied on every move so the toolbar toggle takes effect mid-hover\n                this.setCrosshairVisible(this.crosshairEnabled);\n\n                // First pass: Find the closest X across all traces\n                let bestX: any = null;\n                let minDiff = Infinity;\n\n                for (const trace of preparedPlot.traces) {\n                    if (trace.settings?.hideFocus) continue;\n                    if (!trace.items || trace.items.length === 0) continue;\n\n                    const bisect = d3.bisector(function (d: any) { return d.data[trace.keyX]; }).center;\n                    const i = bisect(trace.items, x0, 0);\n                    const item = trace.items[i];\n\n                    if (item) {\n                        const xVal = item.data[trace.keyX];\n                        // Assuming x-axis is linear/numeric for distance calculation. \n                        // If categorical, this logic might need adjustment, but usually tooltips work on pixel distance or index.\n                        // Given axisX.invert(mx) returns a value, we assume we can compare.\n                        // For categorical, x0 might be a string or index? \n                        // The original code used x0 directly in bisect, implying it's comparable.\n\n                        // We calculate distance in domain space (e.g. years)\n                        // Note: bisect.center usually returns the index of the closest value.\n                        const diff = Math.abs(xVal - x0);\n                        if (diff < minDiff) {\n                            minDiff = diff;\n                            bestX = xVal;\n                        }\n                    }\n                }\n\n                MyD3.emphasizeYearMarkers(yearMarkers, bestX);\n                MyD3.emphasizeRteItems(rteItems, bestX);\n\n                // Collect data for all traces based on bestX\n                const tooltipTraces: TooltipTraceData[] = [];\n                let markerX = -1, markerY = -1, nbSites = -1;\n                let isFirstTraceWithData = true;\n\n                for (let idx = 0; idx < preparedPlot.traces.length; idx++) {\n                    const trace = preparedPlot.traces[idx];\n                    if (trace.settings?.hideFocus) continue;\n\n                    // Find data point matching bestX\n                    // We can use bisect again or just search. Since arrays are sorted, bisect is fast.\n                    // But we need exact match (or very close).\n                    let selectedData = null;\n                    let hasData = false;\n                    let selX = bestX;\n                    let selY = undefined;\n\n                    if (bestX !== null) {\n                        const bisect = d3.bisector(function (d: any) { return d.data[trace.keyX]; }).center;\n                        const i = bisect(trace.items, bestX, 0);\n                        const potentialItem = trace.items[i];\n\n                        // Check if it matches bestX\n                        if (potentialItem && potentialItem.data[trace.keyX] === bestX) {\n                            selectedData = potentialItem;\n                            hasData = true;\n                            selX = selectedData.data[trace.keyX];\n                            selY = selectedData.data[trace.keyY];\n                        }\n                    }\n\n                    if (hasData && selectedData) {\n                        const pixelX = axisX(selX);\n                        const pixelY = axisY(selY);\n\n                        if (isFirstTraceWithData) {\n                            markerX = pixelX;\n                            markerY = pixelY;\n                            isFirstTraceWithData = false;\n                        }\n\n                        if (trace.focusMarker) {\n                            trace.focusMarker.attr(\"cx\", pixelX).attr(\"cy\", pixelY);\n                            trace.focusMarker.style(\"opacity\", 1);\n                        }\n\n                        // Update nbSites from first trace that has it and has data\n                        if (selectedData.data.nbSites !== undefined && nbSites < 0) {\n                            nbSites = selectedData.data.nbSites;\n                        }\n                    } else {\n                        // Hide marker if no data for this year\n                        if (trace.focusMarker) {\n                            trace.focusMarker.style(\"opacity\", 0);\n                        }\n                    }\n\n                    // Collect trace data for tooltip building\n                    tooltipTraces.push({\n                        trace,\n                        selectedData,\n                        selX: bestX, // Use bestX so all entries show the same year header if used\n                        selY,\n                        isFirst: (idx === 0), // Keep original isFirst logic for tooltip rendering if needed\n                        hasData\n                    });\n                }\n\n                // Build tooltip using custom or default builder\n                const tooltipContext: TooltipContext = {\n                    traces: tooltipTraces,\n                    nbSites,\n                    dataType: this.data.type,\n                    translate: vueTranslation,\n                    customOptions: this.customOptions\n                };\n\n                const html = this.customOptions?.tooltipBuilder\n                    ? this.customOptions.tooltipBuilder(tooltipContext)\n                    : this.buildDefaultTooltip(tooltipContext);\n\n                // Show tooltip using the Tooltip class\n                // If we found a valid marker position (from the first trace with data), use it.\n                // If no trace has data (shouldn't happen if bestX found), use mouse position or hide?\n                if (markerX !== -1) {\n                    myTooltip.show(html, markerX, markerY);\n                } else if (bestX !== null) {\n                    // Fallback if the first trace didn't have data but others did?\n                    // actually markerX is set by the first trace in the loop. \n                    // If the first trace doesn't have data, markerX stays -1.\n                    // We should probably find the first trace *that has data* to set markerX/Y.\n                    // Let's fix the markerX logic above.\n\n                    // Re-scanning to find a valid marker pos if needed\n                    const validTrace = tooltipTraces.find(t => t.hasData);\n                    if (validTrace && validTrace.selectedData) {\n                        const px = axisX(validTrace.selX);\n                        const py = axisY(validTrace.selY);\n                        myTooltip.show(html, px, py);\n                    } else {\n                        myTooltip.show(html, mx, my); // Fallback to mouse\n                    }\n                } else {\n                    myTooltip.hide();\n                }\n\n            })\n            .on(\"mouseleave\", (e: any) => {\n                for (const idx in hideAndShow) {\n                    hideAndShow[idx].style(\"opacity\", 0);\n                }\n                this.setCrosshairVisible(false);\n                MyD3.emphasizeYearMarkers(yearMarkers, null);\n                MyD3.emphasizeRteItems(rteItems, null);\n                myTooltip.hide();\n            })\n    }\n\n    /** Show/hide the crosshair lines of the current draw. */\n    private setCrosshairVisible(visible: boolean) {\n        for (const part of this.crosshairParts) part.style(\"opacity\", visible ? 1 : 0);\n    }\n\n    /**\n     * Grow the data points sitting on `bestX` (null resets them). The base radius\n     * travels on the element as `data-r`, the x value as `data-x`, so this needs to\n     * know nothing about the traces the markers came from.\n     */\n    private static emphasizeYearMarkers(markers: any, bestX: any) {\n        const key = bestX === null || bestX === undefined ? null : `${bestX}`;\n        markers.attr(\"r\", function (this: SVGCircleElement) {\n            const el = d3.select(this);\n            const base = parseFloat(el.attr(\"data-r\"));\n            if (isNaN(base)) return el.attr(\"r\");\n            return el.attr(\"data-x\") === key ? base * 1.8 : base;\n        });\n    }\n\n    /**\n     * Subtle emphasis for the random-time-effect items (circles + error lines):\n     * the items of all years EXCEPT `bestX` turn slightly transparent, so the\n     * hovered year's RTE stands out without any size change. null resets.\n     */\n    private static emphasizeRteItems(items: any, bestX: any) {\n        const key = bestX === null || bestX === undefined ? null : `${bestX}`;\n        items.style(\"opacity\", function (this: SVGElement) {\n            if (key === null) return null;\n            return d3.select(this).attr(\"data-x\") === key ? null : 0.55;\n        });\n    }\n\n    addUI(svgRoot: any, svg: any, width: number, height: number) {\n        const rootContainer = this.plotElement;\n        if (!rootContainer) return;\n        if (this.toolbarContainer) {\n            //  a zoom/pan redraw wiped the plot element (innerHTML = ''); the toolbar\n            //  node survives in JS — re-attach it instead of rebuilding\n            if (!this.toolbarContainer.isConnected) {\n                rootContainer.appendChild(this.toolbarContainer);\n            }\n            return;\n        }\n        this.toolbarContainer = ElementBuilder.append(rootContainer, \"div\", {\n            class: \"position-absolute top-0 end-0 m-2 text-end m-0\"\n        }).el();\n        //  the toolbar is position:absolute against the nearest positioned ancestor;\n        //  make rootContainer that ancestor unless the consumer already positioned it\n        //  (defensive: a consumer forgetting `position` on its chart container would\n        //  otherwise have the toolbar escape to some further-up positioned parent)\n        if (getComputedStyle(rootContainer).position === \"static\") {\n            rootContainer.style.position = \"relative\";\n        }\n\n        //  the crosshair only exists on the classic path (classicPostRendering)\n        if (this.data?.type !== \"OTHER\") {\n            const crosshairButton = ElementBuilder.append(this.toolbarContainer, \"button\", {\n                type: \"button\",\n                class: \"btn btn-sm btn-outline-secondary me-1\",\n                title: this.t(\"trends.zoom.crosshair\", \"Toggle crosshair\")\n            }).el() as HTMLButtonElement;\n            crosshairButton.innerHTML = '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\"'\n                + ' stroke=\"currentColor\" stroke-width=\"1\"><line x1=\"8\" y1=\"1\" x2=\"8\" y2=\"15\"/>'\n                + '<line x1=\"1\" y1=\"8\" x2=\"15\" y2=\"8\"/><circle cx=\"8\" cy=\"8\" r=\"3.5\"/></svg>';\n            crosshairButton.onclick = () => {\n                this.crosshairEnabled = !this.crosshairEnabled;\n                if (!this.crosshairEnabled) this.setCrosshairVisible(false);\n                crosshairButton.className = this.crosshairEnabled\n                    ? \"btn btn-sm btn-secondary me-1\"\n                    : \"btn btn-sm btn-outline-secondary me-1\";\n            };\n        }\n\n        const imageButton = ElementBuilder.append(this.toolbarContainer, \"button\", {\n            type: \"button\",\n            class: \"btn btn-sm btn-outline-secondary\",\n            title: this.t(\"trends.image.save\", \"Save as image\")\n        }).el();\n        //  inlined (like the zoom icons) so the library does not depend on the\n        //  Django-served sprite, which is not on every page that hosts a chart\n        imageButton.innerHTML = '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\"'\n            + ' stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">'\n            + '<path d=\"M8 2v8\"/><path d=\"M4.5 7 8 10.5 11.5 7\"/><path d=\"M2.5 13h11\"/></svg>';\n        imageButton.onclick = () => this.buildDownloadPopup();\n    }\n\n    /**\n     * Translate with an English fallback — MyD3 can be constructed without a\n     * translate fn, and vue-i18n echoes the key back when it has no message.\n     */\n    private t(key: string, fallback: string): string {\n        if (typeof this.vueTranslation !== \"function\") return fallback;\n        const s = this.vueTranslation(key);\n        return s && s !== key ? s : fallback;\n    }\n\n    /**\n     * Open the download dialog. It is a Bootstrap-styled modal mounted on\n     * `document.body`: as a child of the plot container it was clipped by small\n     * charts, which put the expert controls and the format buttons out of reach.\n     */\n    buildDownloadPopup() {\n        if (this.popupContainer) return; //  already open\n\n        const $t = (key: string, fallback: string) => this.t(key, fallback);\n        const MIN_W = 400, MIN_H = 300, MAX_W = 2048, MAX_H = 2048;\n        const uid = `myd3dl${MyD3.dlSeq++}`;\n        const formatButtons: HTMLButtonElement[] = [];\n\n        const modal = ElementBuilder.create(\"div\", {\n            class: \"modal fade show\",\n            tabindex: \"-1\",\n            role: \"dialog\",\n            \"aria-modal\": \"true\",\n            \"aria-label\": $t(\"trends.image.dialogTitle\", \"Download plot as image\")\n        }).el();\n        modal.style.display = \"block\";\n        const backdrop = ElementBuilder.create(\"div\", { class: \"modal-backdrop fade show\" }).el();\n        const content = ElementBuilder.append(\n            ElementBuilder.append(modal, \"div\", {\n                class: \"modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable\"\n            }).el(),\n            \"div\", { class: \"modal-content\" }\n        ).el();\n\n        //  ---- helpers ----\n        const sectionTitle = (parent: HTMLElement, text: string) =>\n            ElementBuilder.append(parent, \"h6\", { class: \"fw-semibold mb-2\" }).text(text).el();\n\n        const field = (parent: HTMLElement, id: string, label: string,\n                       attrs: Record<string, unknown>): HTMLInputElement => {\n            ElementBuilder.append(parent, \"label\", { for: id, class: \"form-label small mb-1\" }).text(label);\n            return ElementBuilder.append(parent, \"input\", {\n                class: \"form-control form-control-sm\", id, ...attrs\n            }).el() as HTMLInputElement;\n        };\n\n        const clampInput = (input: HTMLInputElement, fallback: number, min: number, max: number): number => {\n            const parsed = parseFloat(input.value);\n            const value = isNaN(parsed) ? fallback : Math.max(min, Math.min(max, parsed));\n            input.value = `${value}`; //  reflect the clamp back to the user\n            return value;\n        };\n\n        //  ---- header ----\n        const header = ElementBuilder.append(content, \"div\", { class: \"modal-header\" }).el();\n        ElementBuilder.append(header, \"h5\", { class: \"modal-title\" })\n            .text($t(\"trends.image.dialogTitle\", \"Download plot as image\"));\n        const closeButton = ElementBuilder.append(header, \"button\", {\n            type: \"button\",\n            class: \"btn-close\",\n            \"aria-label\": $t(\"trends.image.close\", \"Close\")\n        }).el();\n\n        //  ---- body ----\n        const body = ElementBuilder.append(content, \"div\", { class: \"modal-body\" }).el();\n        ElementBuilder.append(body, \"p\", { class: \"text-muted small\" }).text($t(\"trends.image.text\",\n            \"You can download the plot as an image file. Please select the resolution you want to \"\n            + \"use and click a file format to start the download.\"));\n        const grid = ElementBuilder.append(body, \"div\", { class: \"row g-4\" }).el();\n\n        //  Scale a chart size into the accepted range, keeping its aspect ratio —\n        //  dashboard widgets are far below the minimum, and their unscaled size would\n        //  open the dialog in the invalid state.\n        const fitSize = (w: number, h: number): [number, number] => {\n            const grow = Math.max(MIN_W / w, MIN_H / h, 1);\n            w *= grow;\n            h *= grow;\n            const shrink = Math.min(MAX_W / w, MAX_H / h, 1);\n            return [Math.round(w * shrink), Math.round(h * shrink)];\n        };\n\n        //  resolution\n        const colSize = ElementBuilder.append(grid, \"div\", { class: \"col-md-6\" }).el();\n        sectionTitle(colSize, $t(\"trends.image.resolution\", \"Resolution\"));\n        const sizeRow = ElementBuilder.append(colSize, \"div\", { class: \"row g-2\" }).el();\n        const [startW, startH] = fitSize(this.dlWidth, this.dlHeight);\n        const inputW = field(ElementBuilder.append(sizeRow, \"div\", { class: \"col-6\" }).el(),\n            `${uid}-w`, $t(\"trends.image.width\", \"Width\"),\n            { type: \"number\", step: \"1\", min: `${MIN_W}`, max: `${MAX_W}`, value: `${startW}` });\n        const inputH = field(ElementBuilder.append(sizeRow, \"div\", { class: \"col-6\" }).el(),\n            `${uid}-h`, $t(\"trends.image.height\", \"Height\"),\n            { type: \"number\", step: \"1\", min: `${MIN_H}`, max: `${MAX_H}`, value: `${startH}` });\n\n        const presetRow = ElementBuilder.append(colSize, \"div\", { class: \"d-flex flex-wrap gap-1 mt-2\" }).el();\n        const presets: [string, number, number][] = [];\n        const screen = this.plotSize();\n        if (screen && screen.w > 0 && screen.h > 0) {\n            const [w, h] = fitSize(screen.w, screen.h);\n            presets.push([$t(\"trends.image.presetScreen\", \"As shown\"), w, h]);\n        }\n        presets.push([\"1024 × 768\", 1024, 768], [\"1600 × 1200\", 1600, 1200], [\"1920 × 1080\", 1920, 1080]);\n        for (const [label, w, h] of presets) {\n            const btn = ElementBuilder.append(presetRow, \"button\", {\n                type: \"button\", class: \"btn btn-sm btn-outline-secondary\"\n            }).text(label).el();\n            btn.onclick = () => {\n                inputW.value = `${w}`;\n                inputH.value = `${h}`;\n                resCheck();\n            };\n        }\n        ElementBuilder.append(colSize, \"div\", { class: \"form-text\" })\n            .text(`${MIN_W}–${MAX_W} × ${MIN_H}–${MAX_H} px`);\n        const errorText = ElementBuilder.append(colSize, \"div\", { class: \"text-danger small\" }).el();\n\n        //  labels drawn into the exported image\n        const colLabels = ElementBuilder.append(grid, \"div\", { class: \"col-md-6\" }).el();\n        sectionTitle(colLabels, $t(\"trends.image.labels\", \"Labels\"));\n        const inputTitle = field(ElementBuilder.append(colLabels, \"div\", { class: \"mb-2\" }).el(),\n            `${uid}-title`, $t(\"trends.image.title\", \"Title\"),\n            { type: \"text\", value: this.dlTitle || this.customOptions?.title || \"\" });\n        const inputSubtitle = field(ElementBuilder.append(colLabels, \"div\").el(),\n            `${uid}-subtitle`, $t(\"trends.image.subtitle\", \"Subtitle\"),\n            { type: \"text\", value: this.dlSubtitle || this.customOptions?.subtitle || \"\" });\n\n        //  expert-only rendering knobs\n        let inputStrokeWidth: HTMLInputElement | null = null;\n        let inputStrokeWidthMul: HTMLInputElement | null = null;\n        let inputFontSizeMul: HTMLInputElement | null = null;\n        if (this.customOptions?.expertMode) {\n            const expert = ElementBuilder.append(body, \"div\", { class: \"border rounded bg-light p-3 mt-4\" }).el();\n            const expertHead = ElementBuilder.append(expert, \"div\", {\n                class: \"d-flex align-items-center gap-2 mb-2\"\n            }).el();\n            ElementBuilder.append(expertHead, \"span\", { class: \"badge-circle badge-admin\" });\n            ElementBuilder.append(expertHead, \"h6\", { class: \"fw-semibold mb-0\" })\n                .text($t(\"trends.image.options\", \"Expert settings\"));\n            const expertRow = ElementBuilder.append(expert, \"div\", { class: \"row g-2\" }).el();\n            const expertCol = () => ElementBuilder.append(expertRow, \"div\", { class: \"col-sm-4\" }).el();\n            inputStrokeWidth = field(expertCol(), `${uid}-sw`, $t(\"trends.image.strokeWidthMain\", \"Stroke width\"),\n                { type: \"number\", step: \"0.05\", min: \"0.5\", max: \"20\", value: `${this.dlStrokeWidth}` });\n            inputStrokeWidthMul = field(expertCol(), `${uid}-swm`, $t(\"trends.image.strokeWidthMul\", \"Stroke width multiplier\"),\n                { type: \"number\", step: \"0.05\", min: \"0.25\", max: \"3\", value: `${this.dlStrokeWidthMul}` });\n            inputFontSizeMul = field(expertCol(), `${uid}-fsm`, $t(\"trends.image.fontSizeMul\", \"Font size multiplier\"),\n                { type: \"number\", step: \"0.05\", min: \"0.5\", max: \"3\", value: `${this.dlFontSizeMul}` });\n        }\n\n        //  ---- footer: one button per file format ----\n        const footer = ElementBuilder.append(content, \"div\", { class: \"modal-footer justify-content-between\" }).el();\n        ElementBuilder.append(footer, \"span\", { class: \"fw-semibold small\" })\n            .text($t(\"trends.image.save\", \"Save as image\"));\n        const formatsRow = ElementBuilder.append(footer, \"div\", { class: \"btn-group\" }).el();\n        for (const format of [\"SVG\", \"PNG\", \"JPEG\", \"WEBP\"]) {\n            const btn = ElementBuilder.append(formatsRow, \"button\", {\n                type: \"button\", class: \"btn btn-sm btn-primary\"\n            }).text(format).el() as HTMLButtonElement;\n            btn.onclick = () => {\n                if (!isValidResolution()) return;\n                this.dlWidth = parseInt(inputW.value);\n                this.dlHeight = parseInt(inputH.value);\n                if (inputFontSizeMul) this.dlFontSizeMul = clampInput(inputFontSizeMul, this.dlFontSizeMul, 0.5, 3.0);\n                if (inputStrokeWidth) this.dlStrokeWidth = clampInput(inputStrokeWidth, this.dlStrokeWidth, 0.5, 20.0);\n                if (inputStrokeWidthMul) this.dlStrokeWidthMul = clampInput(inputStrokeWidthMul, this.dlStrokeWidthMul, 0.25, 3.0);\n                this.dlTitle = inputTitle.value;\n                this.dlSubtitle = inputSubtitle.value;\n                this.download({\n                    type: format.toLowerCase(),\n                    width: this.dlWidth,\n                    height: this.dlHeight,\n                    name: this.customOptions?.downloadName || \"plot\"\n                });\n            };\n            formatButtons.push(btn);\n        }\n\n        //  ---- validation ----\n        const isValidResolution = () => {\n            const w = parseInt(inputW.value);\n            const h = parseInt(inputH.value);\n            return !isNaN(w) && !isNaN(h) && w >= MIN_W && h >= MIN_H && w <= MAX_W && h <= MAX_H;\n        };\n        const resCheck = () => {\n            const valid = isValidResolution();\n            errorText.textContent = valid ? \"\" : $t(\"trends.image.invalidResolution\", \"Invalid resolution\");\n            for (const btn of formatButtons) btn.disabled = !valid;\n            if (valid) {\n                this.dlWidth = parseInt(inputW.value);\n                this.dlHeight = parseInt(inputH.value);\n            }\n        };\n        inputW.addEventListener(\"input\", resCheck);\n        inputH.addEventListener(\"input\", resCheck);\n\n        //  ---- mount + dismissal ----\n        const close = () => this.closeDownloadPopup();\n        closeButton.onclick = close;\n        //  mousedown (not click) so a drag that ends outside the dialog does not close it\n        modal.addEventListener(\"mousedown\", (e: MouseEvent) => {\n            if (e.target === modal) close();\n        });\n        this.popupKeyHandler = (e: KeyboardEvent) => {\n            if (e.key === \"Escape\") close();\n        };\n        document.addEventListener(\"keydown\", this.popupKeyHandler);\n        //  the chart can be torn down (route change, component unmount) while the dialog\n        //  is open — it hangs off <body>, so nothing else would ever remove it\n        this.popupWatchTimer = window.setInterval(() => {\n            if (!this.plotSize()) close();\n        }, 500);\n\n        document.body.appendChild(backdrop);\n        document.body.appendChild(modal);\n        document.body.classList.add(\"modal-open\");\n        this.popupContainer = modal;\n        this.popupBackdrop = backdrop;\n        resCheck();\n        inputW.focus();\n        inputW.select();\n    }\n\n    /** Remove the dialog and everything it registered outside the chart. */\n    closeDownloadPopup() {\n        if (this.popupKeyHandler) {\n            document.removeEventListener(\"keydown\", this.popupKeyHandler);\n            this.popupKeyHandler = undefined;\n        }\n        if (this.popupWatchTimer !== undefined) {\n            window.clearInterval(this.popupWatchTimer);\n            this.popupWatchTimer = undefined;\n        }\n        if (this.popupContainer) this.popupContainer.remove();\n        if (this.popupBackdrop) this.popupBackdrop.remove();\n        this.popupContainer = undefined;\n        this.popupBackdrop = undefined;\n        //  a chart can sit inside another modal — only give the body its scroll back\n        //  once no modal at all is left open\n        if (!document.querySelector(\".modal.show\")) {\n            document.body.classList.remove(\"modal-open\");\n        }\n    }\n\n    /** On-screen size of the chart container, or null when it is gone from the DOM. */\n    private plotSize(): { w: number; h: number } | null {\n        let elm: HTMLElement | undefined;\n        try {\n            elm = this.plotElement;\n        }\n        catch (e) {\n            return null;\n        }\n        if (!elm || !elm.isConnected) return null;\n        return { w: Math.round(elm.clientWidth), h: Math.round(elm.clientHeight) };\n    }\n\n    /**\n     * Download the plot as an image\n     * @param type The type of image to download\n     */\n    download(options: any) {\n        if (options.type === 'svg') {\n            this.toSvg(options);\n        }\n        else {\n            this.toImage(options);\n        }\n    }\n\n\n    /**\n     * For downloading the plot as an image, we first create a SVG image as URL (which can be the src of an image)\n     * @private\n     */\n    private svgInit(options: any): any {\n        let svg;\n        if (options.width) {\n            //svg = d3.select('#' + this.plotId).select(\"svg\");\n            svg = d3.create(\"svg\").attr(\"width\", options.width).attr(\"height\", options.height);\n            options.svg = svg;\n            this.draw(options);\n            //  the tooltip host is an empty <foreignObject>; it draws nothing, but Chrome\n            //  taints a canvas painted from an SVG that contains one, which made every\n            //  raster export fail with \"Tainted canvases may not be exported\"\n            svg.selectAll(\"foreignObject\").remove();\n        }\n        else {\n            svg = d3.select(this.plotElement).select(\"svg\");\n        }\n        const svgNode = svg.node() as SVGSVGElement;\n        if (!svgNode) {\n            throw new Error(\"Could not create SVG Node\");\n        }\n        const svgString = new XMLSerializer().serializeToString(svgNode);\n        const blob = new Blob([svgString], { type: \"image/svg+xml\" });\n        const DOMURL = window.URL || window.webkitURL || window;\n        const url = DOMURL.createObjectURL(blob);\n        console.log(\"Created SVG Image with len \" + url.length + \" and svg XML len = \" + svgString.length);\n        return {\n            svg: svg,\n            url: url\n        }\n    }\n\n    /**\n     * Creates an SVG image from the plot\n     * @private\n     */\n    private createSvgImage(options: any) {\n        const data = this.svgInit(options);\n        data.img = new Image();\n        data.img.src = data.url;\n        return data;\n    }\n\n    /**\n     * Creates a download link and clicks it\n     * @param url\n     * @param name\n     * @private\n     */\n    private downloadClick(url: string, name: string) {\n        const downloadLink = document.createElement(\"a\");\n        downloadLink.href = url;\n        downloadLink.download = name;\n        downloadLink.click();\n\n        const DOMURL = window.URL || window.webkitURL || window;\n        DOMURL.revokeObjectURL(url);\n    }\n\n    /**\n     * Downloads the plot as an image of the given type\n     * @param type the type of image to download (png, jpeg, ...)\n     * @private\n     */\n    private toImage(options: any) {\n        const data = this.createSvgImage(options);\n        let svgSize: any;\n        if (options.width) {\n            svgSize = { width: options.width, height: options.height };\n        }\n        else {\n            svgSize = data.svg.node().getBoundingClientRect();\n        }\n        console.log(\"SVG size = \" + svgSize.width + \" x \" + svgSize.height);\n        const dl = this.downloadClick;\n        data.img.onload = function () {\n            const canvas = document.createElement('canvas');\n            canvas.width = svgSize.width;\n            canvas.height = svgSize.height;\n            data.img.width = canvas.width;\n            data.img.height = canvas.height;\n            const ctx = canvas.getContext('2d');\n            if (!ctx) {\n                return;\n            }\n            ctx.drawImage(data.img, 0, 0);\n            const imgURI = canvas\n                .toDataURL(\"image/\" + options.type);\n            // .replace(\"image/png\", \"image/octet-stream\");\n            dl(imgURI, `${options.name}.${options.type}`);\n        }\n    }\n\n    /**\n     * Downloads the plot as an SVG image\n     * @private\n     */\n    private toSvg(options: any) {\n        const data = this.svgInit(options);\n        this.downloadClick(data.url, `${options.name}.svg`);\n    }\n\n    /**\n     * Truncate text to fit within available space with ellipsis\n     * @param text Original text\n     * @param maxWidth Maximum width in pixels\n     * @param fontSize Font size in pixels\n     * @returns Truncated text with ellipsis if needed\n     */\n    public truncateTextWithEllipsis(text: string, maxWidth: number, fontSize: number): string {\n        if (maxWidth <= 0) return '';\n\n        // Estimate character width (roughly 0.6 * fontSize for most fonts)\n        const avgCharWidth = fontSize * 0.6;\n        const ellipsisWidth = avgCharWidth * 3; // Width of \"...\"\n\n        // If the text fits, return as is\n        const textWidth = text.length * avgCharWidth;\n        if (textWidth <= maxWidth) {\n            return text;\n        }\n\n        // Calculate how many characters we can fit including ellipsis\n        const availableWidthForText = maxWidth - ellipsisWidth;\n        const maxChars = Math.floor(availableWidthForText / avgCharWidth);\n\n        if (maxChars <= 0) {\n            return '...';\n        }\n\n        return text.substring(0, maxChars) + '...';\n    }\n\n    /**\n     * Apply text shadow and positioning for bar chart labels\n     * @param textSelection D3 selection of text elements\n     */\n    public applyBarLabelStyling(textSelection: any): void {\n        textSelection\n            // A solid white outline (painted under the glyphs) keeps labels readable on any bar color\n            .style('paint-order', 'stroke')\n            .style('stroke', 'rgba(255,255,255,0.9)')\n            .style('stroke-width', '3px')\n            .style('stroke-linejoin', 'round')\n            .style('pointer-events', 'all')  // Enable mouse interactions for tooltips\n            .style('cursor', 'pointer');      // Show pointer cursor on hover\n    }\n\n    /**\n     * Whether on-bar labels should be drawn for bands of the given thickness.\n     * 'auto' (default) skips labels that would be physically unreadable.\n     */\n    public shouldRenderBarLabels(bandSize: number, minReadable: number): boolean {\n        const mode = this.customOptions?.barLabels ?? 'auto';\n        if (mode === 'never') return false;\n        if (mode === 'always') return true;\n        return bandSize >= minReadable;\n    }\n\n    /**\n     * Get the text anchor and alignment settings for bar labels\n     * @param isVertical Whether this is for a vertical bar chart (rotated text)\n     * @returns Object with text-anchor and dominant-baseline values\n     */\n    public getBarLabelAlignment(isVertical = false): { textAnchor: string; dominantBaseline: string } {\n        const align = this.customOptions?.align || \"start\";\n\n        if (isVertical) {\n            // For vertical bars (rotated -90 degrees), alignment logic is inverted\n            switch (align) {\n                case \"start\":\n                    return { textAnchor: \"end\", dominantBaseline: \"central\" };\n                case \"middle\":\n                    return { textAnchor: \"middle\", dominantBaseline: \"central\" };\n                case \"end\":\n                    return { textAnchor: \"start\", dominantBaseline: \"central\" };\n                default:\n                    return { textAnchor: \"end\", dominantBaseline: \"central\" };\n            }\n        } else {\n            // For horizontal bars (normal text)\n            switch (align) {\n                case \"start\":\n                    return { textAnchor: \"start\", dominantBaseline: \"central\" };\n                case \"middle\":\n                    return { textAnchor: \"middle\", dominantBaseline: \"central\" };\n                case \"end\":\n                    return { textAnchor: \"end\", dominantBaseline: \"central\" };\n                default:\n                    return { textAnchor: \"start\", dominantBaseline: \"central\" };\n            }\n        }\n    }\n\n    /**\n     * Calculate simple label position for bar charts\n     * @param barBounds Object with bar positioning info\n     * @param plotBounds Object with plot area bounds\n     * @param textBounds Object with text dimensions\n     * @param isVertical Whether this is for vertical bars\n     * @returns Object with x and y coordinates for label placement\n     */\n    public calculateBarLabelPosition(\n        barBounds: { left: number; right: number; top: number; bottom: number; center: { x: number; y: number } },\n        plotBounds: { left: number; right: number; top: number; bottom: number },\n        textBounds: { width: number; height: number },\n        isVertical = false\n    ): { x: number; y: number } {\n        const align = this.customOptions?.align || \"start\";\n        const margin = 5; // Small margin from bar edges\n\n        if (isVertical) {\n            // For vertical bars, position horizontally at bar center, vertically based on alignment\n            const x = barBounds.center.x;\n            let y: number;\n\n            switch (align) {\n                case \"start\":\n                    // For rotated text, \"start\" means top of the bar\n                    y = Math.max(plotBounds.top + textBounds.height / 2 + margin, barBounds.top + margin);\n                    break;\n                case \"end\":\n                    // For rotated text, \"end\" means bottom of the bar\n                    y = Math.min(plotBounds.bottom - textBounds.height / 2 - margin, barBounds.bottom - margin);\n                    break;\n                case \"middle\":\n                default:\n                    // Center in the bar or plot area\n                    y = barBounds.center.y;\n                    break;\n            }\n\n            // Ensure text stays within plot bounds\n            y = Math.max(plotBounds.top + textBounds.height / 2, Math.min(plotBounds.bottom - textBounds.height / 2, y));\n            return { x, y };\n        } else {\n            // For horizontal bars, position vertically at bar center, horizontally based on alignment\n            const y = barBounds.center.y;\n            let x: number;\n\n            switch (align) {\n                case \"start\":\n                    // Start at the beginning of the bar or plot area\n                    x = Math.max(plotBounds.left + margin, barBounds.left + margin);\n                    break;\n                case \"end\":\n                    // End at the end of the bar or plot area\n                    x = Math.min(plotBounds.right - margin, barBounds.right - margin);\n                    break;\n                case \"middle\":\n                default:\n                    // Center in the bar\n                    x = barBounds.center.x;\n                    break;\n            }\n\n            // Ensure text stays within plot bounds, respecting the text anchor\n            // (a start-anchored label extends to the right of x, not around it)\n            switch (align) {\n                case \"start\":\n                    x = Math.max(plotBounds.left + margin, Math.min(plotBounds.right - textBounds.width - margin, x));\n                    break;\n                case \"end\":\n                    x = Math.max(plotBounds.left + textBounds.width + margin, Math.min(plotBounds.right - margin, x));\n                    break;\n                default:\n                    x = Math.max(plotBounds.left + textBounds.width / 2, Math.min(plotBounds.right - textBounds.width / 2, x));\n            }\n            return { x, y };\n        }\n    }\n\n    /**\n     * Clamp text position to stay within plot boundaries\n     * @param position Current position\n     * @param textLength Estimated text length\n     * @param minBound Minimum boundary\n     * @param maxBound Maximum boundary\n     * @param isVertical Whether this is vertical positioning\n     * @returns Clamped position\n     */\n    private clampTextPosition(position: number, textLength: number, minBound: number, maxBound: number, isVertical = false): number {\n        const halfLength = textLength / 2;\n\n        if (isVertical) {\n            // For vertical text, check bounds differently\n            return Math.max(minBound + halfLength, Math.min(maxBound - halfLength, position));\n        } else {\n            // For horizontal text\n            return Math.max(minBound + halfLength, Math.min(maxBound - halfLength, position));\n        }\n    }\n\n    /**\n     * Combines small items in categorical data based on grouping options\n     */\n    public groupSmallItems<T extends any[]>(\n        data: T,\n        getValue: (item: T[0]) => number,\n        getLabel: (item: T[0]) => string,\n        setLabel: (item: T[0], label: string) => T[0],\n        setValue: (item: T[0], value: number) => T[0],\n        groupOptions?: MyD3CustomOptions['groupSmallItems']\n    ): T {\n        if (!groupOptions || (!groupOptions.maxItems && !groupOptions.minPercentage)) {\n            return data;\n        }\n\n        const sortedData = [...data].sort((a, b) => getValue(b) - getValue(a));\n        const groupLabel = groupOptions.groupLabel || 'Others';\n        const totalValue = sortedData.reduce((sum, item) => sum + getValue(item), 0);\n\n        let itemsToKeep: T[0][] = [];\n        let itemsToGroup: T[0][] = [];\n\n        // Apply minimum percentage threshold\n        if (groupOptions.minPercentage !== undefined && totalValue > 0) {\n            for (const item of sortedData) {\n                const percentage = (getValue(item) / totalValue) * 100;\n                if (percentage >= groupOptions.minPercentage) {\n                    itemsToKeep.push(item);\n                } else {\n                    itemsToGroup.push(item);\n                }\n            }\n        } else {\n            itemsToKeep = sortedData;\n        }\n\n        // Apply maximum items limit\n        if (groupOptions.maxItems !== undefined && itemsToKeep.length > groupOptions.maxItems) {\n            const keepItems = itemsToKeep.slice(0, groupOptions.maxItems);\n            const groupItems = itemsToKeep.slice(groupOptions.maxItems);\n            itemsToKeep = keepItems;\n            itemsToGroup = [...itemsToGroup, ...groupItems];\n        }\n\n        // Create grouped item if needed\n        if (itemsToGroup.length > 0) {\n            const groupedValue = itemsToGroup.reduce((sum, item) => sum + getValue(item), 0);\n\n            // Use the first item as template and modify its values\n            const groupedItem: any = setValue(setLabel(itemsToGroup[0], groupLabel), groupedValue);\n\n            // Ensure the grouped item has a hue property for rendering\n            // If the first item doesn't have a hue, assign a neutral one\n            if (groupedItem.hue === undefined || groupedItem.hue === null) {\n                groupedItem.hue = 0; // Gray color for grouped items\n            }\n\n            // Store grouped children information for enhanced tooltips\n            groupedItem._groupedChildren = itemsToGroup.map(item => ({\n                label: getLabel(item),\n                value: getValue(item),\n                percentage: totalValue > 0 ? (getValue(item) / totalValue) * 100 : 0\n            }));\n            (groupedItem as any)._isGroupedItem = true;\n\n            itemsToKeep.push(groupedItem);\n        }\n\n        return itemsToKeep as T;\n    }\n}\n\nexport { MyD3, MyPlotVisuals, MyD3CustomOptions, TooltipContext, TooltipTraceData };\n","import type { MyD3CustomOptions, PlotData } from \"../myd3/types\";\n\nexport interface InlaPanelRow {\n    x: number;\n    y: number;\n    ymin: number;\n    ymax: number;\n    y_der: number;\n    y_dermin: number;\n    y_dermax: number;\n    sig: \"increasing\" | \"decreasing\" | \"not significant\" | string;\n}\n\n/**\n * MyD3 options for the component panels (p0/p1/p2). Since the 2026-08-14\n * emission change (inla_hurdle.R) these carry raw response scales — P(occupied),\n * P(colony|occ), animals per colony — not a 1.0-indexed trend. So: fit the\n * y-axis to the data instead of forcing the classic 0–2 index frame (keeping\n * the zero floor), pad the top so the CI band clears the frame, and drop the\n * y=1.0 index guide, which has no meaning on these scales. The indexed panels\n * (p12/p123) keep the MyD3 defaults. Legacy emissions (all five panels indexed,\n * no meta.raw_component_panels) still render correctly with these options —\n * the axis simply fits the indexed curve.\n */\nexport const RAW_SCALE_PANEL_OPTIONS: MyD3CustomOptions = {\n    yIncludeValues: [0],\n    yPadTopRatio: 0.05,\n    hideUnityLine: true,\n};\n\n// Matches myd3/utils/significance.ts: 1 -> increase colour, 2 -> decrease, 0/other -> full colour.\nexport const SIG_TO_INT: Record<string, number> = {\n    \"increasing\": 1,\n    \"decreasing\": 2,\n    \"not significant\": 0,\n};\n\n// Palette matches the canonical HGAM trace (bats/plotter/compute/cc_plotbuilder.py:188-189).\nconst INCREASE = \"#16a34a\";\nconst DECREASE = \"#dc2626\";\n// Neutral hue for \"not significant\" segments and the CI band — the account slate-500\n// (--color-text-muted) so the figure reads as native to the dashboard palette.\nconst NEUTRAL = \"#64748b\";\n\n/**\n * Hue (0-360) -> \"#rrggbb\".\n *\n * MyD3 resolves `style.color` through PlotModel.applyColorHex, whose regex accepts\n * ONLY a 6-digit hex — an `hsl()`/`hsla()` string is silently ignored and the trace\n * falls back to the hue-derived default (blue). Callers tinting a trace from a hue\n * must convert here first.\n */\nexport function hueToHex(hue: number, s = 0.7, l = 0.45): string {\n    const h = ((hue % 360) + 360) % 360;\n    const c = (1 - Math.abs(2 * l - 1)) * s;\n    const x = c * (1 - Math.abs(((h / 60) % 2) - 1));\n    const m = l - c / 2;\n    const seg = Math.floor(h / 60) % 6;\n    const rgb = [\n        [c, x, 0], [x, c, 0], [0, c, x], [0, x, c], [x, 0, c], [c, 0, x],\n    ][seg];\n    const hex = (v: number) =>\n        Math.round((v + m) * 255).toString(16).padStart(2, \"0\");\n    return `#${hex(rgb[0])}${hex(rgb[1])}${hex(rgb[2])}`;\n}\n\n/**\n * Pick, for every integer year covered by the panel, the row closest to it.\n *\n * On grids emitted in multiplier mode (inla_hurdle.R, year_grid_m > 0) the integer\n * years are exact grid members, so this reduces to an exact extraction. Legacy\n * 18-point grids only contain the two endpoint years — nearest-row snapping keeps\n * those rows' tooltips approximately placed (the curve is smooth, so the y at\n * x=2006.06 is visually the y at 2006) until the row is recomputed.\n */\nfunction rowPerYear(panel: InlaPanelRow[]): Map<number, InlaPanelRow> {\n    const best = new Map<number, InlaPanelRow>();\n    for (const row of panel) {\n        const year = Math.round(row.x);\n        const prev = best.get(year);\n        if (!prev || Math.abs(row.x - year) < Math.abs(prev.x - year)) {\n            best.set(year, row);\n        }\n    }\n    return best;\n}\n\n/**\n * Turn one INLA trend panel (p0/p1/p2/p12/p123) into a MyD3 \"trend\" PlotData.\n *\n * Two traces, mirroring the server-side HGAM pattern (D3PlotHelperGamCC.init_plot):\n * - the LINE trace: every grid point, per-segment significance colouring at the\n *   grid's full resolution, `hideFocus` so it never answers hover — the fine grid\n *   would otherwise put fractional years in the tooltip header.\n * - the YEAR trace: one row per integer year (see rowPerYear), `hideGraph` so it\n *   draws nothing — it exists solely to give the tooltip integer-year snap points\n *   and, when `opts.sitesPerYear` is provided, the per-year site count.\n *\n * The filled 95% CI band renders from ciLow/ciHigh via AreaRenderable\n * (visuals.showErrorArea is on by default). We map the emitted ymin/ymax to those\n * columns. We do NOT set keyRteLow/keyRteHigh: those drive a separate error-bar-lines\n * overlay reading rteVal/rteLow/rteHigh, which the hurdle trend does not use.\n *\n * `opts.color` collapses all three colours onto one flat hue. Overlaying several\n * sources in the compare tool needs each source to read as a single identifiable\n * line, which per-segment significance colouring would defeat. Omit it and the\n * significance palette applies as normal.\n *\n * It must be a 6-digit hex — see hueToHex above for why.\n */\nexport function inlaTrendToTraces(\n    panel: InlaPanelRow[],\n    opts: { title?: string; color?: string; sitesPerYear?: Record<string, number> } = {},\n): PlotData {\n    const style = {\n        // color drives the neutral line segments + CI band; colors.increase/decrease\n        // recolour the locally-significant segments (myd3/utils/significance.ts).\n        color: opts.color || NEUTRAL,\n        colors: opts.color\n            ? { increase: opts.color, decrease: opts.color }\n            : { increase: INCREASE, decrease: DECREASE },\n    };\n\n    const lineH = [\"year\", \"y\", \"ciLow\", \"ciHigh\", \"significance\"];\n    const lineR = panel.map((row) => [\n        row.x,\n        row.y,\n        row.ymin,\n        row.ymax,\n        SIG_TO_INT[row.sig] ?? 0,\n    ]);\n    const lineTrace = {\n        title: opts.title || \"\",\n        settings: {\n            type: \"trend\",\n            keyX: \"year\",\n            keyY: \"y\",\n            hideFocus: true,\n            style,\n        },\n        items: { h: lineH, r: lineR },\n    };\n\n    const hasSites = opts.sitesPerYear !== undefined;\n    const yearH = [\"year\", \"y\", \"ciLow\", \"ciHigh\", \"significance\"];\n    if (hasSites) yearH.push(\"nbSites\");\n    const yearR: number[][] = [];\n    for (const [year, row] of [...rowPerYear(panel).entries()].sort((a, b) => a[0] - b[0])) {\n        const r = [\n            year,\n            row.y,\n            row.ymin,\n            row.ymax,\n            SIG_TO_INT[row.sig] ?? 0,\n        ];\n        // 0 when the year is absent from the map — same fallback the HGAM builder\n        // uses (cc_plotbuilder.py: sites_per_year miss -> 0).\n        if (hasSites) r.push(opts.sitesPerYear![String(year)] ?? 0);\n        yearR.push(r);\n    }\n    const yearTrace = {\n        title: opts.title || \"\",\n        settings: {\n            type: \"trend\",\n            keyX: \"year\",\n            keyY: \"y\",\n            hideGraph: true,\n            style,\n        },\n        items: { h: yearH, r: yearR },\n    };\n\n    return { traces: [lineTrace, yearTrace] };\n}\n","/**\n * Merges the per-observation-type payloads from the plotter API (response.obsPlots,\n * see bats/plotter/api.py::_build_all_obs_type_plots) into a single MyD3 PlotData for\n * the \"all in one\" trend layout.\n *\n * Deliberately plain JS with the INLA converter injected: this keeps the module free\n * of build-step dependencies so `node --test` can exercise it directly, and keeps\n * merging separable from conversion.\n */\n\n/**\n * Per-type line identity. The base observation type (matching `baseObsId` — it is\n * the one the map and the species header describe) keeps a solid line; the rest are\n * dashed so overlapping trends stay tellable apart at a glance. If `baseObsId` is\n * absent or contributes no traces, the first contributing type in the requested\n * order keeps the solid line instead.\n */\nexport const OBS_TYPE_STYLE = {\n  W: { hue: 210, dash: '8,4' },\n  S: { hue: 30, dash: '8,4' },\n  SBB: { hue: 280, dash: '2,3' },\n  SEC: { hue: 130, dash: '6,3' },\n};\n\nconst DEFAULT_STYLE = { hue: 0, dash: '4,4' };\n\n/** Traces for one type, already titled but not yet styled. */\nfunction tracesFor(payload, label, inlaToTraces) {\n  const plot = payload && payload.plot;\n  if (!plot) return [];\n  if (plot.type === 'inla') {\n    const panel = plot.trend && plot.trend.panels && plot.trend.panels.p123;\n    if (!panel) return [];\n    return inlaToTraces(panel, { title: label, sitesPerYear: plot.sites_per_year }).traces;\n  }\n  if (!plot.traces) return [];\n  // Deep copy: the same payload also feeds the side-by-side layout and the sources\n  // card, which must keep the server's own styling.\n  return JSON.parse(JSON.stringify(plot.traces)).map((trace) => ({\n    ...trace,\n    title: trace.title ? `${trace.title} (${label})` : label,\n  }));\n}\n\nexport function mergeObsPlots(obsPlots, order, labels, inlaToTraces, baseObsId) {\n  // Pre-compute per-type traces so we know, up front, which types actually\n  // contribute — needed both to resolve the fallback (first contributing type)\n  // and to decide whether the requested baseObsId is usable.\n  const byId = {};\n  // Carry the backend's top-level plot.settings (e.g. `zoom`) through the merge —\n  // take it from the first source plot in `order` that has one. It is chart-wide\n  // config, not per-series, so any contributing type is an equally valid donor.\n  // (Note the merged chart draws INLA sources through inlaToTraces, which builds a\n  // wholly new plot object — so an INLA plot can donate its `settings` here, but on\n  // the single/grid paths a backend `settings.zoom` never survives that adapter.)\n  let settings;\n  for (const obsId of order) {\n    const plot = obsPlots && obsPlots[obsId] && obsPlots[obsId].plot;\n    if (plot && plot.settings) {\n      settings = plot.settings;\n      break;\n    }\n  }\n  for (const obsId of order) {\n    const label = (labels && labels[obsId]) || obsId;\n    const own = tracesFor(obsPlots && obsPlots[obsId], label, inlaToTraces);\n    if (own.length) byId[obsId] = own;\n  }\n\n  let solidId = (baseObsId && byId[baseObsId]) ? baseObsId : null;\n  if (!solidId) {\n    for (const obsId of order) {\n      if (byId[obsId]) {\n        solidId = obsId;\n        break;\n      }\n    }\n  }\n\n  const traces = [];\n  for (const obsId of order) {\n    const own = byId[obsId];\n    if (!own) continue;\n    const style = OBS_TYPE_STYLE[obsId] || DEFAULT_STYLE;\n    const isSolid = obsId === solidId;\n    for (const trace of own) {\n      trace.settings = trace.settings || {};\n      trace.settings.style = { ...(trace.settings.style || {}) };\n      // PlotModel.applyStyle applies hsva first, then lets an explicit style.color\n      // (and its `colors` sibling) override the whole derived palette. INLA traces\n      // (inlaTrendToTraces.ts) always carry a `color`/`colors` pair, which would\n      // silently defeat the merge hue below — drop them so hsva actually wins.\n      delete trace.settings.style.color;\n      delete trace.settings.style.colors;\n      trace.settings.style.hsva = [style.hue, 1, 1, 1];\n      if (!isSolid) trace.settings.style.dashArray = style.dash;\n      traces.push(trace);\n    }\n  }\n  // Always 'TG': the backend serves single trend plots as that type, and MyD3 keys\n  // per-trace tooltip labels (and TG significance styling) off plot.type — dropping\n  // it here would leave the merged tooltip rows unlabelled.\n  const merged = { type: 'TG', traces };\n  if (settings) merged.settings = settings;\n  return merged;\n}\n","import {defineStore} from 'pinia'\n\nexport const useTrendsStore = defineStore('trends', {\n  state: () => ({\n    com: null,\n    user: null,\n    /**\n     * the plot settings object manages all the sane possible choices and the current settings for the trends page\n     */\n    plotSettings: null,\n\n    speciesDict: {},\n\n    // /**\n    //  * all the column definitions, for descriptors etc.\n    //  */\n    // columnDefs: null,\n    // /**\n    //  * a map holding all the species with the id (Mmyo, Mnat ...) as key\n    //  */\n    // species: null,\n    // /**\n    //  * all the statuses\n    //  */\n    // statuses: null,\n    // obervationTypes: null,\n    //\n    // /**\n    //  * holds all the suppliers (sources)\n    //  */\n    // suppliers: null,\n    // /**\n    //  * for plot options; holds all the sane possibilities for the selectors\n    //  */\n    // possibleChoices: null,\n    // plotOptions: null,\n    // sourceFiles: null,\n    // /**\n    //  * a summary of all the source files (summed up values) stored in the structure of an actual source file.\n    //  */\n    // sumupSourceFile: null,\n    // locations: null,\n  }),\n})\n","import script from \"./MyBase.vue?vue&type=script&lang=js\"\nexport * from \"./MyBase.vue?vue&type=script&lang=js\"\n\nconst __exports__ = script;\n\nexport default __exports__","<script>\nimport {defineComponent} from 'vue';\nimport {useTrendsStore} from \"@/store/trends\";\n\nexport default defineComponent({\n  data: function (){\n    return {\n      mStore: null,\n    }\n  },\n  // mounted: function() {\n  //   return;\n  // },\n  methods: {\n    _getStore() {\n      if (!this.mStore){\n        this.mStore = useTrendsStore();\n      }\n      return this.mStore;\n    },\n  },\n  computed: {\n    store: function () {\n      return this._getStore();\n    },\n    accountComponent: function () {\n      return this.store.accountComponent;\n    },\n    user: function () {\n      return this.store.user;\n    },\n  }\n});\n</script>\n","// Single source of truth on the frontend for which trend model a request uses.\n// The obs type carries its own default (backend obs_type.py `default_plot_model`,\n// surfaced through the observationTypes payload). The admin \"more options\" model\n// picker is an explicit override that wins when present.\n\nexport interface ObsTypeLike {\n    default_plot_model?: string | null;\n}\n\nexport function resolvePlotModel(\n    observationType: ObsTypeLike | null | undefined,\n    opts: { adminOverride?: string | null } = {},\n): string {\n    if (opts.adminOverride) { return opts.adminOverride; }\n    return (observationType && observationType.default_plot_model) || \"HGAM\";\n}\n","import {ApiUtil} from \"@/lib/ApiCom\";\nimport {resolvePlotModel} from \"@/lib/inla/resolvePlotModel\";\n\nclass PossibleChoices{\n\n}\n\n\nclass MyPlotSettings{\n    ////\n    // HELPER CONSTANTS\n    ////\n    // readonly $t: any;\n    component: any;\n    readonly allRegions: any;\n    readonly mapRegion: any;\n\n    constructor(component: any) {\n        // this.$t = vueTranslator;\n        this.component = component;\n        this.allRegions = {id:-1, name: component.$t('plotOptions.allRegions')};\n        this.mapRegion = {id:-2, name: component.$t('plotOptions.mapSection')};\n    }\n\n    ////\n    //  DATA CONTAINERS\n    ////\n    /**\n     * a map holding all the species with the id (Mmyo, Mnat ...) as key\n     * comes from the server, and is stored as is\n     */\n    speciesDict: any = null;\n    // speciesTitles: any = null;\n    observationTypes: any = {};\n    bioGeoRegions: any = {};\n    geoRegions1: any = {};\n    geoRegions2: any = {};\n    geoRegions3: any = {};\n    geoAdministrativeRegions: any = {};\n    mapBounds: any = null;\n    /** grid square sizes (km) available on the server, e.g. [10, 20, 30, 40, 50] */\n    availableGridSizes: number[] = [];\n    /** whether TK25 map-sheet aggregation can be offered as a grid alternative */\n    tk25Available = false;\n    /** obs type the server opens with (admin-configurable; W until set) */\n    defaultObservationTypeId = 'W';\n\n\n    ////\n    //  SELECTION / CURRENT SETTINGS\n    ////\n    /**\n     * the currently selected species with all it's info.\n     */\n    species: any = null;\n    /**\n     * the currently selected observation type\n     */\n    observationType: any = null;\n    /**\n     * the currently selected region\n     */\n    selectedRegion: any = null;\n    /**\n     * the year that was selected as starting year\n     */\n    yearStart = 2000;\n    /**\n     * the year that was selected as the end year\n     */\n    yearEnd = 2020;\n\n    ////\n    //  POSSIBLE CHOICES / what's available for selection\n    ////\n    /**\n     * the minimum year that's possible for the current options\n     */\n    yearMin = 2000;\n    /**\n     * the maximum year that's possible for the current options\n     */\n    yearMax = 2020;\n    /**\n     * filtered count types for the selection\n     */\n    availableCountTypes: any[] = [];\n    /**\n     * filtered observation types for the selection\n     */\n    availableObservationTypes: any[] = [];\n    /**\n     * filtered biogeo regions for the selection\n     */\n    availableBiogeo: any[] = [];\n    /**\n     * filtered geo1 regions for the selection\n     */\n    availableGeo1: any[] = [];\n    avalaibleGeoAdm: any[] = [];\n\n\n    ////\n    // MORE OPTIONS\n    ////\n    showLocations = false;\n    showSquares = true;\n    squareSize = 20;\n    /** map aggregation: arbitrary km grid ('grid') or TK25 map sheets ('tk25') */\n    mapAggregation: 'grid' | 'tk25' = 'grid';\n    showDistribution = true;\n    /**\n     * how the trend card presents observation types:\n     *  'single'   — one plot for `observationType` (default)\n     *  'combined' — every viewable type merged into one plot\n     *  'grid'     — one plot per viewable type, side by side\n     */\n    obsLayout: 'single' | 'combined' | 'grid' = 'single';\n    filterDate = false;\n    filterDateMonthStart = 12;\n    filterDateMonthEnd = 2;\n    filterDateIncludeNulls = false;\n    trimModel = 2;\n    trimSerialCorrelation = true;\n    trimOverdispersion = true;\n    trimTotals = false;\n    trimCovariateGeo = false;\n    trimChangepointsAll = false;\n    trimStepwise = false;\n    minCountsPerSite = 0;\n    fillYearGaps = true;\n\n    /** basemap tile source; see MyMap.createTileLayer for the URL/attribution table */\n    mapLayer = 'OSM';\n\n    // ---- Layer styling (client-only; never serialized to/from the server) ----\n    // Colours are explicit hex values from a native colour picker. MyMap resolves\n    // `fill` to a graduated light→base ramp when shading by count, and uses `border`\n    // as the independent cell outline — see map.ts.\n    /**\n     * observation cells. `fill`/`border` are the primary colours (used as-is when not\n     * graduated, and as the high-count end of the gradient). `fillTo`/`borderTo` are the\n     * low-count end of the count-shading gradient. `gradientMode` is the blend colour\n     * space, `gradientInvert` swaps the low/high ends.\n     */\n    mapStyleSite = {\n        fill: '#000000', fillTo: '#ffffff',\n        border: '#000000', borderTo: '#000000',\n        opacity: 0.55, weight: 1,\n        graduated: false, gradientMode: 'oklch', gradientInvert: false,\n        // cells whose every site was surveyed without ever holding the species\n        noDetectionFill: '#dc3545',\n    };\n    /** official FFH species range polygon */\n    mapStyleDistribution = {fill: '#dc2626', opacity: 0.3, weight: 0};\n    /** how strongly the area outside the selected region is dimmed (0.15–0.75) */\n    mapStyleRegionDim = 0.5;\n\n    /** immutable defaults so \"Reset styling\" can restore them */\n    static readonly MAP_STYLE_DEFAULTS = {\n        mapStyleSite: {\n            fill: '#000000', fillTo: '#ffffff',\n            border: '#000000', borderTo: '#000000',\n            opacity: 0.55, weight: 1,\n            graduated: false, gradientMode: 'oklch', gradientInvert: false,\n            // cells whose every site was surveyed without ever holding the species\n            noDetectionFill: '#dc3545',\n        },\n        mapStyleDistribution: {fill: '#dc2626', opacity: 0.3, weight: 0},\n        mapStyleRegionDim: 0.5,\n    };\n\n    resetMapStyle(){\n        const d = MyPlotSettings.MAP_STYLE_DEFAULTS;\n        this.mapStyleSite = {...d.mapStyleSite};\n        this.mapStyleDistribution = {...d.mapStyleDistribution};\n        this.mapStyleRegionDim = d.mapStyleRegionDim;\n    }\n\n\n    emitChange(data: any = undefined){\n        // this.component.$emit('settingsChanged', data);\n        console.warn(\"EMIT CHANGE NOT IMPLEMENTED\")\n    }\n    /**\n     * handles a server response and populates everything\n     * @param json the server response\n     */\n    handleResponse(json: any){\n        if (json.species) {\n            ApiUtil.addKeyToMapItemsAsId(json.species);\n            this.speciesDict = json.species;\n            this.observationTypes = ApiUtil.listToMapWithIdAsKey(json.observationTypes);\n            this.bioGeoRegions = ApiUtil.listToMapWithIdAsKey(json.biogeo);\n            for (const idx in this.bioGeoRegions) this.bioGeoRegions[idx].type = 'b';\n            this.geoAdministrativeRegions = ApiUtil.listToMapWithIdAsKey(json.geoadm);\n            for (const idx in this.geoAdministrativeRegions) this.geoAdministrativeRegions[idx].type = 'a';\n            this.geoRegions1 = ApiUtil.listToMapWithIdAsKey(json.geo1);\n            this.geoRegions2 = ApiUtil.listToMapWithIdAsKey(json.geo2);\n            this.geoRegions3 = ApiUtil.listToMapWithIdAsKey(json.geo3);\n        }\n\n        if (json.gridSizes)\n            this.availableGridSizes = json.gridSizes;\n        if (json.tk25Available != null)\n            this.tk25Available = json.tk25Available;\n        if (json.defaultObservationType)\n            this.defaultObservationTypeId = json.defaultObservationType;\n\n        if (json.possible_choices){\n            this.availableCountTypes = this.filterAvailable(this.speciesDict, json.possible_choices.count_types, 'latin');\n            this.availableObservationTypes = this.filterAvailable(this.observationTypes, json.possible_choices.obs_types, 'name');\n            this.availableBiogeo = this.filterAvailable(this.bioGeoRegions, json.possible_choices.biogeo_ids, 'name');\n            this.availableGeo1 = this.filterAvailable(this.geoRegions1, json.possible_choices.geo1_ids, 'name');\n            this.avalaibleGeoAdm = this.filterAvailable(this.geoAdministrativeRegions, json.possible_choices.geoadm_ids, 'name');\n            if (json.possible_choices.year_min != null) this.yearMin = json.possible_choices.year_min;\n            if (json.possible_choices.year_max != null) this.yearMax = json.possible_choices.year_max;\n        }\n        else{\n            console.warn(\"No possible choices!\");\n        }\n\n\n        if (! this.observationType){\n            this.observationType = this.observationTypes[this.defaultObservationTypeId]\n                || this.observationTypes['W'];\n        }\n        if (! this.selectedRegion){\n            this.selectedRegion = this.allRegions;\n        }\n\n        if (json.plot_options){\n            this.species = this.speciesDict[json.plot_options.species];\n            this.observationType = this.observationTypes[json.plot_options.observationType];\n\n            // Reflect a deep-linked region (backend set biogeo/geo1/geoadm) in the\n            // dropdown. Without this the plot is correct but the picker shows \"all\".\n            const po = json.plot_options;\n            if (po.biogeo != null) {\n                this.selectedRegion = this.bioGeoRegions[po.biogeo] || this.allRegions;\n            } else if (po.geo1 != null) {\n                this.selectedRegion = this.geoRegions1[po.geo1] || this.allRegions;\n            } else if (po.geoadm != null) {\n                this.selectedRegion = this.geoAdministrativeRegions[po.geoadm] || this.allRegions;\n            } else {\n                this.selectedRegion = this.allRegions;\n            }\n\n            this.yearStart = json.plot_options.yearStart;\n            this.yearEnd = json.plot_options.yearEnd;\n\n            this.showLocations = json.plot_options.showLocations;\n            this.showSquares = json.plot_options.showSquares;\n            this.squareSize = json.plot_options.squareSize;\n            if (json.plot_options.mapAggregation === 'grid' || json.plot_options.mapAggregation === 'tk25')\n                this.mapAggregation = json.plot_options.mapAggregation;\n            this.showDistribution = json.plot_options.showDistribution;\n            this.filterDate = json.plot_options.filterDate;\n            this.filterDateMonthStart = json.plot_options.filterDateMonthStart;\n            this.filterDateMonthEnd = json.plot_options.filterDateMonthEnd;\n            this.filterDateIncludeNulls = json.plot_options.filterDateIncludeNulls;\n            this.trimModel = json.plot_options.trimModel;\n            this.trimSerialCorrelation = json.plot_options.trimSerialCorrelation;\n            this.trimOverdispersion = json.plot_options.trimOverdispersion;\n            this.trimTotals = json.plot_options.trimTotals;\n            this.trimCovariateGeo = json.plot_options.trimCovariateGeo;\n            this.trimChangepointsAll = json.plot_options.trimChangepointsAll;\n            this.trimStepwise = json.plot_options.trimStepwise;\n            this.minCountsPerSite = json.plot_options.minCountsPerSite;\n            this.fillYearGaps = json.plot_options.fillYearGaps;\n        }\n        else{\n            console.warn(\"No options!\");\n        }\n\n        if (! this.species){\n            console.warn(\"No species selected.\");\n        }\n        console.log(\"MyPlotSettings::handleResponse - species id is \" + this.species?.id);\n    }\n\n    buildOptions() : any {\n        // The selected observation type is the single source of truth for the trend model\n        // (SBB -> INLA, everything else -> HGAM). See resolvePlotModel.\n        const options: any = {\n            plotModel: resolvePlotModel(this.observationType)\n        }\n        if (this.species) options.species = this.species.id;\n        if (this.observationType) options.observationType = this.observationType.id;\n        if (this.selectedRegion){\n            if (this.selectedRegion.id > 0){\n                if (this.selectedRegion.type === 'b'){\n                    options.biogeo = this.selectedRegion.id;\n                }\n                else{\n                    options.geo1 = this.selectedRegion.id;\n                }\n            }\n            else if (this.selectedRegion.id === -2){\n                options.geoBounds = this.mapBounds;\n            }\n            else if (isNaN(this.selectedRegion.id)){\n                if (this.selectedRegion.type === 'a'){\n                    options.geoadm = this.selectedRegion.id;\n                }\n            }\n        }\n        options.yearStart = this.yearStart;\n        options.yearEnd = this.yearEnd;\n\n        //extra options\n        if (this.canUseMoreOptions()) {\n            if (this.filterDate) {\n                options.filterDate = this.filterDate;\n                options.filterDateStart = this.filterDateMonthStart;\n                options.filterDateEnd = this.filterDateMonthEnd;\n                options.filterDateIncludeNulls = this.filterDateIncludeNulls;\n            }\n            options.trimOverdispersion = this.trimOverdispersion;\n            options.trimSerialCorrelation = this.trimSerialCorrelation;\n            options.trimCovariateGeo = this.trimCovariateGeo;\n            options.trimModel = this.trimModel;\n            options.trimTotals = this.trimTotals;\n            options.trimStepwise = this.trimStepwise;\n            options.trimChangepointsAll = this.trimChangepointsAll;\n            options.showLocations = this.showLocations;\n            options.showSquares = this.showSquares;\n            options.squareSize = this.squareSize;\n            options.mapAggregation = this.mapAggregation;\n            options.showDistribution = this.showDistribution;\n            options.fillYearGaps = this.fillYearGaps;\n            options.minCountsPerSite = this.minCountsPerSite;\n            // Multi-type layouts make the server build every viewable type. Admin-only\n            // by construction: this whole block is gated on canUseMoreOptions().\n            options.obsLayout = this.obsLayout;\n        }\n        return options;\n    }\n\n    /**\n     * call this method, when the map bounds have changed\n     * @param bounds leaflet bounds object\n     * @returns {boolean} true if the map bounds have changed\n     */\n    updateMapBounds(bounds: any) : boolean{\n        const oldBounds = this.mapBounds;\n        this.mapBounds = bounds;\n        if (bounds){\n            this.selectedRegion = this.mapRegion;\n            if (this.selectedRegion){ //} && this.selectedRegion.id === this.mapRegion.id) {\n                return true;\n            }\n        }\n        else{\n            if (this.selectedRegion?.id === this.mapRegion?.id) {\n                this.selectedRegion = this.allRegions;\n            }\n            if (oldBounds) return true;\n        }\n        return false;\n    }\n\n    /**\n     * filters the available items from the map, and returns a sorted list\n     * @param map the map containing all the items\n     * @param available the list of the keys that should be filtered\n     * @param sort the field that should be used for sorting\n     * @private\n     */\n    private filterAvailable(map: any, available: any, sort: string){\n        const list = [];\n        for (const idx in available){\n            const key = available[idx];\n            const item = map[key];\n            if (item){\n                list.push(item);\n            }\n        }\n        return list.sort(function (a, b){\n            // return (a[sort].localeCompare(b[sort]));\n            return (a[sort]?.localeCompare(b[sort] ?? '') ?? 0);\n        });\n    }\n\n    private canUseMoreOptions(){\n        const user = this.component.store.user;\n        if (user){\n            if (user.isAdmin){\n                return true;\n            }\n        }\n        return false;\n    }\n\n    get effectiveYearMax(){\n        const currentYear = new Date().getFullYear();\n        return this.yearMax != null ? Math.min(this.yearMax, currentYear) : currentYear;\n    }\n\n    yearsMin(){\n        const cap = this.effectiveYearMax;\n        let v = Math.floor(this.yearMin / 10) * 10;\n        const years = [];\n        while (v < cap){\n            years.push(v);\n            v += 10;\n        }\n        return years;\n    }\n\n    yearsMax(){\n        const effectiveMax = this.effectiveYearMax;\n        const addByModZero = (effectiveMax % 10) == 0 ? 0 : 1;\n        const maxV = Math.floor(effectiveMax / 10 + addByModZero) * 10;\n        let v = Math.floor(this.yearMin / 10 + 1) * 10;\n        const years = [];\n        while (v <= maxV){\n            years.push(v);\n            v += 10;\n        }\n        if (years.length > 0 && years[years.length - 1] > effectiveMax) {\n            years[years.length - 1] = effectiveMax;\n        }\n        return years;\n    }\n}\n\nexport {MyPlotSettings}","// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport Leaflet from \"leaflet\";\n\n/** Upper-bound edges of the graduated site-count classes; 5 classes total. */\nconst COUNT_BIN_LABELS = ['1', '2–3', '4–7', '8–15', '16+'];\nfunction countBinIndex(nb: number): number {\n    if (nb <= 1) return 0;\n    if (nb <= 3) return 1;\n    if (nb <= 7) return 2;\n    if (nb <= 15) return 3;\n    return 4;\n}\n\n// ---- Colour interpolation. The count-shading gradient blends a low-count colour into\n// a high-count colour; the blend space (RGB/HSL/LAB/LCH/OKLCH) changes how the midtones\n// travel. OKLCH is perceptually smooth; RGB can go muddy. ----\ntype RGB = [number, number, number];\nfunction hexToRgb(hex: string): RGB {\n    let h = (hex || '').replace('#', '');\n    if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n    const n = parseInt(h || '000000', 16);\n    return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\nfunction rgbToHex(r: number, g: number, b: number): string {\n    const c = (v: number) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0');\n    return '#' + c(r) + c(g) + c(b);\n}\nconst lerp = (a: number, b: number, t: number) => a + (b - a) * t;\n/** Interpolate an angle (degrees) along the shorter arc. */\nfunction lerpHue(a: number, b: number, t: number): number {\n    const d = ((b - a) % 360 + 540) % 360 - 180;\n    return ((a + d * t) % 360 + 360) % 360;\n}\n// sRGB companding (0..255 <-> linear 0..1)\nconst toLin = (c: number) => { c /= 255; return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4); };\nconst toSrgb = (c: number) => (c <= 0.0031308 ? c * 12.92 : 1.055 * Math.pow(c, 1 / 2.4) - 0.055) * 255;\nfunction rgbToXyz([r, g, b]: RGB): RGB {\n    const R = toLin(r), G = toLin(g), B = toLin(b);\n    return [R * 0.4124 + G * 0.3576 + B * 0.1805, R * 0.2126 + G * 0.7152 + B * 0.0722, R * 0.0193 + G * 0.1192 + B * 0.9505];\n}\nfunction xyzToRgb([x, y, z]: RGB): RGB {\n    return [toSrgb(x * 3.2406 + y * -1.5372 + z * -0.4986), toSrgb(x * -0.9689 + y * 1.8758 + z * 0.0415), toSrgb(x * 0.0557 + y * -0.2040 + z * 1.0570)];\n}\nconst _f = (t: number) => (t > 0.008856 ? Math.cbrt(t) : 7.787 * t + 16 / 116);\nconst _fi = (t: number) => { const t3 = t * t * t; return t3 > 0.008856 ? t3 : (t - 16 / 116) / 7.787; };\nfunction xyzToLab([x, y, z]: RGB): RGB {\n    const fx = _f(x / 0.95047), fy = _f(y), fz = _f(z / 1.08883);\n    return [116 * fy - 16, 500 * (fx - fy), 200 * (fy - fz)];\n}\nfunction labToXyz([L, a, b]: RGB): RGB {\n    const fy = (L + 16) / 116, fx = fy + a / 500, fz = fy - b / 200;\n    return [0.95047 * _fi(fx), _fi(fy), 1.08883 * _fi(fz)];\n}\nfunction labToLch([L, a, b]: RGB): RGB { const C = Math.hypot(a, b); let H = Math.atan2(b, a) * 180 / Math.PI; if (H < 0) H += 360; return [L, C, H]; }\nfunction lchToLab([L, C, H]: RGB): RGB { const h = H * Math.PI / 180; return [L, C * Math.cos(h), C * Math.sin(h)]; }\nfunction rgbToOklab([r, g, b]: RGB): RGB {\n    const R = toLin(r), G = toLin(g), B = toLin(b);\n    const l = Math.cbrt(0.4122214708 * R + 0.5363325363 * G + 0.0514459929 * B);\n    const m = Math.cbrt(0.2119034982 * R + 0.6806995451 * G + 0.1073969566 * B);\n    const s = Math.cbrt(0.0883024619 * R + 0.2817188376 * G + 0.6299787005 * B);\n    return [0.2104542553 * l + 0.7936177850 * m - 0.0040720468 * s, 1.9779984951 * l - 2.4285922050 * m + 0.4505937099 * s, 0.0259040371 * l + 0.7827717662 * m - 0.8086757660 * s];\n}\nfunction oklabToRgb([L, A, B]: RGB): RGB {\n    const l = (L + 0.3963377774 * A + 0.2158037573 * B) ** 3;\n    const m = (L - 0.1055613458 * A - 0.0638541728 * B) ** 3;\n    const s = (L - 0.0894841775 * A - 1.2914855480 * B) ** 3;\n    return [toSrgb(4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s), toSrgb(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s), toSrgb(-0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s)];\n}\nfunction rgbToHsl([r, g, b]: RGB): RGB {\n    r /= 255; g /= 255; b /= 255;\n    const max = Math.max(r, g, b), min = Math.min(r, g, b), d = max - min, l = (max + min) / 2;\n    let h = 0, s = 0;\n    if (d) { s = l > 0.5 ? d / (2 - max - min) : d / (max + min); h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4; h *= 60; }\n    return [h, s, l];\n}\nfunction hslToRgb([h, s, l]: RGB): RGB {\n    h = ((h % 360) + 360) % 360 / 360; s = Math.max(0, Math.min(1, s)); l = Math.max(0, Math.min(1, l));\n    const q = l < 0.5 ? l * (1 + s) : l + s - l * s, p = 2 * l - q;\n    const hk = (t: number) => { t = (t % 1 + 1) % 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; return p; };\n    return [hk(h + 1 / 3) * 255, hk(h) * 255, hk(h - 1 / 3) * 255];\n}\n/** Blend two hex colours at t (0..1) in the requested colour space. */\nfunction interpolate(hexA: string, hexB: string, t: number, mode: string): string {\n    const ca = hexToRgb(hexA), cb = hexToRgb(hexB), hx = (c: RGB) => rgbToHex(c[0], c[1], c[2]);\n    if (mode === 'hsl') { const A = rgbToHsl(ca), B = rgbToHsl(cb); return hx(hslToRgb([lerpHue(A[0], B[0], t), lerp(A[1], B[1], t), lerp(A[2], B[2], t)])); }\n    if (mode === 'lab') { const A = xyzToLab(rgbToXyz(ca)), B = xyzToLab(rgbToXyz(cb)); return hx(xyzToRgb(labToXyz([lerp(A[0], B[0], t), lerp(A[1], B[1], t), lerp(A[2], B[2], t)]))); }\n    if (mode === 'lch') { const A = labToLch(xyzToLab(rgbToXyz(ca))), B = labToLch(xyzToLab(rgbToXyz(cb))); return hx(xyzToRgb(labToXyz(lchToLab([lerp(A[0], B[0], t), lerp(A[1], B[1], t), lerpHue(A[2], B[2], t)])))); }\n    if (mode === 'oklch') { const A = labToLch(rgbToOklab(ca)), B = labToLch(rgbToOklab(cb)); return hx(oklabToRgb(lchToLab([lerp(A[0], B[0], t), lerp(A[1], B[1], t), lerpHue(A[2], B[2], t)]))); }\n    return hx([lerp(ca[0], cb[0], t), lerp(ca[1], cb[1], t), lerp(ca[2], cb[2], t)]); // rgb\n}\n/** Colour for a normalised count position (0 = low, 1 = high) along the gradient. */\nfunction gradientColorAt(low: string, high: string, t: number, mode: string, invert: boolean): string {\n    return interpolate(low, high, invert ? 1 - t : t, mode);\n}\n/** The five class colours for the legend / count bins. */\nfunction gradientSteps(low: string, high: string, mode: string, invert: boolean): string[] {\n    return [0, 1, 2, 3, 4].map(i => gradientColorAt(low, high, i / 4, mode, invert));\n}\n\nclass Geo{\n    public static RADIUS_EARTH_KM = 6371;\n    public static RADIUS_EARTH_MI = 3958.8;\n    public static CENTER_LAT_GERMANY = 51.1638175\n    public static deg2rad(deg: number): number {\n        return deg * (Math.PI/180);\n    }\n    public static haversine(lat1: number, lon1: number, lat2:number, lon2:number): number {\n        const R = Geo.RADIUS_EARTH_KM;\n        const rlat1 = Geo.deg2rad(lat1);\n        const rlat2 = Geo.deg2rad(lat2);\n        const difflat = rlat2 - rlat1;\n        const difflon = Geo.deg2rad(lon2 - lon1);\n        return 2 * R * Math.asin(Math.sqrt(Math.sin(difflat/2)*Math.sin(difflat/2)+Math.cos(rlat1)*Math.cos(rlat2)*Math.sin(difflon/2)*Math.sin(difflon/2)));\n    }\n}\nclass SquaresHelper {\n    centerLat: number;\n    squareSizeInKm: number;\n    squareSizeLat: number;\n    squareSizeLon: number;\n    offsetX: number;\n    offsetY: number;\n\n    constructor(squareSizeInKm: number) {\n        this.centerLat = Geo.CENTER_LAT_GERMANY;\n        this.squareSizeInKm = squareSizeInKm;\n\n        //  you can calculate the distance for the latitude right away.\n        const dstY = Geo.haversine(this.centerLat, 0.0, this.centerLat + 0.1, 0.0)\n        this.squareSizeLat = (this.squareSizeInKm / dstY) * 0.1\n        //  actually you need to calculate the square size of the longitude individually, but we simplify it with squares\n        const dstX = Geo.haversine(this.centerLat, 0.0, this.centerLat, 0.1);\n        this.squareSizeLon = (this.squareSizeInKm / dstX) * 0.1\n\n        const nbLon = Math.ceil(180.0 / dstX)\n        const nbLat = Math.ceil(90.0 / dstY)\n        this.offsetX = nbLon * this.squareSizeLon;\n        this.offsetY = nbLat * this.squareSizeLat;\n        // this.offsetY = 0.0;\n        // this.offsetX = 0.0;\n    }\n    coordsByIndex(indexLat: number, indexLon: number): number[]{\n        const lat = indexLat * this.squareSizeLat - this.offsetY;\n        const lon = indexLon * this.squareSizeLon - this.offsetX;\n        return [lat, lon];\n    }\n}\nclass MyMap {\n    /** the helper that handles resolving indices to actual GPS coordinates */\n    squaresHelper: SquaresHelper;\n    /** the Vue component */\n    component: any;\n    /** the id of the map element */\n    idMap: string;\n    /** the Leaflet map */\n    map: any;\n    /** the layer holding the distribution of the bats */\n    distributionLayer: any;\n    /** the layer holding the geometry data of the selected region */\n    regionLayer: any;\n    /** the layer holding the observations of the bats */\n    squaresLayer: any;\n    /** the layer holding per-site location markers */\n    locationsLayer: any;\n    /** the legend */\n    legendDiv: any;\n    /** the tile layer holding the map tiles*/\n    layer: any;\n    tmpLayer: string;\n\n    /** the button control holds the drag and select button */\n    dragAndSelectButtonContainer: any;\n    infoControl: any;\n    infoDiv: any;\n\n    // dragAndSelectButton: any;\n    // dragAndSelect = false;\n    // dragAndSelectStarted = false;\n    // dragAndSelectStartPos: Leaflet.LatLng = Leaflet.latLng(0,0);\n    // /** the selection rectangle (for drag&select) */\n    // selectRectangle: Leaflet.Rectangle;\n    // /** used to darken the world outside the selected area */\n    // outerWorldBounds: Leaflet.Polygon;\n    //\n    // callbackSelectRectangle: any;\n\n    /** for some reason, i need to use the method this way to work. can't define it the regular way */\n    // dnsDown = (e: Leaflet.LeafletMouseEvent) => {\n    //     if (this.dragAndSelect) {\n    //         // selectRectangle.setBounds([e.latlng, e.latlng]);\n    //         this.dragAndSelectStarted = true;\n    //         this.dragAndSelectStartPos = e.latlng;\n    //         this.selectRectangle.setBounds([e.latlng, e.latlng]);\n    //     }\n    // };\n    // dnsUp = (e: Leaflet.LeafletMouseEvent) => {\n    //     if (this.dragAndSelect){\n    //         if (this.dragAndSelectStarted) {\n    //             this.updateSelectRectangle(e.latlng);\n    //             const bounds = this.selectRectangle.getBounds();\n    //             this.dragAndSelectStarted = false;\n    //             this.dragAndSelect = false;\n    //             this.createOuterWorldBounds();\n    //             this.removeDragAndSelectRect();\n    //\n    //             const div: HTMLElement = Leaflet.DomUtil.create('div');\n    //\n    //             div.innerHTML += '<svg class=\"me-2\" width=\"32\" height=\"32\"><use xlink:href=\"#bi-bounding-box\"/></svg>';\n    //             const button: HTMLAnchorElement = Leaflet.DomUtil.create(\"a\", \"fs-6 me-2\", div);\n    //             button.innerText = this.component.$t('trends.clearSelection');\n    //             button.href = \"#\";\n    //             Leaflet.DomEvent.on(button, \"click\", (e: Leaflet.DomEvent.Event) => {\n    //                 Leaflet.DomEvent.stopPropagation(e);\n    //                 Leaflet.DomEvent.preventDefault(e);\n    //                 this.deleteSelection();\n    //                 this.centerMap();\n    //             });\n    //\n    //             const button2: HTMLAnchorElement = Leaflet.DomUtil.create(\"a\", \"fs-6\", div);\n    //             button2.innerText = this.component.$t('trends.zoomInArea');\n    //             button2.href = \"#\";\n    //             Leaflet.DomEvent.on(button2, \"click\", (e: Leaflet.DomEvent.Event) => {\n    //                 Leaflet.DomEvent.stopPropagation(e);\n    //                 Leaflet.DomEvent.preventDefault(e);\n    //                 this.map.fitBounds(bounds);\n    //             });\n    //\n    //             this.showInfo(div);\n    //             // this.map.fitBounds(this.selectRectangle.getBounds());\n    //             if (this.callbackSelectRectangle){\n    //                 this.callbackSelectRectangle(bounds);\n    //             }\n    //         }\n    //         this.setDragAndSelect(false);\n    //     }\n    // }\n    // dnsMove = (e: Leaflet.LeafletMouseEvent) => {\n    //     if (this.dragAndSelect && this.dragAndSelectStarted) {\n    //         this.updateSelectRectangle(e.latlng);\n    //         e.originalEvent.preventDefault();\n    //     }\n    // }\n\n    constructor(component: any){\n        this.idMap = component.idMap;\n        this.component = component;\n        this.tmpLayer = this.settings.mapLayer;\n        this.squaresHelper = new SquaresHelper(this.settings.squareSize);\n    }\n\n    /**\n     * Rebuilds the index→coordinate helper for a new grid cell size. Server-side squares\n     * arrive as grid indices, so the helper must match the size the server gridded at,\n     * otherwise reconstructed squares/markers are misplaced.\n     */\n    setSquareSize(sizeInKm: number){\n        if (! sizeInKm) return;\n        if (this.squaresHelper && this.squaresHelper.squareSizeInKm === sizeInKm) return;\n        this.squaresHelper = new SquaresHelper(sizeInKm);\n    }\n\n    create(){\n        if (this.map){\n            return;\n        }\n        const options = {\n            center: [51.5, 10],\n            zoom: 5.0,\n            zoomSnap: 0.25,\n            // Keep the default SVG renderer for vector layers: the canvas renderer\n            // bitmap-scales during Leaflet's fractional-zoom animation and drifts out\n            // of sync with the tiles. The PNG export rasterises the SVG overlay instead.\n            // minZoom: 4.0,\n            // maxZoom: 7.0,\n            // zoomControl: false\n            // zoomAnimation: false,\n            // fadeAnimation: false,\n        };\n        if (! document.getElementById(this.idMap)){\n            console.warn(\"Oh no! No map element found!\");\n            return;\n        }\n        const map = new Leaflet.map(this.idMap, options);\n\n\n\n        this.map = map;\n        this.createTileLayer();\n        this.createInfoControl();\n        // Legend before the tool buttons: within the top-right corner Leaflet stacks\n        // controls in add order, so the legend sits above the download/fullscreen buttons.\n        this.createLegend();\n        this.createControls();\n        // this.updateUI();\n    }\n\n    /** True when this frame's data comes from an import that records complete surveys. */\n    hasCompleteSurvey(): boolean {\n        return !!this.component?.siteStats?.has_complete_survey;\n    }\n\n    /** Style resolvers: turn the colour settings into concrete Leaflet path options. */\n    styleForCell(nbLoc: number, nbLocPos?: number): any {\n        const s = this.settings.mapStyleSite;\n        // A cell where every site was surveyed and none ever held the species is a\n        // result, not a gap -- flag it instead of shading it by site count. Strict\n        // === 0: undefined means a legacy cell with no information, and must not match.\n        if (this.hasCompleteSurvey() && nbLocPos === 0) {\n            return {\n                color: s.noDetectionFill,\n                weight: s.weight,\n                opacity: 1,\n                fillColor: s.noDetectionFill,\n                fillOpacity: s.opacity,\n            };\n        }\n        let fill = s.fill, border = s.border;\n        if (s.graduated) {\n            const t = countBinIndex(nbLoc) / 4;\n            // `fillTo`/`borderTo` are the low-count end; the primary colour is the high-count end.\n            fill = gradientColorAt(s.fillTo, s.fill, t, s.gradientMode, s.gradientInvert);\n            border = gradientColorAt(s.borderTo, s.border, t, s.gradientMode, s.gradientInvert);\n        }\n        return {\n            color: border,\n            weight: s.weight,\n            opacity: 1,\n            fillColor: fill,\n            fillOpacity: s.opacity,\n        };\n    }\n    styleForDistribution(): any {\n        const s = this.settings.mapStyleDistribution;\n        return {\n            color: s.fill,\n            weight: s.weight,\n            opacity: 1,\n            fillColor: s.fill,\n            fillOpacity: s.opacity,\n        };\n    }\n    styleForRegionMask(): any {\n        return {color: '#000000', weight: 0, opacity: 0, fillColor: '#000000', fillOpacity: this.settings.mapStyleRegionDim};\n    }\n\n    /**\n     * Live-restyle the region mask (e.g. when the dimming slider moves) without a refetch\n     * or refit. No-op when no region is selected — there is nothing to dim on the full map.\n     */\n    updateRegionStyle(){\n        if (this.regionLayer && this.regionLayer.setStyle) {\n            this.regionLayer.setStyle(this.styleForRegionMask());\n        }\n    }\n\n    /** Standard orientation/utility controls: scale bar, recenter, fullscreen, export. */\n    createControls(){\n        Leaflet.control.scale({imperial: false, position: 'bottomright'}).addTo(this.map);\n\n        const makeButton = (title: string, iconHref: string, onClick: () => void) => {\n            const ctl = Leaflet.control({position: 'topright'});\n            ctl.onAdd = () => {\n                const div: HTMLElement = Leaflet.DomUtil.create('div', 'leaflet-bar leaflet-control map-tool');\n                const a: HTMLAnchorElement = Leaflet.DomUtil.create('a', '', div);\n                a.href = '#';\n                a.title = title;\n                a.setAttribute('role', 'button');\n                a.setAttribute('aria-label', title);\n                a.innerHTML = '<svg width=\"18\" height=\"18\" aria-hidden=\"true\"><use xlink:href=\"#' + iconHref + '\"/></svg>';\n                Leaflet.DomEvent.on(a, 'click', (e: any) => {\n                    Leaflet.DomEvent.stopPropagation(e);\n                    Leaflet.DomEvent.preventDefault(e);\n                    onClick();\n                });\n                return div;\n            };\n            ctl.addTo(this.map);\n        };\n\n        makeButton(this.t('trends.mapTools.recenter', 'Recenter'), 'bi-geo-alt', () => this.centerMap());\n        makeButton(this.t('trends.mapTools.fullscreen', 'Fullscreen'), 'bi-arrows-fullscreen', () => this.toggleFullscreen());\n        makeButton(this.t('trends.mapTools.exportImage', 'Export image'), 'bi-download', () => this.exportPng());\n\n        // Leaving fullscreen must restore the pre-fullscreen size. resizedFn sizes the map\n        // as Math.max(clientHeight, width*0.7), so a fullscreen-inflated inline height would\n        // stick (the max never shrinks). Clear the inline heights first so resizedFn\n        // recomputes from the CSS-driven size, then run the normal resize path.\n        document.addEventListener('fullscreenchange', () => {\n            if (! document.fullscreenElement) {\n                const elmMap = document.getElementById(this.idMap);\n                if (elmMap) elmMap.style.height = '';\n                const plotId = this.component?.getPlotId?.();\n                const elmPlot = plotId ? document.getElementById(plotId) : null;\n                if (elmPlot) elmPlot.style.height = '';\n            }\n            if (this.component?.resizedListener) this.component.resizedListener();\n        });\n    }\n\n    /** Small i18n helper: use the component translator when present, else a fallback string. */\n    t(key: string, fallback: string): string {\n        try {\n            const v = this.component?.$t ? this.component.$t(key) : null;\n            return (v && v !== key) ? v : fallback;\n        } catch (e) {\n            return fallback;\n        }\n    }\n\n    toggleFullscreen(){\n        const el = this.map?.getContainer?.();\n        if (! el) return;\n        // Resizing is handled by the fullscreenchange listener (component.resizedListener),\n        // which recomputes the height once the container has settled at its new size.\n        if (! document.fullscreenElement) {\n            if (el.requestFullscreen) el.requestFullscreen().catch(() => { /* unsupported/blocked */ });\n        } else {\n            document.exitFullscreen();\n        }\n    }\n\n    // updateUI(){\n    //     if (this.component?.store?.plotSettings?.plotMode === 'CLASSIC') {\n    //         this.createDragAndSelect();\n    //         // this.createDragAndSelectRect();\n    //     }\n    //     else{\n    //         this.removeDragAndSelectButton();\n    //         this.deleteSelection();\n    //         // this.removeDragAndSelectRect();\n    //     }\n    // }\n\n    centerMap(){\n        if (! this.map) return;\n        const corner1 = Leaflet.latLng(47.3, 5.8),\n            corner2 = Leaflet.latLng(55.1, 15.1),\n            bounds = Leaflet.latLngBounds(corner1, corner2);\n        this.map.fitBounds(bounds);\n    }\n\n    get settings(){\n        return this.component.$refs.settings.settings;\n    }\n\n    /**\n     * Available basemaps. `crossOrigin: 'anonymous'` is set on every tile layer so the\n     * PNG export can draw tiles onto a canvas without tainting it; OSM, Carto and Esri\n     * all send permissive CORS headers. OpenTopoMap may not, so exporting on Topo can\n     * fall back to the \"no basemap\" path — handled gracefully in exportPng().\n     */\n    static readonly BASEMAPS: Record<string, any> = {\n        OSM: {\n            url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',\n            attribution: '© OpenStreetMap contributors', maxZoom: 19,\n        },\n        Carto: {\n            url: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png',\n            attribution: '© OpenStreetMap contributors © CARTO', subdomains: 'abcd', maxZoom: 20,\n        },\n        ArcGIS: {\n            url: 'https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',\n            attribution: 'Sources: Esri, HERE, Garmin, © OpenStreetMap contributors, and the GIS User Community', maxZoom: 16,\n        },\n        Topo: {\n            url: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',\n            attribution: '© OpenStreetMap contributors, SRTM | © OpenTopoMap (CC-BY-SA)', maxZoom: 17,\n        },\n        Satellite: {\n            url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',\n            attribution: 'Source: Esri, Maxar, Earthstar Geographics, and the GIS User Community', maxZoom: 19,\n        },\n    };\n\n    createTileLayer(){\n        if (this.layer && this.tmpLayer === this.settings.mapLayer) {\n            return; // unchanged\n        }\n        const cfg = MyMap.BASEMAPS[this.settings.mapLayer] || MyMap.BASEMAPS.OSM;\n        const options: any = {\n            attribution: cfg.attribution,\n            maxZoom: cfg.maxZoom,\n            crossOrigin: 'anonymous',\n        };\n        if (cfg.subdomains) options.subdomains = cfg.subdomains;\n\n        if (this.layer) {\n            this.map.removeLayer(this.layer);\n        }\n        this.layer = new Leaflet.TileLayer(cfg.url, options);\n        this.tmpLayer = this.settings.mapLayer;\n        this.layer.addTo(this.map);\n        this.layer.bringToBack();\n    }\n\n    createInfoControl(){\n        const ctl = Leaflet.control({position: 'bottomleft'});\n        ctl.onAdd = (map: any) => {\n            ctl._addedToMap = true;\n            // const div: HTMLElement = Leaflet.DomUtil.create('div', 'leaflet-bar leaflet-control map-info fs-5');\n            const div: HTMLElement = Leaflet.DomUtil.create('div', 'map-info fs-5');\n            this.infoDiv = div;\n            return div;\n        };\n        ctl.onRemove = (map: any) => {\n            ctl._addedToMap = false;\n        };\n        this.infoControl = ctl;\n        this.infoControl.addTo(this.map);\n    }\n\n    showInfo(content: any){\n        if (! this.infoControl) return;\n        this.infoDiv.innerHTML = '';\n        if (! this.infoControl._addedToMap)\n            this.infoControl.addTo(this.map);\n        if (typeof content === 'string' && content.length > 0)\n            this.infoDiv.innerHTML = content;\n        else if (content instanceof HTMLElement){\n            this.infoDiv.appendChild(content);\n        }\n    }\n    hideInfo(){\n        if (! this.infoControl) return;\n        if (this.infoControl._addedToMap)\n            this.infoControl.remove();\n    }\n\n    /** Builds the legend HTML from current settings + the data in memory. */\n    legendHtml(): string {\n        const settings = this.settings;\n        const rows: string[] = [];\n\n        // Observation cells: graduated scale (with counts) or a single swatch.\n        if (settings.showSquares) {\n            const squares = this.component?.squares || [];\n            const nbCells = squares.length;\n            const nbSites = this.component?.nbLocations || 0;\n            const obsLabel = this.component.$t('trends.observations');\n            if (settings.mapStyleSite.graduated) {\n                const ms = settings.mapStyleSite;\n                const steps = gradientSteps(ms.fillTo, ms.fill, ms.gradientMode, ms.gradientInvert);\n                const borderSteps = gradientSteps(ms.borderTo, ms.border, ms.gradientMode, ms.gradientInvert);\n                rows.push('<div class=\"lg-title\">' + obsLabel + '</div>');\n                const scale = COUNT_BIN_LABELS.map((lbl, i) =>\n                    '<span class=\"lg-bin\"><i style=\"background:' + steps[i] + ';border-color:' +\n                    borderSteps[i] + '\"></i>' + lbl + '</span>').join('');\n                rows.push('<div class=\"lg-scale\">' + scale + '</div>');\n                rows.push('<div class=\"lg-sub\">' + this.t('trends.mapTools.sitesPerCell', 'sites per cell') + '</div>');\n            } else {\n                rows.push('<div class=\"lg-row\"><i class=\"lg-sw\" style=\"background:' +\n                    settings.mapStyleSite.fill + ';border-color:' + settings.mapStyleSite.border +\n                    '\"></i><span>' + obsLabel + '</span></div>');\n            }\n            const nbNoDetection = squares.filter((sq: any) => sq.nb_loc_pos === 0).length;\n            if (this.hasCompleteSurvey() && nbNoDetection) {\n                rows.push('<div class=\"lg-row\"><i class=\"lg-sw\" style=\"background:' +\n                    settings.mapStyleSite.noDetectionFill + ';border-color:' +\n                    settings.mapStyleSite.noDetectionFill + '\"></i><span>' +\n                    this.t('trends.mapTools.noDetection', 'no detections') + '</span></div>');\n            }\n            rows.push('<div class=\"lg-count\">' +\n                this.t('trends.mapTools.cellsCount', 'cells') + ': ' + nbCells + ' · ' +\n                this.component.$tc('trends.sites', {n: nbSites}) + '</div>');\n        }\n\n        // Distribution range swatch.\n        if (settings.showDistribution) {\n            rows.push('<div class=\"lg-row\"><i class=\"lg-sw\" style=\"background:' +\n                settings.mapStyleDistribution.fill + '\"></i><span>' +\n                this.component.$t('trends.distribution') + '</span></div>');\n        }\n        return rows.join('');\n    }\n\n    createLegend(){\n        const html = this.legendHtml();\n        if (this.legendDiv) {\n            this.legendDiv.innerHTML = html;\n            return;\n        }\n        const legend = Leaflet.control({position: 'topright'});\n        legend.onAdd = () => {\n            const div = Leaflet.DomUtil.create('div', 'map-legend');\n            div.innerHTML = html;\n            this.legendDiv = div;\n            return div;\n        };\n        legend.addTo(this.map);\n    }\n\n    /**\n     * Rasterise the current map to a PNG the admin can drop into a report. Composites\n     * the loaded basemap tiles and the vector canvas (cells / distribution / markers)\n     * onto one bitmap — no extra library — then draws a legend and attribution.\n     * Needs CORS-enabled tiles (set in createTileLayer); if the basemap tainted the\n     * canvas we surface a hint instead of a broken download.\n     */\n    exportPng(){\n        const container: HTMLElement | undefined = this.map?.getContainer?.();\n        if (! container) return;\n        const cRect = container.getBoundingClientRect();\n        const dpr = window.devicePixelRatio || 1;\n        const w = Math.round(cRect.width);\n        const h = Math.round(cRect.height);\n\n        const canvas = document.createElement('canvas');\n        canvas.width = w * dpr;\n        canvas.height = h * dpr;\n        const ctx = canvas.getContext('2d');\n        if (! ctx) return;\n        ctx.scale(dpr, dpr);\n        ctx.fillStyle = '#ffffff';\n        ctx.fillRect(0, 0, w, h);\n\n        const drawEl = (el: any) => {\n            const r = el.getBoundingClientRect();\n            if (r.width === 0 || r.height === 0) return;\n            try {\n                ctx.drawImage(el, r.left - cRect.left, r.top - cRect.top, r.width, r.height);\n            } catch (e) { /* skip an un-drawable element */ }\n        };\n\n        // Basemap tiles first.\n        container.querySelectorAll('.leaflet-tile-pane img').forEach((img: any) => {\n            if (img.complete && img.naturalWidth > 0) drawEl(img);\n        });\n\n        const finish = () => {\n            this.drawExportLegend(ctx, w, h);\n            try {\n                canvas.toBlob((blob: Blob | null) => {\n                    if (! blob) return;\n                    const url = URL.createObjectURL(blob);\n                    const a = document.createElement('a');\n                    const species = this.component?.species?.id || 'map';\n                    a.href = url;\n                    a.download = `map_${species}_${this.settings.mapAggregation}.png`;\n                    document.body.appendChild(a);\n                    a.click();\n                    document.body.removeChild(a);\n                    URL.revokeObjectURL(url);\n                }, 'image/png');\n            } catch (e) {\n                // Tainted canvas (basemap without CORS headers, e.g. Topo). Guide the admin.\n                this.showInfo(this.t('trends.mapTools.exportTainted',\n                    'Could not export this basemap. Switch to OpenStreetMap, Carto or Satellite and try again.'));\n            }\n        };\n\n        // Vector layers live in the SVG overlay pane; serialise it to an image and\n        // draw it over the tiles. It carries no external refs, so it never taints.\n        const svg = container.querySelector('.leaflet-overlay-pane svg') as SVGElement | null;\n        if (! svg) { finish(); return; }\n        const svgRect = svg.getBoundingClientRect();\n        const clone = svg.cloneNode(true) as SVGElement;\n        // Measure the on-screen box from the original (transformed) element, then strip\n        // the positioning transform on the clone so the rasterised image holds only the\n        // viewBox-mapped content — we place that content back at svgRect via drawImage.\n        (clone as any).style.transform = 'none';\n        clone.setAttribute('width', String(svgRect.width));\n        clone.setAttribute('height', String(svgRect.height));\n        const xml = new XMLSerializer().serializeToString(clone);\n        const img = new Image();\n        img.onload = () => {\n            try { ctx.drawImage(img, svgRect.left - cRect.left, svgRect.top - cRect.top, svgRect.width, svgRect.height); } catch (e) { /* ignore */ }\n            finish();\n        };\n        img.onerror = () => finish();\n        img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(xml);\n    }\n\n    /** Draws a compact legend + basemap attribution onto the export canvas. */\n    drawExportLegend(ctx: any, w: number, h: number){\n        const settings = this.settings;\n        const pad = 10;\n        const lines: Array<{sw?: string, steps?: string[], text: string, bold?: boolean}> = [];\n\n        if (settings.showSquares) {\n            if (settings.mapStyleSite.graduated) {\n                const ms = settings.mapStyleSite;\n                lines.push({text: this.component.$t('trends.observations'), bold: true});\n                lines.push({steps: gradientSteps(ms.fillTo, ms.fill, ms.gradientMode, ms.gradientInvert),\n                    text: COUNT_BIN_LABELS.join('  ')});\n            } else {\n                lines.push({sw: settings.mapStyleSite.fill,\n                    text: this.component.$t('trends.observations')});\n            }\n            const nbNoDetection = (this.component?.squares || [])\n                .filter((sq: any) => sq.nb_loc_pos === 0).length;\n            if (this.hasCompleteSurvey() && nbNoDetection) {\n                lines.push({sw: settings.mapStyleSite.noDetectionFill,\n                    text: this.t('trends.mapTools.noDetection', 'no detections')});\n            }\n        }\n        if (settings.showDistribution) {\n            lines.push({sw: settings.mapStyleDistribution.fill,\n                text: this.component.$t('trends.distribution')});\n        }\n        if (! lines.length) return;\n\n        const lineH = 18;\n        const boxW = 190;\n        const boxH = pad * 2 + lines.length * lineH;\n        const x0 = w - boxW - pad;\n        const y0 = pad;\n\n        ctx.fillStyle = 'rgba(255,255,255,0.92)';\n        ctx.strokeStyle = '#cbd5e1';\n        ctx.lineWidth = 1;\n        ctx.fillRect(x0, y0, boxW, boxH);\n        ctx.strokeRect(x0, y0, boxW, boxH);\n\n        ctx.textBaseline = 'middle';\n        ctx.font = '12px system-ui, sans-serif';\n        let y = y0 + pad + lineH / 2;\n        for (const ln of lines) {\n            let x = x0 + pad;\n            if (ln.steps) {\n                for (const c of ln.steps) {\n                    ctx.fillStyle = c;\n                    ctx.fillRect(x, y - 6, 12, 12);\n                    x += 13;\n                }\n                x += 4;\n            } else if (ln.sw) {\n                ctx.fillStyle = ln.sw;\n                ctx.fillRect(x, y - 6, 12, 12);\n                x += 18;\n            }\n            ctx.fillStyle = '#0f172a';\n            ctx.font = ln.bold ? '600 12px system-ui, sans-serif' : '12px system-ui, sans-serif';\n            ctx.fillText(ln.text, x, y);\n            y += lineH;\n        }\n\n        // Basemap attribution, bottom-left.\n        const cfg = MyMap.BASEMAPS[settings.mapLayer] || MyMap.BASEMAPS.OSM;\n        const attr = (cfg.attribution || '').replace(/<[^>]*>/g, '');\n        if (attr) {\n            ctx.font = '10px system-ui, sans-serif';\n            const tw = ctx.measureText(attr).width;\n            ctx.fillStyle = 'rgba(255,255,255,0.8)';\n            ctx.fillRect(2, h - 16, tw + 8, 14);\n            ctx.fillStyle = '#475569';\n            ctx.fillText(attr, 6, h - 9);\n        }\n    }\n\n    // createDragAndSelectRect(){\n    //     // if (this.selectRectangle){\n    //     //     this.selectRectangle.remove();\n    //     // }\n    //     this.removeDragAndSelectRect();\n    //     this.selectRectangle = Leaflet.rectangle([[0,0], [0,0]], { color: \"#000\", weight: 2, fillColor: \"#00f\", fillOpacity: 0.25 });\n    //     this.selectRectangle.addTo(this.map);\n    // }\n    // removeDragAndSelectRect(){\n    //     if (this.selectRectangle){\n    //         this.selectRectangle.remove();\n    //         this.selectRectangle = undefined;\n    //     }\n    // }\n\n    // removeDragAndSelectButton(){\n    //     if (!this.dragAndSelectButtonContainer) return;\n    //     //  remove the info panel (rect)\n    //     this.dragAndSelectButtonContainer.remove();\n    //     this.dragAndSelectButtonContainer = undefined;\n    //     //  remove the element representing the select rectangle\n    //     this.removeDragAndSelectRect();\n    //     //  remove the drag and select button\n    //     this.map.off(\"mousedown\", this.dnsDown);\n    //     this.map.off(\"mouseup\", this.dnsUp);\n    //     this.map.off(\"mousemove\", this.dnsMove);\n    // }\n    // createDragAndSelect(){\n    //     if (this.dragAndSelectButtonContainer) return;\n    //     const ctl = Leaflet.control({position: 'topleft'});\n    //     this.dragAndSelectButtonContainer = ctl;\n    //     ctl.onAdd = (map: any) => {//function (map) {\n    //         const div: HTMLElement = Leaflet.DomUtil.create('div', 'leaflet-bar leaflet-control');\n    //         const button: HTMLAnchorElement = Leaflet.DomUtil.create(\"a\", \"leaflet-control-custom\", div);\n    //         button.href = \"#\";\n    //         button.title = this.component.$t('trends.map.dragAndSelect');\n    //         button.innerHTML = '<svg class=\"bi\" width=\"24\" height=\"24\"><use xlink:href=\"#bi-bounding-box\"/></svg>';\n    //         this.dragAndSelectButton = button;\n    //\n    //         Leaflet.DomEvent.on(button, \"click\", (e: Leaflet.DomEvent.Event) => {\n    //             Leaflet.DomEvent.stopPropagation(e);\n    //             Leaflet.DomEvent.preventDefault(e);\n    //             this.setDragAndSelect(! this.dragAndSelect);\n    //         });\n    //\n    //         return div;\n    //     };\n    //     ctl.addTo(this.map);\n    //\n    //\n    //     // Handle map click event to update the drag-and-select rectangle\n    //     this.map.on(\"mousedown\", this.dnsDown);\n    //     this.map.on(\"mouseup\", this.dnsUp);\n    //     // Handle map mousemove event to update the drag-and-select rectangle during dragging\n    //     this.map.on(\"mousemove\", this.dnsMove);\n    // }\n\n    // deleteSelection(){\n    //     this.removeOuterWorldBounds();\n    //     this.removeDragAndSelectRect();\n    //     this.component.$nextTick(() => {\n    //         this.hideInfo()\n    //         if (this.callbackSelectRectangle){\n    //             this.callbackSelectRectangle(null);\n    //         }\n    //     });\n    // }\n\n    // setDragAndSelect(enabled: boolean){\n    //     this.dragAndSelect = enabled;\n    //     this.dragAndSelectStarted = false;\n    //     if (this.dragAndSelect){\n    //         this.createDragAndSelectRect();\n    //         let html = \"\";\n    //         html += '<svg class=\"bi me-2\" width=\"32\" height=\"32\"><use xlink:href=\"#bi-bounding-box\"/></svg>';\n    //         html += this.component.$t('trends.dragAndSelect');\n    //         this.showInfo(html);\n    //         this.map.dragging.disable();\n    //         this.dragAndSelectButton.style.backgroundColor = \"black\";\n    //         this.dragAndSelectButton.style.color = \"white\";\n    //     }\n    //     else{\n    //         // this.hideInfo();\n    //         this.map.dragging.enable();\n    //         this.dragAndSelectButton.style.backgroundColor = \"white\";\n    //         this.dragAndSelectButton.style.color = \"black\";\n    //     }\n    // }\n\n    // updateSelectRectangle(latlng: Leaflet.LatLng){\n    //     const minLat = Math.min(this.dragAndSelectStartPos.lat, latlng.lat);\n    //     const maxLat = Math.max(this.dragAndSelectStartPos.lat, latlng.lat);\n    //     const minLng = Math.min(this.dragAndSelectStartPos.lng, latlng.lng);\n    //     const maxLng = Math.max(this.dragAndSelectStartPos.lng, latlng.lng);\n    //     this.selectRectangle.setBounds([[minLat, minLng], [maxLat, maxLng]]);\n    // }\n\n    // createOuterWorldBounds(){\n    //     this.removeOuterWorldBounds();\n    //     const outerBounds = [\n    //         [-90, -1800],\n    //         [-90, 1800],\n    //         [90, 1800],\n    //         [90, -1800],\n    //     ];\n    //     const rectBounds = this.selectRectangle.getBounds();\n    //     const innerBounds = [\n    //         [rectBounds.getSouth(), rectBounds.getWest()],\n    //         [rectBounds.getSouth(), rectBounds.getEast()],\n    //         [rectBounds.getNorth(), rectBounds.getEast()],\n    //         [rectBounds.getNorth(), rectBounds.getWest()],\n    //     ];\n    //\n    //     this.outerWorldBounds = Leaflet.polygon([outerBounds, innerBounds], { color: '#000', opacity: 1.0, fillOpacity: 0.5 }).addTo(this.map);\n    // }\n\n    // removeOuterWorldBounds(){\n    //     if (this.outerWorldBounds){\n    //         this.outerWorldBounds.remove(this.map);\n    //     }\n    //     this.outerWorldBounds = undefined;\n    // }\n\n    // createDistributionLayer(distributionSquares: any[]){\n    //     if (!this.map) return;\n    //     // if (this.map){\n    //     //     this.map.off();\n    //     //     this.map.remove();\n    //     //     this.create();\n    //     // }\n    //     this.createTileLayer();\n    //     this.createLegend(); //this is a quick hack to make the legend update (colors change)\n    //     const settings = this.settings;\n    //     if (this.distributionLayer) {\n    //         this.map.removeLayer(this.distributionLayer);\n    //     }\n    //     if (!settings.showDistribution) return;\n    //     const allSquares = [];\n    //     const options: any = JSON.parse(JSON.stringify(settings.mapOptionsDistribution));\n    //     for (const idx in distributionSquares) {\n    //         const s = distributionSquares[idx];\n    //\n    //         const poly = this.polygonFromSquare(s, options);\n    //         if (! poly) continue;\n    //         allSquares.push(poly);\n    //     }\n    //     const distributionLayer = new Leaflet.LayerGroup(allSquares);\n    //     distributionLayer.addTo(this.map);\n    //     this.distributionLayer = distributionLayer;\n    // }\n\n    createDistributionLayerFull(geojsonData: any){\n        if (this.distributionLayer) {\n            this.map.removeLayer(this.distributionLayer);\n            this.distributionLayer = null;\n        }\n        if (!this.settings.showDistribution || ! geojsonData) return;\n\n        this.distributionLayer = Leaflet.geoJSON(geojsonData, this.styleForDistribution()).addTo(this.map);\n        if (this.distributionLayer.bringToBack) this.distributionLayer.bringToBack();\n    }\n\n    /**\n     * Renders one marker at the centre of every observation grid square. The squares\n     * are already incognito-filtered and aggregated server-side, so this stays privacy\n     * safe (no exact site coordinates are exposed). Honors the `showLocations` toggle.\n     */\n    createLocationsLayer(squares: any[]){\n        if (this.locationsLayer) {\n            this.map.removeLayer(this.locationsLayer);\n            this.locationsLayer = null;\n        }\n        if (!this.settings.showLocations || ! squares) return;\n\n        const markers = [];\n        const s = this.settings.mapStyleSite;\n        const markerOptions = {\n            radius: 4,\n            color: s.border,\n            weight: 1,\n            opacity: 1,\n            fillColor: s.fill,\n            fillOpacity: 0.9,\n        };\n        for (const idx in squares) {\n            const center = this.squareCenter(squares[idx]);\n            if (! center) continue;\n            const marker = Leaflet.circleMarker(center, markerOptions);\n            const nb = squares[idx].nb_loc;\n            if (nb != null) {\n                marker.bindPopup('<h6>' + this.component.$tc('trends.sites', {n: nb}) + '</h6>');\n            }\n            markers.push(marker);\n        }\n        this.locationsLayer = new Leaflet.LayerGroup(markers);\n        this.locationsLayer.addTo(this.map);\n    }\n\n    /** Returns the [lat, lon] centre of a grid square, from a polygon or grid indices. */\n    squareCenter(s: any): number[] | undefined {\n        if (s.polygon && s.polygon.length) {\n            let latSum = 0, lonSum = 0;\n            for (const p of s.polygon) { latSum += p[0]; lonSum += p[1]; }\n            return [latSum / s.polygon.length, lonSum / s.polygon.length];\n        }\n        if (s.i) {\n            const [lat1, lon1] = this.squaresHelper.coordsByIndex(s.i[0], s.i[1]);\n            const end = s.i2 ? [s.i2[0] + 1, s.i2[1] + 1] : [s.i[0] + 1, s.i[1] + 1];\n            const [lat2, lon2] = this.squaresHelper.coordsByIndex(end[0], end[1]);\n            return [(lat1 + lat2) / 2, (lon1 + lon2) / 2];\n        }\n        return undefined;\n    }\n\n\n    /** \"Inverts\" a json geometry by cutting holes into the world polygon. */\n    createHolesFromGeometry(geojsonData: any){\n        const outerBounds = [\n            [-90, -1800],  // Using extended longitude range like in your working code\n            [-90, 1800],\n            [90, 1800],\n            [90, -1800],\n        ];\n\n        const innerBounds: any[] = [];\n\n        const extractCoordinates = (geometry: any) => {\n            if (geometry.type === 'Polygon') {\n                // Convert from [lng, lat] to [lat, lng] for Leaflet\n                const coords = geometry.coordinates[0].map((coord: any) => [coord[1], coord[0]]);\n                innerBounds.push(coords);\n\n                // Also add any holes from the original polygon\n                for (let i = 1; i < geometry.coordinates.length; i++) {\n                    const hole = geometry.coordinates[i].map((coord: any) => [coord[1], coord[0]]);\n                    innerBounds.push(hole);\n                }\n            } else if (geometry.type === 'MultiPolygon') {\n                geometry.coordinates.forEach((polygon: any) => {\n                    // Add the outer ring\n                    const coords = polygon[0].map((coord: any) => [coord[1], coord[0]]);\n                    innerBounds.push(coords);\n\n                    // Add any holes from this polygon\n                    for (let i = 1; i < polygon.length; i++) {\n                        const hole = polygon[i].map((coord: any) => [coord[1], coord[0]]);\n                        innerBounds.push(hole);\n                    }\n                });\n            }\n        };\n\n        if (geojsonData.type === 'FeatureCollection') {\n            geojsonData.features.forEach((feature: any) => {\n                extractCoordinates(feature.geometry);\n            });\n        } else if (geojsonData.type === 'Feature') {\n            extractCoordinates(geojsonData.geometry);\n        } else {\n            // Direct geometry object\n            extractCoordinates(geojsonData);\n        }\n        return [innerBounds, outerBounds];\n    }\n    // createRegionLayer(geojsonData: any){\n    //     if (this.regionLayer) {\n    //         this.map.removeLayer(this.regionLayer);\n    //     }\n    //     if (! geojsonData) return;\n    //\n    //     // const [innerBounds, outerBounds] = this.createHolesFromGeometry(geojsonData);\n    //     // if (innerBounds.length > 0) {\n    //     //     const options: any = JSON.parse(JSON.stringify(this.settings.mapOptionsHide));\n    //     //     this.regionLayer = Leaflet.polygon([outerBounds, ...innerBounds], options).addTo(this.map);\n    //     // } else {\n    //     //     // Fallback: just create world polygon if no inner bounds\n    //     //     const options: any = JSON.parse(JSON.stringify(this.settings.mapOptionsRegion));\n    //     //     this.regionLayer = Leaflet.geoJSON(geojsonData, options).addTo(this.map);\n    //     // }\n    //\n    //     const options: any = JSON.parse(JSON.stringify(this.settings.mapOptionsRegion));\n    //     this.regionLayer = Leaflet.geoJSON(geojsonData, options).addTo(this.map);\n    // }\n\n\n    createRegionLayer(geojsonData: any){\n        if (this.regionLayer) {\n            this.map.removeLayer(this.regionLayer);\n        }\n        if (! geojsonData) {\n            this.regionLayer = null;\n            this.createLegend(); // Update legend when no region data\n            setTimeout(() => {\n                this.centerMap();\n            }, 240);\n            return;\n        }\n        // Try to render an inverse mask: darken everything outside the selected region\n        const [innerBounds, outerBounds] = this.createHolesFromGeometry(geojsonData);\n        if (innerBounds && innerBounds.length > 0) {\n            this.regionLayer = Leaflet.polygon([outerBounds, ...innerBounds], this.styleForRegionMask()).addTo(this.map);\n        }\n        else{\n            // Fallback: draw the region normally if we couldn't extract any bounds\n            this.regionLayer = Leaflet.geoJSON(geojsonData, this.styleForRegionMask()).addTo(this.map);\n        }\n        this.createLegend(); // Update legend when region layer is created\n\n        // Fit map to the bounds of the geojsonData\n        try {\n            let bounds: any = null;\n            if (innerBounds && innerBounds.length > 0) {\n                const points: Leaflet.LatLng[] = [];\n                for (const ring of innerBounds) {\n                    for (const coord of ring) {\n                        // coord is [lat, lng]\n                        points.push(Leaflet.latLng(coord[0], coord[1]));\n                    }\n                }\n                if (points.length > 0) {\n                    bounds = Leaflet.latLngBounds(points);\n                }\n            }\n            if (bounds && bounds.isValid && bounds.isValid()) {\n                // Defer the fit like the no-region centerMap() branch above:\n                // on a backend-preloaded route the map is created while its\n                // container is still hidden (v-show), so fitting immediately\n                // frames the region into a zero-sized viewport and zooms fully\n                // out. Waiting lets resizedFn() size the container first; we\n                // invalidateSize() so the fit uses its final dimensions.\n                const regionBounds = bounds;\n                setTimeout(() => {\n                    if (! this.map) return;\n                    this.map.invalidateSize();\n                    this.map.fitBounds(regionBounds);\n                }, 240);\n            }\n        } catch (err) {\n            console.warn('Could not fit map to region bounds', err);\n        }\n    }\n\n    createSitesLayer(squares: any[]){\n        const settings = this.settings;\n        if (this.squaresLayer) {\n            this.map.removeLayer(this.squaresLayer);\n        }\n\n        if (!settings.showSquares) return;\n        const allSquares = [];\n        for (const idx in squares) {\n            const s = squares[idx];\n            const baseStyle = this.styleForCell(s.nb_loc || 0, s.nb_loc_pos);\n            const poly = this.polygonFromSquare(s, baseStyle);\n            if (! poly) continue;\n\n            // Hover: lift the cell with a heavier outline, then restore its base style.\n            poly.on('mouseover', (e: any) => {\n                e.target.setStyle({weight: Math.max(2, (baseStyle.weight || 0) + 2), color: '#0f172a'});\n                if (e.target.bringToFront) e.target.bringToFront();\n            });\n            poly.on('mouseout', (e: any) => {\n                e.target.setStyle(baseStyle);\n            });\n\n            poly.bindTooltip(this.cellTooltipHtml(s), {sticky: true, direction: 'top', className: 'map-cell-tooltip'});\n            poly.bindPopup(this.cellPopupHtml(s));\n            allSquares.push(poly);\n        }\n        const squaresLayer = new Leaflet.LayerGroup(allSquares);\n        squaresLayer.addTo(this.map);\n        this.squaresLayer = squaresLayer;\n    }\n\n    /** Resolve a contributors dict {supplierId: count} to display names. */\n    contributorNames(contributors: any): string[] {\n        const names: string[] = [];\n        for (const cIdx in contributors || {}) {\n            let c = undefined;\n            for (const cmp of this.component?.contributors || []) {\n                if (cmp.id == cIdx) c = cmp;\n            }\n            names.push(c ? c.name : ('#' + cIdx));\n        }\n        return names;\n    }\n\n    /** Compact hover tooltip: TK25 sheet id as title in TK25 mode, else the site count. */\n    cellTooltipHtml(s: any): string {\n        const title = s.tk25\n            ? this.t('trends.mapTools.tk25Sheet', 'TK25 sheet') + ' ' + s.tk25\n            : this.component.$tc('trends.sites', {n: s.nb_loc});\n        let html = '<strong>' + title + '</strong>';\n        if (s.tk25) {\n            html += '<br>' + this.component.$tc('trends.sites', {n: s.nb_loc});\n        }\n        const names = this.contributorNames(s.contributors);\n        if (names.length) {\n            const shown = names.slice(0, 3).join(', ');\n            const more = names.length > 3 ? ' +' + (names.length - 3) : '';\n            html += '<br><span class=\"tt-muted\">' + shown + more + '</span>';\n        }\n        if (this.hasCompleteSurvey() && s.nb_loc_pos !== undefined) {\n            html += '<br>' + this.component.$tc('trends.sites', {n: s.nb_loc_pos}) + ' · ' +\n                this.t('trends.mapTools.withDetections', 'with detections');\n        }\n        return html;\n    }\n\n    /** Fuller click popup with the complete contributor list. */\n    cellPopupHtml(s: any): string {\n        const title = s.tk25\n            ? this.t('trends.mapTools.tk25Sheet', 'TK25 sheet') + ' ' + s.tk25\n            : this.component.$tc('trends.sites', {n: s.nb_loc});\n        let html = '<h6>' + title + '</h6>';\n        if (s.tk25) {\n            html += '<div>' + this.component.$tc('trends.sites', {n: s.nb_loc}) + '</div>';\n        }\n        html += '<div class=\"text-muted\">';\n        const names = this.contributorNames(s.contributors);\n        html += names.length ? names.join(', ') : 'No contributors';\n        html += '</div>';\n        if (this.hasCompleteSurvey() && s.nb_loc_pos !== undefined) {\n            html += '<div>' + this.component.$tc('trends.sites', {n: s.nb_loc_pos}) + ' · ' +\n                this.t('trends.mapTools.withDetections', 'with detections') + '</div>';\n        }\n        return html;\n    }\n\n    polygonFromSquare(s: any, options: any){\n        if (s.polygon) {\n            return Leaflet.polygon(s.polygon, options);\n        }\n        else if (s.i){\n            const [lat1, lon1] = this.squaresHelper.coordsByIndex(s.i[0], s.i[1]);\n            let lat2, lon2;\n            if (s.i2){\n                [lat2, lon2] = this.squaresHelper.coordsByIndex(s.i2[0] + 1, s.i2[1] + 1);\n            }\n            else{\n                [lat2, lon2] = this.squaresHelper.coordsByIndex(s.i[0] + 1, s.i[1] + 1);\n            }\n\n            const poly = [\n                [lat1, lon1],\n                [lat1, lon2],\n                [lat2, lon2],\n                [lat2, lon1]\n            ];\n            return Leaflet.polygon(poly, options);\n        }\n        return undefined;\n    }\n}\n\nexport {MyMap}","<script>\nimport {defineComponent} from 'vue';\nimport {ApiCommunication, ApiRequestBuilder} from \"@/lib/ApiCom\";\nimport {MyD3} from \"@/lib/myd3/MyD3\";\nimport {inlaTrendToTraces} from \"@/lib/inla/inlaTrendToTraces\";\nimport {mergeObsPlots} from \"@/lib/trends/mergeObsPlots\";\nimport {User} from \"@/lib/User\";\nimport MyBase from \"@/components/trends/MyBase.vue\";\nimport {MyPlotSettings} from \"@/components/trends/settings/MyPlotSettings\";\nimport {MyMap} from \"@/trends/map\";\nimport {sitesShortcutUrlForPlotOptions} from \"@/lib/siteShortcuts\";\nimport axios from \"axios\";\n\nconst ApiCom = new ApiCommunication('/api_plot');\n\nexport default defineComponent({\n  extends: MyBase,\n  data: function (){\n    return {\n      prefix: \"x\", //used for html ids etc.; prevents collisions with other components (for previewing multiple layouts)\n\n      working: true,\n      fatalError: null,\n      loadingInfoTexts: [],\n\n      map: null,\n      plotSettings: null,\n\n      //  these are obsolete. actually you should use the plotsettings (below)\n      //  TODO: make them computed props\n      species: null,\n      speciesTitles: null,\n      //  these are obsolete. actually you should use the plotsettings (above)\n\n      squares: [],\n      locations: [],\n      contributors:[],\n      nbLocations: 0,\n      nbCounts: 0,\n      siteStats: null,\n\n      plot: null,\n      plotError: null,\n      overall: null,\n      summary: null,\n      timings: null,\n      gof: null,\n      isInla: false,\n      obsPlots: null,\n    };\n  },\n  created: function() {\n    if (! this.store.plotSettings){\n      this.store.plotSettings = new MyPlotSettings(this);\n    }\n    window.addEventListener(\"resize\", this.resizedListener);\n  },\n  unmounted: function() {\n    window.removeEventListener(\"resize\", this.resizedListener);\n  },\n  mounted() {\n    this.createMap();\n    this.resizedListener();\n    if (window.trendData){\n      // Django pre-injects trendData into the page, bypassing ApiCom entirely.\n      // Since no API request is made, ApiCom's request tracking won't reset working.\n      this.handleResponse(window.trendData);\n      this.working = false;\n    }\n  },\n  methods: {\n    resizedListener: function(){\n      if (this.resizeTimeoutId){\n        clearTimeout(this.resizeTimeoutId);\n      }\n      this.resizeTimeoutId = setTimeout(this.resizedFn, 150);\n    },\n    resizedFn: function(){\n      const elmMap = document.getElementById(this.idMap);\n      const elmMap2 = document.getElementById(\"box2\");\n      // Absent in the side-by-side layout, where each type owns its own container\n      // and takes its height from CSS.\n      const elmPlot = document.getElementById(this.getPlotId());\n      // Size from the empty-state box while it exists, from the map otherwise.\n      const basis = elmMap2 || elmMap;\n      if (basis) {\n        // Clear our own previous inline height before measuring, so clientHeight\n        // reflects the CSS-intended height (e.g. the map's 45vh). Measuring with\n        // the inline height in place ratchets: a height computed in the\n        // no-species empty state would override the CSS forever and could\n        // never shrink again.\n        basis.style.height = '';\n        const w = basis.clientWidth;\n        // Hidden or not laid out yet (e.g. mid re-render) — don't size from a\n        // zero-width element; keep CSS heights and let the next call fix it up.\n        if (w > 0) {\n          const h = Math.max(basis.clientHeight, Math.floor(w * 0.7));\n          if (elmMap2) elmMap2.style.height = h + 'px';\n          if (elmMap) elmMap.style.height = h + 'px';\n          if (elmPlot) elmPlot.style.height = h + 'px';\n        }\n      }\n      if (this.map?.map) this.map.map.invalidateSize();\n      this.updatePlot();\n    },\n    get: function (){\n      const data = new ApiRequestBuilder('GET', this.buildOptions()).build();\n      ApiCom.post(this, data, this.handleResponse, this.handleError);\n    },\n    handleResponse: function (json){\n      const settingsComponent = this.$refs.settings;\n      const settings = settingsComponent.settings;\n      if (json.user){\n        this.store.user = new User(json.user);\n      }\n      settingsComponent.handleResponse(json);\n      if (json.species) {\n        this.speciesDict = settings.speciesDict;\n        this.species = settings.species;\n\n        this.speciesTitles = json.speciesDesc.titles;\n\n\n        const images = json.speciesImages;\n\n        this.store.speciesDict = this.speciesDict;\n        for (const speciesId in this.speciesDict){\n          const s = this.speciesDict[speciesId];\n          if (s.counts){\n            //  these are special counts, not actual species\n            const sImages = [];\n            // const sDescs = {}\n            for (const sub of s.counts){\n              const subImages = images[sub] || [];\n              sImages.push(...subImages);\n              // sImages[sub] = subImages;\n\n              const subDescId = json.speciesDesc.species[sub];\n              if (subDescId){\n                const desc = json.speciesDesc.data[subDescId];\n                // sDescs[sub] = desc;\n                // this.speciesDict[speciesId].desc = desc;\n              }\n            }\n            s.images = sImages;\n            // if (s.id === \"WHISKERED\"){\n            //   alert(JSON.stringify(s));\n            // }\n          }\n          else{\n            s.images = images[speciesId] || [];\n            const descId = json.speciesDesc.species[speciesId];\n            if (descId){\n              const desc = json.speciesDesc.data[descId];\n              s.desc = desc;\n            }\n          }\n        }\n\n        // for (const speciesId in this.speciesDict){\n        //   this.speciesDict[speciesId].images = [];\n        //   const descId = json.speciesDesc.species[speciesId];\n        //   if (descId){\n        //     const desc = json.speciesDesc.data[descId];\n        //     this.speciesDict[speciesId].desc = desc;\n        //   }\n        // }\n        //\n        // for (const speciesId in images){\n        //   const s = this.speciesDict[speciesId];\n        //   s.images = images[speciesId];\n        // }\n      }\n\n      this.speciesDict = settings.speciesDict;\n      this.species = settings.species;\n\n      this.store.plotSettings.handleResponse(json);\n\n      this.plot = json.plot;\n      this.obsPlots = json.obsPlots || null;\n      this.updatePlot();\n\n      this.nbLocations = json.nb_loc;\n      this.nbCounts = json.nb_rows;\n      // Detection breakdown; present only for frames containing data from an import\n      // that records complete surveys (fnt_counts v12 provenance).\n      this.siteStats = json.site_stats || null;\n      this.plotError = json.plot_error;\n      this.overall = json.overall;\n      this.summary = json.summary;\n      this.timings = json.timings;\n      this.gof = json.gof;\n\n\n      this.contributors = json.contributors;\n\n      // Cache the distribution geojson so map-only toggles can re-render without a refetch.\n      this.distfull = json.distfull;\n      this.map.createDistributionLayerFull(this.distfull);\n      this.map.createRegionLayer(json.region);\n\n      this.squareSize = json.square_size;\n      this.squares = json.squares;\n      // The grid cell size may have changed server-side; rebuild the client-side\n      // index→coordinate helper so reconstructed squares/markers align with the new grid.\n      this.map.setSquareSize(json.square_size);\n      this.updateMapSquare();\n      this.map.createLocationsLayer(this.squares);\n      // Rebuild the legend now that squares/site counts are in memory (createRegionLayer\n      // above ran its own createLegend before this.squares was assigned).\n      this.map.createLegend();\n      // this.centerMap();\n      this.resizedListener();\n    },\n    updatePlot: function(){\n      const layout = this.store.plotSettings?.obsLayout || 'single';\n      if (layout === 'grid' && this.obsPlots && this.obsPlotIds.length){\n        // The grid cells are rendered by Vue from obsPlots, which we assigned moments\n        // ago — they do not exist in the DOM until the re-render lands.\n        this.$nextTick(this.drawObsGrid);\n        return;\n      }\n      const plotId = this.getPlotId();\n      if (layout === 'combined' && this.obsPlots && this.obsPlotIds.length){\n        this.drawCombined(plotId);\n        return;\n      }\n      if (this.plot) {\n        const customOptions = this.getCustomOptions();\n        // INLA hurdle: draw the composite p123 into the main trend card via the adapter.\n        // The raw inla plot ships an empty `traces` array (traces are built client-side).\n        // No ttShowSignificance: the per-segment line colouring already shows it, and\n        // the tooltip now belongs to the per-year trace (value + site count).\n        this.isInla = this.plot.type === 'inla';\n        const plotData = this.isInla ? this.trendPlotData : this.plot;\n        const d3 = new MyD3(plotId, plotData, customOptions, this.$tc);\n\n        // Ensure subtitle end-year reflects actual data (max year from traces)\n        try {\n          const s = this.store.plotSettings;\n          const dataMinYear = Math.ceil(d3.preparedPlot?.xMin || s.yearStart);\n          const dataMaxYear = Math.floor(d3.preparedPlot?.xMax || s.yearEnd);\n          d3.customOptions.subtitle = `${s.selectedRegion.name} (${dataMinYear} - ${dataMaxYear})`;\n        } catch (e) {\n          // Ignore and keep existing subtitle\n        }\n\n        const meaning = this.overall?.slope.meaning.toLowerCase();\n        if (! this.hasEnoughData){\n          d3.message = {\n            text: this.$tc(\"trends.plotError.generic_error\"),\n          };\n        }\n        else if (meaning?.startsWith(\"uncertain\")){\n          d3.message = {\n            text: this.$tc(\"trends.slope.Uncertain\"),\n            color: \"orange\"\n          }\n        }\n\n        d3.draw();\n\n      }\n      else{\n        //TODO: maybe implement for d3 (missing plot - for now at least clear it)\n        this.isInla = false;\n        const plotId = this.getPlotId();\n        const el = document.getElementById(plotId);\n        if (el) el.innerHTML = '';\n      }\n    },\n    /** \"all in one\": every viewable type's traces merged into a single chart */\n    drawCombined: function(plotId){\n      this.isInla = false;\n      const baseObsId = this.store.plotSettings.observationType?.id;\n      const merged = mergeObsPlots(this.obsPlots, this.obsPlotIds, this.obsTypeLabels, inlaTrendToTraces, baseObsId);\n      const el = document.getElementById(plotId);\n      if (!el) return;\n      if (!merged.traces.length){\n        el.innerHTML = '';\n        return;\n      }\n      const customOptions = this.getCustomOptions();\n      // Each obs type surveys its own set of sites, so the shared bottom \"n sites\"\n      // read-out (taken from the first trace) would be wrong for the other lines —\n      // show each line's own count in its tooltip row instead.\n      const contributing = this.obsPlotIds.filter((id) => this.obsPlots[id]?.plot).length;\n      customOptions.ttShowSitesAtBottom = contributing <= 1;\n      new MyD3(plotId, merged, customOptions, this.$tc).draw();\n    },\n    /** \"side by side\": one chart per viewable type, each in its own container */\n    drawObsGrid: function(){\n      this.isInla = false;\n      const s = this.store.plotSettings;\n      for (const obsId of this.obsPlotIds){\n        const el = document.getElementById('divPlotObs_' + obsId);\n        if (!el) continue;\n        const entry = this.obsPlots[obsId];\n        let plotData = entry && entry.plot;\n        if (!plotData){\n          el.innerHTML = '';\n          continue;\n        }\n        const customOptions = this.getCustomOptions();\n        customOptions.subtitle = `${this.obsTypeLabels[obsId]} — ${s.selectedRegion.name} (${s.yearStart} - ${s.yearEnd})`;\n        if (plotData.type === 'inla'){\n          plotData = inlaTrendToTraces(plotData.trend.panels.p123,\n              {title: this.obsTypeLabels[obsId], sitesPerYear: plotData.sites_per_year});\n        }\n        new MyD3('divPlotObs_' + obsId, plotData, customOptions, this.$tc).draw();\n      }\n    },\n    getPlotId: function(){\n      if (document.getElementById(\"divPlotTop\") && document.getElementById(\"divPlotTop\").clientHeight > 0){\n        return \"divPlotTop\";\n      }\n      return \"divPlot1\";\n    },\n    handleError: function(error){\n      this.fatalError = error;\n    },\n    raiseFatalError: function(name, message, status){\n      this.fatalError = {\n        name: name,\n        status: status,\n        message: message\n      };\n      this.working = true;\n    },\n\n    /**\n     * called (by event) when settings have changed, and a request of the plot data is neccessary.\n     */\n    settingsChanged: function () {\n      const settings = this.$refs.settings.settings;\n      const speciesChanged = this.species !== settings.species;\n      this.species = settings.species;\n      this.selectedRegion = settings.selectedRegion;\n      // this.map.updateUI();\n      // if (speciesChanged) {\n        this.updateBrowserUrl();\n      // }\n      this.requestData();\n    },\n    /**\n     * called (by event) when settings were modified, but there is no intention\n     * to automatically request the data (affects more settings).\n     */\n    settingsModify: function () {\n      // this.map.updateUI();\n    },\n    requestData: function (){\n      const data = new ApiRequestBuilder('options', this.$refs.settings.buildOptions()).build();\n      ApiCom.post(this, data, this.handleResponse, this.handleError);\n    },\n    download: function(data){\n      this.requestRawData(data);\n    },\n    openSitesShortcut: function (){\n      // admin shortcut: preselect this trend's sites (species + region) on /account/sites\n      const plotOptions = this.$refs.settings.buildOptions();\n      window.location.href = sitesShortcutUrlForPlotOptions(plotOptions, this.$i18n?.locale);\n    },\n    requestRawData: function (options){\n      const plotOptions = this.$refs.settings.buildOptions();\n      const requestData = {\n        options: options,\n        plotOptions: plotOptions\n      };\n      axios.post('/dl/rawData/void', requestData, {\n        responseType: 'blob', // important\n      }).then((response) => {\n        // generate a filename\n        const filename = `${plotOptions.plotModel}_${plotOptions.observationType}_${plotOptions.species}_${plotOptions.yearStart}-${plotOptions.yearEnd}.${options.type}`;\n        // create file link in browser's memory\n        const href = URL.createObjectURL(response.data);\n\n        // create \"a\" HTML element with href to file & click\n        const link = document.createElement('a');\n        link.href = href;\n        link.setAttribute('download', filename); //or any other extension\n        document.body.appendChild(link);\n        link.click();\n\n        // clean up \"a\" element & remove ObjectURL\n        document.body.removeChild(link);\n        URL.revokeObjectURL(href);\n      });\n    },\n\n    createMap: function (){\n      if (this.map){\n        return;\n      }\n      const map = new MyMap(this);\n      map.create();\n      map.callbackSelectRectangle = (bounds) => {\n        this.$refs.settings.updateMapBounds(bounds)\n      };\n      this.map = map;\n      map.map.on('moveend', this.moveMap)\n    },\n\n    centerMap: function (){\n      this.map.centerMap();\n    },\n\n    /**\n     * A map-only setting changed (distribution / markers / map style). Re-render the\n     * map layers from the data already in memory — no server round-trip needed.\n     */\n    mapSettingsChanged: function (){\n      if (! this.map) return;\n      this.map.createTileLayer();\n      this.map.createDistributionLayerFull(this.distfull);\n      this.map.createLocationsLayer(this.squares);\n      this.updateMapSquare();\n      this.map.updateRegionStyle();\n      this.map.createLegend();\n    },\n    getCustomOptions: function () {\n      const s = this.store.plotSettings;\n      const customOptions = {\n        downloadName: s.species.id,\n        expertMode: this.store?.user?.isAdmin || false,\n        title: s.species.latin,\n        subtitle: `${s.selectedRegion.name} (${s.yearStart} - ${s.yearEnd})`,\n        showGridlines: true,\n      };\n      return customOptions;\n    },\n    // updateMap: function (){\n    //   //  this is actually not used anymore\n    //   //  it was built for location markers\n    //   if (! this.map) return;\n    //   if (this.markersLayer){\n    //     this.map.removeLayer(this.markersLayer);\n    //   }\n    //   if (!this.showLocations) return;\n    //   const allMarkers = [];\n    //   const icon = Leaflet.icon({\n    //     iconUrl: '/static/bats/misc/marker.svg',\n    //     iconSize: [40, 40],\n    //     iconAnchor: [20, 40]\n    //   });\n    //   const options = {icon: icon};\n    //   for (let idx in this.locations){\n    //     const loc = this.locations[idx];\n    //     if (loc.lat !== undefined && loc.lon !== undefined) {\n    //       // const marker = Leaflet.marker([loc.lat, loc.lon], options).addTo(map);\n    //       const marker = Leaflet.marker([loc.lat, loc.lon], options);\n    //       let popupHtml = '<h6>' + loc.name + '</h6><p class=\"text-muted\">';\n    //       if (loc.contributors){\n    //         for (let pidx in loc.contributors){\n    //           if (pidx > 0) popupHtml += ', ';\n    //           popupHtml += loc.contributors[pidx].name;\n    //         }\n    //       }\n    //       popupHtml += '</p>';\n    //       marker.bindPopup(popupHtml);\n    //       allMarkers.push(marker);\n    //     }\n    //   }\n    //\n    //   const markersLayer = new Leaflet.LayerGroup(allMarkers);\n    //   markersLayer.addTo(this.map);\n    //   this.markersLayer = markersLayer;\n    //\n    //   // const featureGroup = new Leaflet.FeatureGroup(allMarkers);\n    //   // this.map.fitBounds(featureGroup.getBounds());\n    // },\n    updateMapSquare: function () {\n      if (!this.map) return;\n      this.map.createSitesLayer(this.squares);\n    },\n\n    // hsv2Rgb: function(h, s, v) {\n    //   let r, g, b, i, f, p, q, t;\n    //   if (arguments.length === 1) {\n    //     s = h.s, v = h.v, h = h.h;\n    //   }\n    //   i = Math.floor(h * 6);\n    //   f = h * 6 - i;\n    //   p = v * (1 - s);\n    //   q = v * (1 - f * s);\n    //   t = v * (1 - (1 - f) * s);\n    //   switch (i % 6) {\n    //     case 0: r = v, g = t, b = p; break;\n    //     case 1: r = q, g = v, b = p; break;\n    //     case 2: r = p, g = v, b = t; break;\n    //     case 3: r = p, g = q, b = v; break;\n    //     case 4: r = t, g = p, b = v; break;\n    //     case 5: r = v, g = p, b = q; break;\n    //   }\n    //   return {\n    //     r: Math.round(r * 255),\n    //     g: Math.round(g * 255),\n    //     b: Math.round(b * 255)\n    //   };\n    // },\n    updateBrowserUrl: function(){\n      // Build the canonical trends path from current state, without vue-router:\n      //   /[en/]trends/<species>[/<obsCode>][/<regionSlug>]\n      // Obs code omitted when 'W'; region omitted for \"all regions\" (id -1)\n      // and map-bounds (id -2). Region slug comes from the server (region.slug).\n      if (!this.species) return;\n      const url = new URL(window.location.href);\n      const first = url.pathname.split(\"/\")[1];\n      const langPrefix = (first === \"en\" || first === \"de\") ? \"/\" + first : \"\";\n\n      const speciesSlug = (this.species.latin || this.species.id).toLowerCase().replace(/ /g, \"-\");\n      const parts = [speciesSlug];\n\n      const settings = this.$refs.settings?.settings;\n      const obs = settings?.observationType;\n      const region = settings?.selectedRegion;\n      if (obs && obs.id && obs.id !== \"W\") {\n        parts.push(obs.id);\n      }\n      if (region && region.slug && region.id !== -1 && region.id !== -2) {\n        parts.push(region.slug);\n      }\n\n      url.pathname = langPrefix + \"/trends/\" + parts.join(\"/\");\n      window.history.replaceState({}, '', url);\n    },\n  },\n  computed:{\n    // isMobile: function(){\n    //   if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)){\n    //     return true;\n    //   }else{\n    //     return false;\n    //   }\n    // },\n    hasEnoughData: function(){\n      return this.nbCounts >= 500;\n    },\n    //TODO: maybe reuse in PlotSettings (redundancy)\n    allRegions: function(){\n      return {id:-1, name: this.$t('plotOptions.allRegions')};\n    },\n    //TODO: maybe reuse in PlotSettings (redundancy)\n    mapRegion: function(){\n      return {id:-2, name: this.$t('plotOptions.mapSection')};\n    },\n    /**\n     * return a HTML id for the leaflet map\n     */\n    idMap: function (){\n      return this.prefix + 'map';\n    },\n    /**\n     * The MyD3 PlotData behind the main trend chart AND the top-bar trend summary\n     * (TrendComponentGAM). HGAM plots ship ready-made traces; INLA plots ship raw\n     * panel arrays that the adapter turns into two traces — the drawn line (full\n     * grid, significance colouring) and the hidden per-year hover trace carrying\n     * nbSites (from plot.sites_per_year, injected server-side).\n     */\n    trendPlotData: function(){\n      if (!this.plot) return null;\n      if (this.plot.type !== 'inla') return this.plot;\n      return inlaTrendToTraces(this.plot.trend.panels.p123,\n          {sitesPerYear: this.plot.sites_per_year});\n    },\n    /** ids present in obsPlots, in the server's own order (W, S, SBB, SEC) */\n    obsPlotIds: function(){\n      if (!this.obsPlots) return [];\n      const all = this.store.plotSettings?.observationTypes || {};\n      return Object.keys(all).filter((id) => id in this.obsPlots);\n    },\n    /** short legend labels, keyed by obs type id */\n    obsTypeLabels: function(){\n      const labels = {};\n      for (const id of this.obsPlotIds){\n        const key = 'trends.obsTabs.labels.' + id;\n        const short = this.$t(key);\n        labels[id] = (short === key) ? id : short;\n      }\n      return labels;\n    },\n  },\n});\n</script>\n<style>\n.my-scrollable{\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n</style>","import script from \"./PlotsBase.vue?vue&type=script&lang=js\"\nexport * from \"./PlotsBase.vue?vue&type=script&lang=js\"\n\nimport \"./PlotsBase.vue?vue&type=style&index=0&id=a6c4d2c0&lang=css\"\n\nconst __exports__ = script;\n\nexport default __exports__","import { User } from '@/lib/User';\nimport { urlFor } from '@/lib/i18nUrl';\n\n/**\n * Shortcuts that preselect a bunch of sites on /account/sites.\n *\n * Every shortcut button (trends page, MyFiles, ...) must be gated by\n * canSeeSiteShortcuts() so the audience can be changed in one place.\n * The backend counterpart is the staff-guarded fetch_shortcut_site_ids\n * action in bats/upload/api.py — keep the two in sync.\n *\n * The selection criteria travel as query params on the sites-page URL\n * (handled in MySitesPage.applySelectionShortcut):\n *   ?selectImport=<DatasetImport id>   sites contained in that import\n *   ?selectPlot=<urlencoded JSON>      sites the trend pipeline uses for\n *                                      these plot options\n * NOTE (planned): a dataScope param will additionally restrict all\n * site-page data fetches to the originating dataset's data.\n */\nexport function canSeeSiteShortcuts(user: User | null): boolean {\n  // currently staff only\n  return !!user && (user.isStaff || user.isAdmin);\n}\n\nexport function sitesShortcutUrlForImport(importId: number, lang?: string): string {\n  return urlFor('/account/sites', lang) + '?selectImport=' + encodeURIComponent(String(importId));\n}\n\nexport function sitesShortcutUrlForPlotOptions(plotOptions: object, lang?: string): string {\n  // rtab=raw: coming from a trend, land on the raw-data tab (species is\n  // preselected from plotOptions.species by the shortcut handler)\n  return urlFor('/account/sites', lang) + '?selectPlot=' + encodeURIComponent(JSON.stringify(plotOptions))\n      + '&rtab=raw';\n}\n","<template>\n  <MyTrendCard :title=\"$t('trends.populationTrend')\" icon=\"graph1\">\n    <template #actions>\n      <ObsTypeSelect @select=\"$emit('select-obs-type', $event)\"></ObsTypeSelect>\n    </template>\n    <div v-if=\"isGrid\" class=\"obs-grid\">\n      <div v-for=\"obsId in obsPlotIds\" :key=\"obsId\" class=\"obs-grid-cell\">\n        <div class=\"obs-grid-title\">\n          {{ obsLabel(obsId) }}\n          <span v-if=\"isAdminOnly(obsId)\" class=\"badge-circle badge-admin\"\n                :title=\"$t('trends.obsTabs.adminOnly')\"></span>\n        </div>\n        <PlotContent :plot=\"obsPlots[obsId].plot\" :plot-error=\"obsPlots[obsId].plot_error\"\n                     :plotId=\"'divPlotObs_' + obsId\" :working=\"working\"></PlotContent>\n      </div>\n    </div>\n    <PlotContent v-else :plot=\"effectivePlot\" :plot-error=\"effectivePlotError\" :plotId=\"plotId\" :working=\"working\"></PlotContent>\n  </MyTrendCard>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport PlotContent from \"@/components/trends/PlotContent.vue\";\nimport MyTrendCard from \"@/components/trends/cards/MyTrendCard.vue\";\nimport ObsTypeSelect from \"@/components/trends/ObsTypeSelect.vue\";\nimport MyBase from \"@/components/trends/MyBase.vue\";\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'PlotCard',\n  components: {MyTrendCard, PlotContent, ObsTypeSelect},\n  emits: ['select-obs-type'],\n  props: {\n    plot: null,\n    plotId: {type: String, default: \"divPlot1\"},\n    plotError: Object,\n    working: {type: Boolean, default: false},\n    obsPlots: Object,\n    obsPlotIds: {type: Array, default: () => []},\n  },\n  methods: {\n    obsLabel: function (obsId){\n      const key = 'trends.obsTabs.labels.' + obsId;\n      const short = this.$t(key);\n      return (short === key) ? obsId : short;\n    },\n    isAdminOnly: function (obsId){\n      return this.store?.plotSettings?.observationTypes?.[obsId]?.public === false;\n    },\n  },\n  computed: {\n    isGrid: function (){\n      return this.store?.plotSettings?.obsLayout === 'grid'\n        && !!this.obsPlots && this.obsPlotIds.length > 0;\n    },\n    /**\n     * In the 'combined' layout, divPlot1 is drawn by drawCombined() from obsPlots,\n     * not from the base type's `plot`. The overlay must therefore reflect whether\n     * the MERGED chart has anything to show, not whether the base type succeeded.\n     */\n    isCombined: function (){\n      return this.store?.plotSettings?.obsLayout === 'combined';\n    },\n    hasCombinedContent: function (){\n      if (!this.obsPlots) return false;\n      return Object.values(this.obsPlots).some((entry) => !!entry?.plot);\n    },\n    effectivePlot: function (){\n      if (this.isCombined && this.hasCombinedContent) return true;\n      return this.plot;\n    },\n    effectivePlotError: function (){\n      if (this.isCombined && this.hasCombinedContent) return null;\n      return this.plotError;\n    },\n  },\n});\n</script>\n\n<!-- Add \"scoped\" attribute to limit CSS to this component only -->\n<style scoped>\n.obs-grid {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  gap: 1.25rem;\n}\n\n@media (max-width: 1199.98px) {\n  .obs-grid {\n    grid-template-columns: 1fr;\n  }\n}\n\n/* Each chart gets its own quiet sub-panel so the title and plot read as one\n   unit instead of four charts bleeding into shared whitespace. */\n.obs-grid-cell {\n  min-width: 0;\n  background: #ffffff;\n  border: 1px solid #e8eef5;\n  border-radius: 0.625rem;\n  padding: 0.85rem 1rem 0.5rem;\n}\n\n/* Eyebrow label, echoing the section labels in the obs-type menu */\n.obs-grid-title {\n  display: flex;\n  align-items: center;\n  gap: 0.4rem;\n  font-size: 0.72rem;\n  font-weight: 600;\n  color: #64748b;\n  text-transform: uppercase;\n  letter-spacing: 0.05em;\n  margin-bottom: 0.35rem;\n}\n</style>\n","<template>\n  <div class=\"plot-content\">\n    <div :id=\"plotId\" class=\"plot-area\"></div>\n    <div v-if=\"!store.plotSettings?.species\" class=\"plot-overlay empty-state\">\n      <div class=\"empty-state-inner\">\n        <svg width=\"128\" height=\"128\" class=\"empty-icon\"><use xlink:href=\"#graph1\"/></svg>\n        <p class=\"empty-text\">{{ $t('trends.intro.trend1' )}}<br><a class=\"empty-link\" href=\"/methodology\">{{ $t('trends.intro.trend2' )}}</a></p>\n      </div>\n    </div>\n    <div v-else-if=\"!plot && !working\" class=\"plot-overlay error-overlay\">\n      <svg width=\"64\" height=\"64\" class=\"error-icon\"><use xlink:href=\"#exclamation-triangle\"/></svg>\n      <div class=\"error-content\">\n        <h5 class=\"error-title\">{{ $t('trends.plotError.generic_error') }}</h5>\n        <div v-if=\"plotError && user?.isAdmin\" class=\"error-detail\">\n          <span class=\"badge-circle badge-admin me-1\"></span>\n          [{{plotError.severity}}]:\n          {{plotError.message}}\n        </div>\n        <div v-else class=\"error-detail\">\n          {{ $t('trends.plotError.generic_error_plot') }}\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport MyBase from \"@/components/trends/MyBase.vue\";\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'PlotContent',\n  components: {},\n  props: {\n    plot: null,\n    plotId: {type: String, default: \"divPlot1\"},\n    plotError: Object,\n    working: {type: Boolean, default: false},\n  },\n  // data: function (){\n  //   return {\n  //   }\n  // },\n  // methods: {\n  //   hello: function () {\n  //     return;\n  //   },\n  // },\n});\n</script>\n\n<style scoped>\n.plot-content {\n  position: relative;\n  width: 100%;\n  min-height: 45vh;\n}\n\n.plot-area {\n  height: 45vh;\n}\n\n.plot-overlay {\n  position: absolute;\n  top:0;\n  left:0;\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n\n/* Empty State */\n.empty-state {\n  flex-direction: column;\n}\n\n.empty-state-inner {\n  text-align: center;\n}\n\n.empty-icon {\n  color: #94a3b8;\n}\n\n.empty-text {\n  font-size: 1.0625rem;\n  color: #64748b;\n  margin-top: 1.5rem;\n  line-height: 1.6;\n}\n\n.empty-link {\n  color: #64748b;\n  text-decoration: underline;\n  text-underline-offset: 2px;\n}\n\n.empty-link:hover {\n  color: #2563eb;\n}\n\n/* Error Overlay */\n.error-overlay {\n  gap: 0.75rem;\n  padding: 1.25rem;\n  background: rgba(220, 38, 38, 0.06);\n  border: 1px solid rgba(220, 38, 38, 0.2);\n  border-radius: 0.625rem;\n}\n\n.error-icon {\n  flex-shrink: 0;\n  color: #dc2626;\n}\n\n.error-title {\n  font-size: 1rem;\n  font-weight: 600;\n  color: #991b1b;\n  margin: 0 0 0.25rem;\n}\n\n.error-detail {\n  font-size: 0.875rem;\n  color: #1e293b;\n  line-height: 1.5;\n}\n</style>\n","import { render } from \"./PlotContent.vue?vue&type=template&id=9b5e7ac8&scoped=true\"\nimport script from \"./PlotContent.vue?vue&type=script&lang=js\"\nexport * from \"./PlotContent.vue?vue&type=script&lang=js\"\n\nimport \"./PlotContent.vue?vue&type=style&index=0&id=9b5e7ac8&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-9b5e7ac8\"]])\n\nexport default __exports__","<template>\n  <div class=\"trend-card-wrapper\">\n    <!-- Borderless: title sits inline above the content, no card chrome -->\n    <template v-if=\"cardStyle === 'borderless'\">\n      <h3 class=\"borderless-title\">{{ title }}</h3>\n      <slot></slot>\n    </template>\n    <!-- Default card: dashboard-style section card with an accent header + optional icon -->\n    <div v-else class=\"section-card\">\n      <div class=\"section-header\">\n        <div class=\"section-title-group\">\n          <svg v-if=\"icon\" class=\"bi\" width=\"18\" height=\"18\"><use :xlink:href=\"'#' + icon\"/></svg>\n          <h5 class=\"section-title\">{{ title }}</h5>\n        </div>\n        <div class=\"section-actions\"><slot name=\"actions\"></slot></div>\n      </div>\n      <div class=\"section-body\"><slot></slot></div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport MyBase from \"@/components/trends/MyBase.vue\";\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'MyTrendCard',\n  components: {},\n  props: {\n    title: String,\n    // Optional bootstrap-icon id (without '#') shown before the title.\n    icon: {type: String, default: \"\"},\n    cardStyle: {type: String, default: \"card\"}\n  },\n});\n</script>\n\n<style scoped>\n.section-card {\n  background: #ffffff;\n  border: 1px solid #e2e8f0;\n  border-radius: 0.875rem;\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\n  overflow: hidden;\n}\n\n.section-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  gap: 1rem;\n  padding: 0.85rem 1.1rem;\n  background: #f8fafc;\n  border-bottom: 1px solid #f1f5f9;\n  border-left: 3px solid #2563eb;\n}\n\n.section-title-group {\n  display: flex;\n  align-items: center;\n  gap: 0.5rem;\n  color: #64748b;\n  min-width: 0;\n}\n\n.section-title-group .bi { color: #2563eb; flex-shrink: 0; }\n\n.section-title {\n  margin: 0;\n  font-size: 1rem;\n  font-weight: 600;\n  color: #1e293b;\n  line-height: 1.4;\n}\n\n.section-actions { flex-shrink: 0; }\n\n.section-body {\n  padding: 1rem;\n}\n\n.borderless-title {\n  font-size: 1.5rem;\n  font-weight: 700;\n  color: #1e293b;\n  margin: 0 0 0.75rem;\n}\n</style>\n","import { render } from \"./MyTrendCard.vue?vue&type=template&id=4f07e000&scoped=true\"\nimport script from \"./MyTrendCard.vue?vue&type=script&lang=js\"\nexport * from \"./MyTrendCard.vue?vue&type=script&lang=js\"\n\nimport \"./MyTrendCard.vue?vue&type=style&index=0&id=4f07e000&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-4f07e000\"]])\n\nexport default __exports__","<template>\n  <div v-if=\"tabs.length >= 2 || isAdmin\" ref=\"root\" class=\"obs-select\">\n    <button ref=\"trigger\" type=\"button\" class=\"obs-trigger\" :class=\"{'is-open': open}\"\n            aria-haspopup=\"listbox\" :aria-expanded=\"open\" @click=\"toggle\">\n      <span class=\"obs-trigger-label\">{{ currentLabel }}</span>\n      <span v-if=\"currentIsAdminOnly\" class=\"badge-circle badge-admin\" :title=\"$t('trends.obsTabs.adminOnly')\"\n            :aria-label=\"$t('trends.obsTabs.adminOnly')\"></span>\n      <svg class=\"obs-chevron\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" aria-hidden=\"true\">\n        <path d=\"M2.5 4.5L6 8l3.5-3.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\"\n              stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n      </svg>\n    </button>\n\n    <Teleport to=\"body\">\n      <ul v-if=\"open\" ref=\"menu\" class=\"obs-menu\" role=\"listbox\" :style=\"menuStyle\"\n          @keydown=\"onMenuKeydown\">\n        <li v-for=\"t in tabs\" :key=\"t.id\" role=\"none\">\n          <button type=\"button\" class=\"obs-option\" role=\"option\"\n                  :class=\"{'is-active': isActive(t), 'is-disabled': !isSelectable(t)}\"\n                  :aria-selected=\"isActive(t)\"\n                  :disabled=\"!isSelectable(t)\"\n                  :title=\"isAvailable(t) || isActive(t) ? t.name : $t('trends.obsTabs.noData')\"\n                  @click=\"select(t)\">\n            <svg class=\"obs-check\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" aria-hidden=\"true\">\n              <path v-if=\"isActive(t)\" d=\"M2.5 7.5L5.5 10.5L11.5 3.5\" fill=\"none\" stroke=\"currentColor\"\n                    stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n            </svg>\n            <span class=\"obs-option-label\">{{ label(t) }}</span>\n            <span v-if=\"isAdminOnly(t)\" class=\"badge-circle badge-admin\" :title=\"$t('trends.obsTabs.adminOnly')\"\n                  :aria-label=\"$t('trends.obsTabs.adminOnly')\"></span>\n            <span v-if=\"!isAvailable(t) && !isActive(t)\" class=\"obs-nodata\">{{ $t('trends.obsTabs.noData') }}</span>\n          </button>\n        </li>\n        <template v-if=\"isAdmin\">\n          <li role=\"none\"><div class=\"obs-section\">{{ $t('trends.obsTabs.layoutSectionLabel') }}</div></li>\n          <li v-for=\"opt in layoutOptions\" :key=\"opt.layout\" role=\"none\">\n            <button type=\"button\" class=\"obs-option\" role=\"option\"\n                    :class=\"{'is-active': settings?.obsLayout === opt.layout}\"\n                    :aria-selected=\"settings?.obsLayout === opt.layout\"\n                    @click=\"selectLayout(opt.layout)\">\n              <svg class=\"obs-check\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" aria-hidden=\"true\">\n                <path v-if=\"settings?.obsLayout === opt.layout\" d=\"M2.5 7.5L5.5 10.5L11.5 3.5\" fill=\"none\"\n                      stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n              </svg>\n              <span class=\"obs-option-label\">{{ opt.label }}</span>\n              <span class=\"badge-circle badge-admin\" :title=\"$t('trends.obsTabs.adminOnly')\"\n                    :aria-label=\"$t('trends.obsTabs.adminOnly')\"></span>\n            </button>\n          </li>\n        </template>\n      </ul>\n    </Teleport>\n  </div>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport MyBase from \"@/components/trends/MyBase.vue\";\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'ObsTypeSelect',\n  emits: ['select'],\n  data() {\n    return {\n      open: false,\n      menuStyle: {},\n    };\n  },\n  computed: {\n    settings() {\n      return this.store?.plotSettings;\n    },\n    tabs() {\n      if (!this.settings?.observationTypes) return [];\n      // server order (W, S, SBB, SEC); anonymous users only ever receive public types\n      return Object.values(this.settings.observationTypes);\n    },\n    currentLabel() {\n      const layout = this.settings?.obsLayout;\n      if (layout && layout !== 'single') {\n        const opt = this.layoutOptions.find((o) => o.layout === layout);\n        if (opt) return opt.label;\n      }\n      const cur = this.settings?.observationType;\n      return cur ? this.label(cur) : '';\n    },\n    currentIsAdminOnly() {\n      return this.isAdminOnly(this.settings?.observationType);\n    },\n    isAdmin() {\n      return this.store?.user?.isAdmin || false;\n    },\n    layoutOptions() {\n      return [\n        {layout: 'combined', label: this.$t('trends.obsTabs.layoutCombined')},\n        {layout: 'grid', label: this.$t('trends.obsTabs.layoutGrid')},\n      ];\n    },\n  },\n  beforeUnmount() {\n    this.teardown();\n  },\n  methods: {\n    label(t) {\n      if (!t) return '';\n      const key = 'trends.obsTabs.labels.' + t.id;\n      const short = this.$t(key);\n      return short === key ? t.id : short;\n    },\n    isActive(t) {\n      return this.settings?.observationType?.id === t.id;\n    },\n    isAvailable(t) {\n      return (this.settings?.availableObservationTypes || []).some((a) => a.id === t.id);\n    },\n    isAdminOnly(t) {\n      return !!t && t.public === false;\n    },\n    isSelectable(t) {\n      // The active type stays inert (already shown); unavailable types have no data.\n      return this.isAvailable(t) && !this.isActive(t);\n    },\n    select(t) {\n      if (!this.isSelectable(t)) return;\n      this.$emit('select', {kind: 'obsType', obsType: t});\n      this.close();\n    },\n    selectLayout(layout) {\n      this.$emit('select', {kind: 'layout', layout: layout});\n      this.close();\n    },\n    toggle() {\n      this.open ? this.close() : this.openMenu();\n    },\n    openMenu() {\n      this.positionMenu();\n      this.open = true;\n      document.addEventListener('pointerdown', this.onDocPointerDown, true);\n      window.addEventListener('resize', this.close, true);\n      window.addEventListener('scroll', this.close, true);\n      this.$nextTick(() => this.focusActiveOption());\n    },\n    close() {\n      if (!this.open) return;\n      this.open = false;\n      this.teardown();\n      const trigger = this.$refs.trigger;\n      if (trigger) trigger.focus();\n    },\n    teardown() {\n      document.removeEventListener('pointerdown', this.onDocPointerDown, true);\n      window.removeEventListener('resize', this.close, true);\n      window.removeEventListener('scroll', this.close, true);\n    },\n    positionMenu() {\n      const trigger = this.$refs.trigger;\n      if (!trigger) return;\n      const r = trigger.getBoundingClientRect();\n      // Fixed + right-anchored so the menu escapes the card's overflow:hidden and\n      // lines up with the trigger's right edge without needing the menu width.\n      this.menuStyle = {\n        top: (r.bottom + 6) + 'px',\n        right: (window.innerWidth - r.right) + 'px',\n        minWidth: r.width + 'px',\n      };\n    },\n    onDocPointerDown(e) {\n      const root = this.$refs.root;\n      const menu = this.$refs.menu;\n      if (root && root.contains(e.target)) return;\n      if (menu && menu.contains(e.target)) return;\n      this.close();\n    },\n    optionButtons() {\n      const menu = this.$refs.menu;\n      if (!menu) return [];\n      return Array.from(menu.querySelectorAll('.obs-option:not([disabled])'));\n    },\n    focusActiveOption() {\n      // The active type is inert (disabled), so land focus on the first selectable\n      // option; the menu itself is focusable via the buttons for arrow navigation.\n      const buttons = this.optionButtons();\n      if (buttons.length) buttons[0].focus();\n    },\n    onMenuKeydown(e) {\n      if (e.key === 'Escape') {\n        e.preventDefault();\n        this.close();\n        return;\n      }\n      if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return;\n      e.preventDefault();\n      const buttons = this.optionButtons();\n      if (!buttons.length) return;\n      const idx = buttons.indexOf(document.activeElement);\n      const step = e.key === 'ArrowDown' ? 1 : -1;\n      const next = (idx + step + buttons.length) % buttons.length;\n      buttons[next].focus();\n    },\n  },\n});\n</script>\n\n<style scoped>\n.obs-select {\n  position: relative;\n  display: inline-flex;\n}\n\n.obs-trigger {\n  display: inline-flex;\n  align-items: center;\n  gap: 0.4rem;\n  border: 1px solid #e2e8f0;\n  background: #ffffff;\n  border-radius: 0.5rem;\n  padding: 0.28rem 0.55rem;\n  font-size: 0.8rem;\n  font-weight: 600;\n  color: #1e293b;\n  line-height: 1.3;\n  cursor: pointer;\n  transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;\n}\n\n.obs-trigger:hover {\n  border-color: #cbd5e1;\n  background: #f8fafc;\n}\n\n.obs-trigger.is-open,\n.obs-trigger:focus-visible {\n  outline: none;\n  border-color: #2563eb;\n  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);\n}\n\n.obs-trigger-label {\n  white-space: nowrap;\n}\n\n.obs-chevron {\n  color: #64748b;\n  flex-shrink: 0;\n  transition: transform 0.18s ease;\n}\n\n.obs-trigger.is-open .obs-chevron {\n  transform: rotate(180deg);\n  color: #2563eb;\n}\n\n/* admin dot uses the shared badge-circle/badge-admin classes (assets/css/access-badges.css) */\n</style>\n\n<style>\n/* Menu is teleported to <body>, so its rules are global (not scoped). Namespaced\n   under .obs-menu to stay isolated. */\n.obs-menu {\n  position: fixed;\n  z-index: 1080;\n  margin: 0;\n  padding: 0.3rem;\n  list-style: none;\n  background: #ffffff;\n  border: 1px solid #e2e8f0;\n  border-radius: 0.6rem;\n  box-shadow: 0 10px 24px -8px rgba(15, 23, 42, 0.25), 0 2px 6px rgba(15, 23, 42, 0.06);\n  max-height: min(60vh, 320px);\n  overflow-y: auto;\n  animation: obs-menu-in 0.14s ease;\n  transform-origin: top right;\n}\n\n@keyframes obs-menu-in {\n  from { opacity: 0; transform: translateY(-4px) scale(0.98); }\n  to   { opacity: 1; transform: translateY(0) scale(1); }\n}\n\n.obs-menu .obs-option {\n  display: flex;\n  align-items: center;\n  gap: 0.45rem;\n  width: 100%;\n  border: 0;\n  background: transparent;\n  border-radius: 0.4rem;\n  padding: 0.4rem 0.55rem;\n  font-size: 0.8rem;\n  font-weight: 500;\n  color: #334155;\n  line-height: 1.35;\n  text-align: left;\n  cursor: pointer;\n  transition: background 0.12s ease, color 0.12s ease;\n}\n\n.obs-menu .obs-option:hover:not(.is-disabled),\n.obs-menu .obs-option:focus-visible:not(.is-disabled) {\n  outline: none;\n  background: #f1f5f9;\n  color: #1e293b;\n}\n\n.obs-menu .obs-option.is-active {\n  color: #2563eb;\n  font-weight: 600;\n  background: rgba(37, 99, 235, 0.08);\n}\n\n.obs-menu .obs-option.is-disabled:not(.is-active) {\n  color: #94a3b8;\n  cursor: not-allowed;\n}\n\n.obs-menu .obs-check {\n  color: #2563eb;\n  flex-shrink: 0;\n}\n\n.obs-menu .obs-option-label {\n  flex: 1 1 auto;\n  white-space: nowrap;\n}\n\n.obs-menu .obs-nodata {\n  font-size: 0.68rem;\n  font-weight: 500;\n  color: #94a3b8;\n  white-space: nowrap;\n}\n\n.obs-menu .obs-section {\n  padding: 0.45rem 0.55rem 0.25rem;\n  font-size: 0.68rem;\n  font-weight: 600;\n  color: #94a3b8;\n  text-transform: uppercase;\n  letter-spacing: 0.04em;\n  border-top: 1px solid #e2e8f0;\n  margin-top: 0.25rem;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .obs-menu { animation: none; }\n  .obs-chevron { transition: none; }\n}\n</style>\n","import { render } from \"./ObsTypeSelect.vue?vue&type=template&id=8916edca&scoped=true\"\nimport script from \"./ObsTypeSelect.vue?vue&type=script&lang=js\"\nexport * from \"./ObsTypeSelect.vue?vue&type=script&lang=js\"\n\nimport \"./ObsTypeSelect.vue?vue&type=style&index=0&id=8916edca&scoped=true&lang=css\"\nimport \"./ObsTypeSelect.vue?vue&type=style&index=1&id=8916edca&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-8916edca\"]])\n\nexport default __exports__","import { render } from \"./PlotCard.vue?vue&type=template&id=a1eea2d4&scoped=true\"\nimport script from \"./PlotCard.vue?vue&type=script&lang=js\"\nexport * from \"./PlotCard.vue?vue&type=script&lang=js\"\n\nimport \"./PlotCard.vue?vue&type=style&index=0&id=a1eea2d4&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-a1eea2d4\"]])\n\nexport default __exports__","<template>\n  <MyTrendCard :title=\"$t('trends.map')\" icon=\"map1\">\n    <div id=\"box2\" v-if=\"!store.plotSettings?.species\">\n      <div class=\"map-empty-state\">\n        <div class=\"empty-inner\">\n          <svg width=\"128\" height=\"128\" class=\"empty-icon\"><use xlink:href=\"#map1\"/></svg>\n          <p class=\"empty-text\">{{ $t('trends.intro.map1' )}}</p>\n        </div>\n      </div>\n    </div>\n    <div v-show=\"store.plotSettings?.species\" :id=\"idMap\" class=\"map-container\"></div>\n  </MyTrendCard>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport MyBase from \"@/components/trends/MyBase.vue\";\nimport MyTrendCard from \"@/components/trends/cards/MyTrendCard.vue\";\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'TcMap',\n  components: {MyTrendCard},\n  props: {\n    idMap: String\n  },\n  data: function (){\n    return {\n    }\n  },\n  mounted: function() {\n    return;\n  },\n  methods: {\n    hello: function () {\n      return;\n    },\n  },\n});\n</script>\n\n<style scoped>\n.map-container {\n  height: 45vh;\n}\n\n.map-empty-state {\n  width: 100%;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n\n.empty-inner {\n  text-align: center;\n}\n\n.empty-icon {\n  color: #94a3b8;\n}\n\n.empty-text {\n  font-size: 1.0625rem;\n  color: #64748b;\n  margin-top: 1.5rem;\n  line-height: 1.6;\n}\n</style>\n<style>\n.map-info {\n  padding: 5px;\n  background-color: white;\n}\n\n/* While fullscreen, fill the screen regardless of the inline height set by resizedFn. */\n.map-container:fullscreen {\n  width: 100% !important;\n  height: 100% !important;\n}\n\n/* Information-carrying legend */\n.map-legend {\n  padding: 8px 10px;\n  background: rgba(255, 255, 255, 0.94);\n  border: 1px solid #e2e8f0;\n  border-radius: 8px;\n  box-shadow: 0 4px 12px -4px rgba(15, 23, 42, 0.2);\n  font-size: 12px;\n  line-height: 1.4;\n  color: #1e293b;\n  max-width: 220px;\n}\n\n.map-legend .lg-title {\n  font-weight: 600;\n  margin-bottom: 4px;\n}\n\n.map-legend .lg-scale {\n  display: flex;\n  gap: 2px;\n  align-items: flex-end;\n}\n\n.map-legend .lg-bin {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 2px;\n  font-size: 10px;\n  color: #64748b;\n}\n\n.map-legend .lg-bin i {\n  width: 22px;\n  height: 12px;\n  border: 1px solid rgba(15, 23, 42, 0.2);\n}\n\n.map-legend .lg-sub {\n  font-size: 10px;\n  color: #94a3b8;\n  margin-top: 2px;\n}\n\n.map-legend .lg-row {\n  display: flex;\n  align-items: center;\n  gap: 6px;\n  margin-top: 4px;\n}\n\n.map-legend .lg-sw {\n  width: 14px;\n  height: 14px;\n  border-radius: 3px;\n  border: 1px solid rgba(15, 23, 42, 0.2);\n  flex-shrink: 0;\n}\n\n.map-legend .lg-count {\n  margin-top: 6px;\n  padding-top: 5px;\n  border-top: 1px solid #eef2f6;\n  font-size: 11px;\n  color: #64748b;\n}\n\n/* Custom tool buttons (recenter / fullscreen / export) */\n.leaflet-control.map-tool a {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 30px;\n  height: 30px;\n  color: #334155;\n}\n\n.leaflet-control.map-tool a:hover {\n  color: #0f172a;\n  background: #f1f5f9;\n}\n\n/* Hover tooltip on grid cells */\n.map-cell-tooltip {\n  font-size: 12px;\n}\n\n.map-cell-tooltip .tt-muted {\n  color: #000;\n  font-size: 11px;\n}\n</style>\n","import { render } from \"./TcMap.vue?vue&type=template&id=11e5e3f5&scoped=true\"\nimport script from \"./TcMap.vue?vue&type=script&lang=js\"\nexport * from \"./TcMap.vue?vue&type=script&lang=js\"\n\nimport \"./TcMap.vue?vue&type=style&index=0&id=11e5e3f5&scoped=true&lang=css\"\nimport \"./TcMap.vue?vue&type=style&index=1&id=11e5e3f5&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-11e5e3f5\"]])\n\nexport default __exports__","<template>\n  <div>\n    <div class=\"settings-row\">\n      <div class=\"settings-bar\">\n        <ul class=\"nav\">\n          <li class=\"nav-item dropdown settings-tab settings-tab-primary\">\n            <a class=\"nav-link dropdown-toggle\" data-bs-toggle=\"dropdown\" href=\"#\" role=\"button\" id=\"nlSpecies\">\n              <i v-if=\"settings.species\">{{ settings.species.latin }}</i>\n              <strong v-else class=\"prompt-label\">\n                <svg width=\"20\" height=\"20\" class=\"prompt-icon\"><use xlink:href=\"#bi-1-circle\"/></svg>\n                {{ $t('plotOptions.selectSpecies') }}\n              </strong>\n            </a>\n            <ul class=\"settings-dropdown dropdown-menu cols-scrollable\">\n              <li v-for=\"(spec, key) in settings.availableCountTypes\" :key=\"key\" class=\"dropdown-item settings-dropdown-item\"\n                  @click=\"selectSpecies(spec)\"\n                  :class=\"{'active': settings.species && settings.species.id === spec.id}\">\n                <i>{{spec.latin}}</i> <span class=\"species-common\">({{capitalizeAll(spec.name)}})</span>\n              </li>\n            </ul>\n          </li>\n          <!--          <li class=\"nav-item dropdown\">-->\n          <!--            <a class=\"nav-link dropdown-toggle\" data-bs-toggle=\"dropdown\" href=\"#\" role=\"button\">{{ (settings.observationType) ? settings.observationType.name : $t('plotOptions.selectObsType') }}</a>-->\n          <!--            <ul class=\"my-dropdown dropdown-menu cols-scrollable\">-->\n          <!--              <li v-for=\"(t, key) in settings.availableObservationTypes\" :key=\"key\" class=\"dropdown-item my-dropdown-item\"-->\n          <!--                  @click=\"selectObservationType(t)\"-->\n          <!--                  :class=\"{'active': settings.observationType && settings.observationType.id === t.id}\">-->\n          <!--                {{ t.name }}-->\n          <!--              </li>-->\n          <!--            </ul>-->\n          <!--          </li>-->\n          <li class=\"nav-item dropdown\">\n            <a class=\"nav-link dropdown-toggle\" :class=\"{'disabled': !settings.species}\" data-bs-toggle=\"dropdown\" href=\"#\" role=\"button\" id=\"nlRegion\">\n              <svg v-if=\"!settings.species\" width=\"20\" height=\"20\" class=\"prompt-icon\"><use xlink:href=\"#bi-2-circle\"/></svg>\n              {{ (settings.selectedRegion) ?\n                    settings.selectedRegion.type === \"b\" ? capitalizeAll(settings.selectedRegion.name)\n                                                     : settings.selectedRegion.name\n                : $t('plotOptions.selectRegion') }}\n            </a>\n            <ul class=\"settings-dropdown dropdown-menu cols-scrollable\">\n              <li class=\"dropdown-item settings-dropdown-item\" @click=\"selectGeo1(settings.allRegions)\" :class=\"{'active': settings.selectedRegion && settings.selectedRegion.id === settings.allRegions.id}\">{{ settings.allRegions.name }}</li>\n              <hr v-if=\"settings.availableBiogeo?.length > 0\">\n              <li v-for=\"(geo, key) in settings.availableBiogeo\" :key=\"'bg' + key\" class=\"dropdown-item settings-dropdown-item\"\n                  @click=\"selectBioGeo(geo)\"\n                  :class=\"{'active': geo.id === settings.selectedRegion.id}\">\n                {{ capitalizeAll(geo.name) }}\n              </li>\n              <hr v-if=\"settings.availableGeo1?.length > 0\">\n              <li v-for=\"(geo, key) in settings.availableGeo1\" :key=\"key\" class=\"dropdown-item settings-dropdown-item\"\n                  @click=\"selectGeo1(geo)\"\n                  :class=\"{'active': geo.id === settings.selectedRegion.id}\">\n                {{ geo.name }}\n              </li>\n              <hr v-if=\"settings.avalaibleGeoAdm?.length > 1\">\n              <li v-for=\"(geo, key) in settings.avalaibleGeoAdm\" :key=\"'ga' + key\" class=\"dropdown-item settings-dropdown-item\"\n                  @click=\"selectGeoAdm(geo)\"\n                  :class=\"{'active': geo.id === settings.selectedRegion.id}\">\n                {{ geo.name }}\n              </li>\n            </ul>\n          </li>\n\n          <div class=\"nav-item timespan-label\">\n            <div id=\"nlTimespan1\">\n              <svg v-if=\"!settings.species\" width=\"20\" height=\"20\" class=\"prompt-icon\"><use xlink:href=\"#bi-3-circle\"/></svg>\n              <span>{{ $t('plotOptions.timespan') }}</span>\n            </div>\n          </div>\n          <li class=\"nav-item dropdown\">\n            <a class=\"nav-link dropdown-toggle\" :class=\"{'disabled': !settings.species}\" data-bs-toggle=\"dropdown\" href=\"#\" role=\"button\" id=\"nlTimespan2\">{{ settings.yearStart <= settings.yearMin ? 'Min.' : settings.yearStart }}</a>\n            <ul class=\"settings-dropdown dropdown-menu cols-scrollable\">\n              <li v-for=\"(y, index) in settings.yearsMin()\" :key=\"index\" class=\"dropdown-item settings-dropdown-item\"\n                  @click=\"selectYearStart(y)\"\n                  :class=\"{'active': settings.yearStart && settings.yearStart === y}\">\n                {{ index === 0 ? 'Min.' : y }}\n              </li>\n            </ul>\n          </li>\n          <div class=\"nav-item timespan-separator\">\n            <span id=\"nlTimespan3\">{{ $t('plotOptions.timespanTo') }}</span>\n          </div>\n          <li class=\"nav-item dropdown\">\n            <a class=\"nav-link dropdown-toggle\" :class=\"{'disabled': !settings.species}\" data-bs-toggle=\"dropdown\" href=\"#\" role=\"button\" id=\"nlTimespan4\">{{ settings.yearEnd >= settings.effectiveYearMax ? 'Max.' : settings.yearEnd }}</a>\n            <ul class=\"settings-dropdown dropdown-menu cols-scrollable\">\n              <li v-for=\"(y, index) in settings.yearsMax()\" :key=\"index\" class=\"dropdown-item settings-dropdown-item\"\n                  @click=\"selectYearEnd(y)\"\n                  :class=\"{'active': settings.yearEnd && settings.yearEnd === y}\">\n                {{ y >= settings.effectiveYearMax ? 'Max.' : y }}\n              </li>\n            </ul>\n          </li>\n          <a v-if=\"settings.canUseMoreOptions()\" class=\"nav-link more-options-link\" data-bs-toggle=\"collapse\" href=\"#collapseMoreOptions\" role=\"button\">{{$t('plotOptions.moreOptions')}} <span class=\"badge-circle badge-admin\"></span></a>\n        </ul>\n      </div>\n    </div>\n\n    <div v-if=\"settings.canUseMoreOptions()\" class=\"collapse options-panel\" id=\"collapseMoreOptions\">\n      <div class=\"options-panel-head\">\n        <div>\n          <div class=\"options-eyebrow\">{{ $t(\"plotOptions.moreOptions\") }} <span class=\"badge-circle badge-admin\"></span></div>\n          <div class=\"options-panel-title\">{{ $t(\"plotOptions.more.adminTitle\") }}</div>\n        </div>\n        <button type=\"button\" class=\"options-close\" data-bs-toggle=\"collapse\" data-bs-target=\"#collapseMoreOptions\"\n                :aria-label=\"$t('plotOptions.more.close')\">\n          <span aria-hidden=\"true\">&times;</span>\n        </button>\n      </div>\n\n      <div class=\"options-grid\">\n        <!-- OBSERVATIONS -->\n        <section class=\"options-card\">\n          <div class=\"options-eyebrow\">{{ $t(\"plotOptions.more.data\") }}</div>\n\n          <div class=\"opt-field\">\n            <label class=\"opt-label\" for=\"selObsType\">{{ $t(\"plotOptions.more.obsType\") }}</label>\n            <select class=\"form-select form-select-sm opt-select\" id=\"selObsType\"\n                    v-model=\"settings.observationType\" @change=\"selectObservationType(settings.observationType)\">\n              <option v-for=\"(obsType, key) in settings.observationTypes\" :key=\"key\" :value=\"obsType\">\n                {{ obsType.id }} — {{ obsType.name }}\n              </option>\n            </select>\n          </div>\n\n          <div class=\"opt-field\">\n            <label class=\"opt-label\">{{ $t(\"plotOptions.more.obsLayout\") }}</label>\n            <div class=\"opt-segment opt-segment-3\" role=\"group\">\n              <button type=\"button\" class=\"opt-segment-btn\" :class=\"{'is-active': settings.obsLayout === 'single'}\"\n                      @click=\"selectObsLayout('single')\">{{ $t(\"plotOptions.more.obsLayoutSingle\") }}</button>\n              <button type=\"button\" class=\"opt-segment-btn\" :class=\"{'is-active': settings.obsLayout === 'combined'}\"\n                      @click=\"selectObsLayout('combined')\">{{ $t(\"plotOptions.more.obsLayoutCombined\") }}</button>\n              <button type=\"button\" class=\"opt-segment-btn\" :class=\"{'is-active': settings.obsLayout === 'grid'}\"\n                      @click=\"selectObsLayout('grid')\">{{ $t(\"plotOptions.more.obsLayoutGrid\") }}</button>\n            </div>\n            <span class=\"opt-toggle-hint\">{{ $t(\"plotOptions.more.obsLayoutHint\") }}</span>\n          </div>\n        </section>\n\n        <!-- MAP -->\n        <section class=\"options-card\">\n          <div class=\"options-eyebrow\">{{ $t(\"plotOptions.more.map\") }}</div>\n\n          <label class=\"opt-toggle\">\n            <span class=\"opt-toggle-text\">\n              <span class=\"opt-toggle-title\">{{ $t(\"plotOptions.more.gridSquares\") }}</span>\n            </span>\n            <span class=\"form-check form-switch opt-switch\">\n              <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\" id=\"cbSquares\"\n                     v-model=\"settings.showSquares\" @change=\"emitMapChange()\">\n            </span>\n          </label>\n\n          <div v-if=\"settings.tk25Available\" class=\"opt-field opt-field-inset\"\n               :class=\"{'opt-field-muted': !settings.showSquares}\">\n            <label class=\"opt-label\">{{ $t(\"plotOptions.more.aggregation\") }}</label>\n            <div class=\"opt-segment\" role=\"group\">\n              <button type=\"button\" class=\"opt-segment-btn\" :class=\"{'is-active': settings.mapAggregation === 'grid'}\"\n                      @click=\"selectMapAggregation('grid')\">{{ $t(\"plotOptions.more.aggregationGrid\") }}</button>\n              <button type=\"button\" class=\"opt-segment-btn\" :class=\"{'is-active': settings.mapAggregation === 'tk25'}\"\n                      @click=\"selectMapAggregation('tk25')\">{{ $t(\"plotOptions.more.aggregationTk25\") }}</button>\n            </div>\n          </div>\n\n          <div v-if=\"settings.mapAggregation === 'grid' && settings.availableGridSizes.length > 1\"\n               class=\"opt-field opt-field-inset\"\n               :class=\"{'opt-field-muted': !settings.showSquares}\">\n            <label class=\"opt-label\" for=\"selGridSize\">{{ $t(\"plotOptions.more.gridSize\") }}</label>\n            <select class=\"form-select form-select-sm opt-select\" id=\"selGridSize\"\n                    v-model.number=\"settings.squareSize\" @change=\"emitChange()\">\n              <option v-for=\"size in settings.availableGridSizes\" :key=\"size\" :value=\"size\">{{ size }} × {{ size }} km</option>\n            </select>\n          </div>\n\n          <label class=\"opt-toggle\">\n            <span class=\"opt-toggle-text\">\n              <span class=\"opt-toggle-title\">{{ $t(\"plotOptions.more.distributionLayer\") }}</span>\n            </span>\n            <span class=\"form-check form-switch opt-switch\">\n              <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\" id=\"cbDistribution\"\n                     v-model=\"settings.showDistribution\" @change=\"emitMapChange()\">\n            </span>\n          </label>\n\n          <label class=\"opt-toggle\">\n            <span class=\"opt-toggle-text\">\n              <span class=\"opt-toggle-title\">{{ $t(\"plotOptions.more.locationMarkers\") }}</span>\n            </span>\n            <span class=\"form-check form-switch opt-switch\">\n              <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\" id=\"cbMarkers\"\n                     v-model=\"settings.showLocations\" @change=\"emitMapChange()\">\n            </span>\n          </label>\n\n          <div class=\"opt-field\">\n            <label class=\"opt-label\" for=\"selBasemap\">{{ $t(\"plotOptions.more.mapStyle\") }}</label>\n            <select class=\"form-select form-select-sm opt-select\" id=\"selBasemap\"\n                    v-model=\"settings.mapLayer\" @change=\"selectMapLayer(settings.mapLayer)\">\n              <option v-for=\"bm in basemaps\" :key=\"bm.key\" :value=\"bm.key\">{{ bm.label }}</option>\n            </select>\n          </div>\n        </section>\n      </div>\n\n      <!-- APPEARANCE: two columns — cells on the left, distribution/region on the right -->\n      <section class=\"options-card options-card-wide\">\n        <div class=\"options-eyebrow\">{{ $t(\"plotOptions.more.appearance\") }}</div>\n\n        <div class=\"appearance-grid\">\n          <!-- Column 1: observation cells -->\n          <div class=\"appearance-col\">\n            <div class=\"style-row-head\">\n              <span class=\"style-row-title\">{{ $t(\"plotOptions.more.styleCells\") }}</span>\n              <label class=\"style-inline-toggle\">\n                <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\"\n                       v-model=\"settings.mapStyleSite.graduated\" @change=\"emitMapChange()\">\n                <span>{{ $t(\"plotOptions.more.shadeByCount\") }}</span>\n              </label>\n            </div>\n\n            <div class=\"color-row\">\n              <label class=\"color-pick\">\n                <span class=\"color-pick-label\">{{ $t(\"plotOptions.more.fill\") }}</span>\n                <span class=\"color-chip\" :style=\"{background: settings.mapStyleSite.fill}\">\n                  <input type=\"color\" :value=\"settings.mapStyleSite.fill\" @input=\"setStyleColor('mapStyleSite', 'fill', $event.target.value)\">\n                </span>\n                <span class=\"color-hex\">{{ settings.mapStyleSite.fill }}</span>\n              </label>\n              <label class=\"color-pick\">\n                <span class=\"color-pick-label\">{{ $t(\"plotOptions.more.border\") }}</span>\n                <span class=\"color-chip\" :style=\"{background: settings.mapStyleSite.border}\">\n                  <input type=\"color\" :value=\"settings.mapStyleSite.border\" @input=\"setStyleColor('mapStyleSite', 'border', $event.target.value)\">\n                </span>\n                <span class=\"color-hex\">{{ settings.mapStyleSite.border }}</span>\n              </label>\n            </div>\n            <div class=\"color-row\">\n              <label class=\"color-pick\">\n                <span class=\"color-pick-label\">{{ $t(\"plotOptions.more.cellNoDetection\") }}</span>\n                <span class=\"color-chip\" :style=\"{background: settings.mapStyleSite.noDetectionFill}\">\n                  <input type=\"color\" :value=\"settings.mapStyleSite.noDetectionFill\" @input=\"setStyleColor('mapStyleSite', 'noDetectionFill', $event.target.value)\">\n                </span>\n                <span class=\"color-hex\">{{ settings.mapStyleSite.noDetectionFill }}</span>\n              </label>\n            </div>\n            <div v-if=\"settings.mapStyleSite.graduated\" class=\"color-row color-row--sub\">\n              <label class=\"color-pick\">\n                <span class=\"color-pick-label\">{{ $t(\"plotOptions.more.fadeTo\") }}</span>\n                <span class=\"color-chip\" :style=\"{background: settings.mapStyleSite.fillTo}\">\n                  <input type=\"color\" :value=\"settings.mapStyleSite.fillTo\" @input=\"setStyleColor('mapStyleSite', 'fillTo', $event.target.value)\">\n                </span>\n                <span class=\"color-hex\">{{ settings.mapStyleSite.fillTo }}</span>\n              </label>\n              <label class=\"color-pick\">\n                <span class=\"color-pick-label\">{{ $t(\"plotOptions.more.fadeTo\") }}</span>\n                <span class=\"color-chip\" :style=\"{background: settings.mapStyleSite.borderTo}\">\n                  <input type=\"color\" :value=\"settings.mapStyleSite.borderTo\" @input=\"setStyleColor('mapStyleSite', 'borderTo', $event.target.value)\">\n                </span>\n                <span class=\"color-hex\">{{ settings.mapStyleSite.borderTo }}</span>\n              </label>\n            </div>\n\n            <div v-if=\"settings.mapStyleSite.graduated\" class=\"gradient-tools\">\n              <div class=\"gradient-preview\" :style=\"{background: cellGradientCss}\"\n                   :title=\"$t('plotOptions.more.gradientPreview')\"></div>\n              <label class=\"style-inline-toggle\">\n                <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\"\n                       v-model=\"settings.mapStyleSite.gradientInvert\" @change=\"emitMapChange()\">\n                <span>{{ $t(\"plotOptions.more.reverse\") }}</span>\n              </label>\n              <label class=\"gradient-blend\">\n                <span>{{ $t(\"plotOptions.more.blend\") }}</span>\n                <select class=\"form-select form-select-sm\" v-model=\"settings.mapStyleSite.gradientMode\" @change=\"emitMapChange()\">\n                  <option v-for=\"m in gradientModes\" :key=\"m\" :value=\"m\">{{ m.toUpperCase() }}</option>\n                </select>\n              </label>\n            </div>\n\n            <div class=\"style-controls\">\n              <label class=\"style-slider\">\n                <span>{{ $t(\"plotOptions.more.opacity\") }}</span>\n                <input type=\"range\" min=\"0.1\" max=\"0.7\" step=\"0.05\"\n                       v-model.number=\"settings.mapStyleSite.opacity\" @input=\"emitMapChange()\">\n              </label>\n              <div class=\"opt-segment opt-segment-3\" role=\"group\">\n                <button type=\"button\" class=\"opt-segment-btn\" :class=\"{'is-active': settings.mapStyleSite.weight === 0}\"\n                        @click=\"selectWeight('mapStyleSite', 0)\">{{ $t(\"plotOptions.more.outlineNone\") }}</button>\n                <button type=\"button\" class=\"opt-segment-btn\" :class=\"{'is-active': settings.mapStyleSite.weight === 1}\"\n                        @click=\"selectWeight('mapStyleSite', 1)\">{{ $t(\"plotOptions.more.outlineThin\") }}</button>\n                <button type=\"button\" class=\"opt-segment-btn\" :class=\"{'is-active': settings.mapStyleSite.weight === 2}\"\n                        @click=\"selectWeight('mapStyleSite', 2)\">{{ $t(\"plotOptions.more.outlineBold\") }}</button>\n              </div>\n            </div>\n          </div>\n\n          <!-- Column 2: distribution + region dimming -->\n          <div class=\"appearance-col\">\n            <div class=\"style-row-head\">\n              <span class=\"style-row-title\">{{ $t(\"plotOptions.more.styleDistribution\") }}</span>\n            </div>\n            <div class=\"color-row\">\n              <label class=\"color-pick\">\n                <span class=\"color-pick-label\">{{ $t(\"plotOptions.more.fill\") }}</span>\n                <span class=\"color-chip\" :style=\"{background: settings.mapStyleDistribution.fill}\">\n                  <input type=\"color\" :value=\"settings.mapStyleDistribution.fill\" @input=\"setStyleColor('mapStyleDistribution', 'fill', $event.target.value)\">\n                </span>\n                <span class=\"color-hex\">{{ settings.mapStyleDistribution.fill }}</span>\n              </label>\n            </div>\n            <div class=\"style-controls\">\n              <label class=\"style-slider\">\n                <span>{{ $t(\"plotOptions.more.opacity\") }}</span>\n                <input type=\"range\" min=\"0.1\" max=\"0.7\" step=\"0.05\"\n                       v-model.number=\"settings.mapStyleDistribution.opacity\" @input=\"emitMapChange()\">\n              </label>\n            </div>\n\n            <div class=\"style-row-head style-row-head--spaced\">\n              <span class=\"style-row-title\">{{ $t(\"plotOptions.more.styleRegionDim\") }}</span>\n            </div>\n            <div class=\"style-controls\">\n              <label class=\"style-slider style-slider-wide\">\n                <span>{{ $t(\"plotOptions.more.dimStrength\") }}</span>\n                <input type=\"range\" min=\"0.15\" max=\"0.75\" step=\"0.05\"\n                       v-model.number=\"settings.mapStyleRegionDim\" @input=\"emitMapChange()\">\n              </label>\n            </div>\n            <p class=\"style-hint\">{{ $t(\"plotOptions.more.dimHint\") }}</p>\n\n            <button type=\"button\" class=\"style-reset\" @click=\"resetStyling()\">\n              {{ $t(\"plotOptions.more.resetStyle\") }}\n            </button>\n          </div>\n        </div>\n      </section>\n\n      <div class=\"options-actions\">\n        <button type=\"button\" class=\"btn-primary-action\" data-bs-toggle=\"collapse\" data-bs-target=\"#collapseMoreOptions\">\n          {{ $t(\"plotOptions.more.close\") }}\n        </button>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport PlotSettingsBase from \"@/components/trends/settings/PlotSettingsBase.vue\";\nimport {set} from \"vue-demi\";\n\nexport default defineComponent({\n  extends: PlotSettingsBase,\n  name: 'PlotSettings2',\n  components: {},\n  props: {\n  },\n  data: function (){\n    return {\n      // Basemap choices (keys must match MyMap.BASEMAPS in map.ts).\n      basemaps: [\n        {key: 'OSM', label: 'OpenStreetMap'},\n        {key: 'Carto', label: 'Carto Light'},\n        {key: 'ArcGIS', label: 'ArcGIS Light'},\n        {key: 'Topo', label: 'Terrain'},\n        {key: 'Satellite', label: 'Satellite'},\n      ],\n      // Gradient blend colour spaces, best perceptual pick first.\n      gradientModes: ['oklch', 'lab', 'lch', 'hsl', 'rgb'],\n    }\n  },\n  // mounted: function() {\n  //   // this.plotVisuals = new MyPlotVisuals();\n  //   return;\n  // },\n  methods: {\n    set,\n    /**\n     * to notify the parent container of changed settings.\n     * @param data a description of what has changed (optional)\n     */\n\n    selectSpecies: function(species){\n      this.settings.species  = species;\n      this.emitChange({species: species});\n    },\n    selectBioGeo: function(bg){\n      this.settings.selectedRegion = bg;\n      this.emitChange({region: bg});\n    },\n    selectGeo1: function(geo1){\n      this.settings.selectedRegion = geo1;\n      this.emitChange({region: geo1});\n    },\n    selectGeoAdm: function(geoAdm){\n      this.settings.selectedRegion = geoAdm;\n      this.emitChange({region: geoAdm});\n    },\n    selectObservationType: function(t){\n      this.settings.observationType  = t;\n      // Picking a concrete type leaves any multi-type layout — set both before the\n      // single emitChange below, so this costs one refetch and not two.\n      this.settings.obsLayout = 'single';\n      this.emitChange({obsType: t});\n    },\n    /** switch how observation types are presented; needs a refetch (server builds them) */\n    selectObsLayout: function(layout){\n      if (this.settings.obsLayout === layout) return;\n      this.settings.obsLayout = layout;\n      this.emitChange({obsLayout: layout});\n    },\n    selectMapLayer: function(layer){\n      this.settings.mapLayer = layer;\n      this.emitMapChange();\n    },\n    setStyleColor: function(styleKey, prop, hex){\n      this.settings[styleKey][prop] = hex;\n      this.emitMapChange();\n    },\n    selectWeight: function(styleKey, weight){\n      this.settings[styleKey].weight = weight;\n      this.emitMapChange();\n    },\n    resetStyling: function(){\n      this.settings.resetMapStyle();\n      this.emitMapChange();\n    },\n    selectMapAggregation: function(mode){\n      if (this.settings.mapAggregation === mode) return;\n      this.settings.mapAggregation = mode;\n      // squares are built server-side, so this needs a refetch (not a client re-render)\n      this.emitChange();\n    },\n    selectYearStart: function(y){\n      if (y >= this.settings.yearEnd){\n        this.settings.yearEnd = y + 10;\n      }\n      this.settings.yearStart = y;\n      this.emitChange({yearStart: this.settings.yearStart, yearEnd: this.settings.yearEnd});\n    },\n    selectYearEnd: function(y){\n      if (y <= this.settings.yearStart){\n        this.settings.yearStart = y - 10;\n      }\n      this.settings.yearEnd = y;\n      this.emitChange({yearStart: this.settings.yearStart, yearEnd: this.settings.yearEnd});\n    },\n    /** WTF? I cannot import the function from the utils.js file. If I do, the preview (npm run serve) does not work! */\n    capitalizeAll: function(s){\n      return s.split(' ').map(w => w[0].toUpperCase() + w.substr(1).toLowerCase()).join(' ');\n    },\n  },\n  computed: {\n    // Live fill-gradient preview. Uses native CSS colour-space interpolation, which\n    // mirrors the map's JS blend closely enough to preview blend mode + direction.\n    cellGradientCss: function(){\n      const s = this.settings.mapStyleSite;\n      const space = {rgb: 'srgb', hsl: 'hsl', lab: 'lab', lch: 'lch', oklch: 'oklch'}[s.gradientMode] || 'oklch';\n      const low = s.gradientInvert ? s.fill : s.fillTo;      // low-count end (left)\n      const high = s.gradientInvert ? s.fillTo : s.fill;     // high-count end (right)\n      return 'linear-gradient(90deg in ' + space + ', ' + low + ', ' + high + ')';\n    },\n  }\n});\n</script>\n\n<style scoped>\n.settings-row {\n  margin-top: 0.5rem;\n  z-index: 1;\n}\n\n.settings-bar {\n  z-index: 1;\n}\n\n.settings-tab-primary {\n  background: #f8fafc;\n  border: 1px solid #e2e8f0;\n  border-bottom: none;\n  border-radius: 0.375rem 0.375rem 0 0;\n}\n\n.settings-dropdown {\n  z-index: 1002;\n}\n\n.settings-dropdown-item {\n  cursor: pointer;\n}\n\n.species-common {\n  color: #64748b;\n}\n\n.prompt-label {\n  font-weight: 600;\n}\n\n.prompt-icon {\n  flex-shrink: 0;\n  margin-right: 0.5rem;\n}\n\n.timespan-label {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  color: #64748b;\n  margin-left: 0.75rem;\n  margin-right: 0.25rem;\n}\n\n.timespan-separator {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  color: #64748b;\n  margin: 0 0.25rem;\n}\n\n.more-options-link {\n  color: #2563eb;\n}\n\n/* In-flow (not an overlay): opening the panel pushes the plot & map down so their\n   live changes stay visible. Full container width, matching the content below. */\n.options-panel {\n  width: 100%;\n  background: #ffffff;\n  border: 1px solid #e2e8f0;\n  border-radius: 0.75rem;\n  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);\n  padding: 1.25rem 1.25rem 1rem;\n  margin: 0.5rem 0 1rem;\n}\n\n.options-panel-head {\n  display: flex;\n  align-items: flex-start;\n  justify-content: space-between;\n  gap: 1rem;\n  padding-bottom: 1rem;\n  margin-bottom: 1rem;\n  border-bottom: 1px solid #eef2f6;\n}\n\n.options-panel-title {\n  font-size: 1.0625rem;\n  font-weight: 600;\n  color: #0f172a;\n  line-height: 1.2;\n}\n\n.options-eyebrow {\n  font-size: 0.6875rem;\n  font-weight: 600;\n  letter-spacing: 0.08em;\n  text-transform: uppercase;\n  color: #94a3b8;\n  margin-bottom: 0.35rem;\n}\n\n.options-close {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 2rem;\n  height: 2rem;\n  flex-shrink: 0;\n  border: 1px solid #e2e8f0;\n  border-radius: 0.5rem;\n  background: #ffffff;\n  color: #64748b;\n  cursor: pointer;\n  font-size: 1.25rem;\n  line-height: 1;\n  transition: all 0.15s ease;\n}\n\n.options-close:hover {\n  background: #f8fafc;\n  color: #0f172a;\n  border-color: #cbd5e1;\n}\n\n.options-grid {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  gap: 0.875rem;\n}\n\n@media (max-width: 575.98px) {\n  .options-grid {\n    grid-template-columns: 1fr;\n  }\n}\n\n.options-card {\n  background: #f8fafc;\n  border: 1px solid #eef2f6;\n  border-radius: 0.625rem;\n  padding: 0.875rem 0.9375rem 1rem;\n}\n\n.options-card .options-eyebrow {\n  margin-bottom: 0.75rem;\n}\n\n.opt-field {\n  margin-bottom: 0.875rem;\n}\n\n.opt-field:last-child {\n  margin-bottom: 0;\n}\n\n.opt-field-inset {\n  margin: -0.25rem 0 0.875rem 0;\n  padding-left: 0.125rem;\n}\n\n.opt-field-muted {\n  opacity: 0.45;\n  pointer-events: none;\n}\n\n.opt-label {\n  display: block;\n  font-size: 0.8125rem;\n  font-weight: 500;\n  color: #475569;\n  margin-bottom: 0.3125rem;\n}\n\n.opt-select {\n  border-color: #dbe2ea;\n  color: #1e293b;\n}\n\n.opt-select:focus {\n  border-color: #2563eb;\n  box-shadow: 0 0 0 0.2rem rgba(37, 99, 235, 0.15);\n}\n\n/* Toggle rows */\n.opt-toggle {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 0.75rem;\n  padding: 0.5rem 0;\n  margin: 0;\n  cursor: pointer;\n  border-top: 1px solid #eef2f6;\n}\n\n.opt-toggle:first-of-type {\n  border-top: none;\n}\n\n.opt-toggle-text {\n  display: flex;\n  flex-direction: column;\n  min-width: 0;\n}\n\n.opt-toggle-title {\n  font-size: 0.875rem;\n  font-weight: 500;\n  color: #1e293b;\n}\n\n.opt-toggle-hint {\n  font-size: 0.75rem;\n  color: #94a3b8;\n  margin-top: 0.0625rem;\n}\n\n.opt-toggle-disabled {\n  cursor: not-allowed;\n}\n\n.opt-toggle-disabled .opt-toggle-title {\n  color: #94a3b8;\n}\n\n.opt-switch {\n  margin: 0;\n  padding: 0;\n  min-height: 0;\n  flex-shrink: 0;\n}\n\n.opt-switch .form-check-input {\n  width: 2.25rem;\n  height: 1.25rem;\n  margin: 0;\n  cursor: pointer;\n  background-color: #cbd5e1;\n  border-color: #cbd5e1;\n}\n\n.opt-switch .form-check-input:checked {\n  background-color: #2563eb;\n  border-color: #2563eb;\n}\n\n.opt-switch .form-check-input:focus {\n  box-shadow: 0 0 0 0.2rem rgba(37, 99, 235, 0.15);\n  border-color: #2563eb;\n}\n\n.opt-switch .form-check-input:disabled {\n  opacity: 0.5;\n}\n\n/* Segmented control (map style) */\n.opt-segment {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  gap: 0.25rem;\n  padding: 0.25rem;\n  background: #eef2f6;\n  border-radius: 0.5rem;\n}\n\n.opt-segment-btn {\n  border: none;\n  background: transparent;\n  color: #64748b;\n  font-size: 0.8125rem;\n  font-weight: 500;\n  padding: 0.375rem 0.5rem;\n  border-radius: 0.375rem;\n  cursor: pointer;\n  transition: all 0.15s ease;\n}\n\n.opt-segment-btn:hover {\n  color: #1e293b;\n}\n\n.opt-segment-btn.is-active {\n  background: #ffffff;\n  color: #2563eb;\n  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.12);\n}\n\n/* Appearance / layer styling */\n.options-card-wide {\n  margin-top: 0.875rem;\n}\n\n.style-row {\n  padding: 0.625rem 0;\n  border-top: 1px solid #eef2f6;\n}\n\n.style-row:first-of-type {\n  border-top: none;\n  padding-top: 0.25rem;\n}\n\n.style-row-head {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 0.75rem;\n  margin-bottom: 0.5rem;\n}\n\n.style-row-title {\n  font-size: 0.8125rem;\n  font-weight: 600;\n  color: #334155;\n}\n\n.style-inline-toggle {\n  display: inline-flex;\n  align-items: center;\n  gap: 0.4rem;\n  margin: 0;\n  font-size: 0.75rem;\n  color: #64748b;\n  cursor: pointer;\n}\n\n.style-inline-toggle .form-check-input {\n  width: 2rem;\n  height: 1.1rem;\n  margin: 0;\n  cursor: pointer;\n  background-color: #cbd5e1;\n  border-color: #cbd5e1;\n}\n\n.style-inline-toggle .form-check-input:checked {\n  background-color: #2563eb;\n  border-color: #2563eb;\n}\n\n/* Two-column appearance layout */\n.appearance-grid {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  gap: 1.25rem 1.75rem;\n}\n\n@media (max-width: 767.98px) {\n  .appearance-grid {\n    grid-template-columns: 1fr;\n    gap: 1rem;\n  }\n}\n\n.appearance-col {\n  min-width: 0;\n}\n\n.appearance-col .style-row-head {\n  margin-bottom: 0.6rem;\n}\n\n.style-row-head--spaced {\n  margin-top: 1rem;\n  padding-top: 0.9rem;\n  border-top: 1px solid #eef2f6;\n}\n\n/* Gradient tools: live preview + direction + blend space */\n.gradient-tools {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: 0.75rem;\n  margin: 0.35rem 0 0.75rem;\n}\n\n.gradient-preview {\n  flex: 1 1 6rem;\n  height: 1.1rem;\n  min-width: 5rem;\n  border-radius: 0.35rem;\n  box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.18);\n}\n\n.gradient-blend {\n  display: inline-flex;\n  align-items: center;\n  gap: 0.4rem;\n  margin: 0;\n  font-size: 0.75rem;\n  color: #64748b;\n}\n\n.gradient-blend select {\n  width: auto;\n  min-width: 5.5rem;\n  border-color: #dbe2ea;\n  color: #1e293b;\n}\n\n.style-hint {\n  margin: 0.5rem 0 0;\n  font-size: 0.72rem;\n  color: #94a3b8;\n  line-height: 1.4;\n}\n\n.style-controls {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: 0.75rem;\n}\n\n/* Fill / border colour rows: two aligned picks per row, one chip each */\n.color-row {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  gap: 0.5rem 1rem;\n  margin-bottom: 0.5rem;\n}\n\n.color-row--sub {\n  margin-top: -0.15rem;\n}\n\n.color-row--sub .color-pick-label {\n  color: #94a3b8;\n}\n\n.color-pick {\n  display: flex;\n  align-items: center;\n  gap: 0.5rem;\n  margin: 0;\n  min-width: 0;\n  cursor: pointer;\n}\n\n.color-pick-label {\n  flex: 0 0 3.25rem;\n  font-size: 0.75rem;\n  font-weight: 500;\n  color: #64748b;\n}\n\n/* Chip shows the current colour and wraps the native picker */\n.color-chip {\n  position: relative;\n  overflow: hidden;\n  display: inline-flex;\n  flex-shrink: 0;\n  width: 2.25rem;\n  height: 1.375rem;\n  border-radius: 0.35rem;\n  box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.2);\n  transition: transform 0.1s ease;\n}\n\n.color-pick:hover .color-chip {\n  transform: scale(1.06);\n}\n\n.color-pick:focus-within .color-chip {\n  box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.2), 0 0 0 0.2rem rgba(37, 99, 235, 0.25);\n}\n\n.color-chip input[type=\"color\"] {\n  position: absolute;\n  inset: -25%;\n  width: 150%;\n  height: 150%;\n  margin: 0;\n  padding: 0;\n  border: none;\n  background: transparent;\n  opacity: 0;\n  cursor: pointer;\n}\n\n.color-hex {\n  font-family: var(--bs-font-monospace, monospace);\n  font-size: 0.7rem;\n  color: #94a3b8;\n  text-transform: lowercase;\n}\n\n.style-slider {\n  display: inline-flex;\n  align-items: center;\n  gap: 0.4rem;\n  margin: 0;\n  font-size: 0.75rem;\n  color: #64748b;\n}\n\n.style-slider input[type=\"range\"] {\n  width: 6rem;\n  accent-color: #2563eb;\n  cursor: pointer;\n}\n\n.style-slider-wide input[type=\"range\"] {\n  width: 10rem;\n}\n\n.opt-segment-3 {\n  grid-template-columns: 1fr 1fr 1fr;\n}\n\n.style-reset {\n  margin-top: 0.75rem;\n  border: 1px solid #e2e8f0;\n  background: #ffffff;\n  color: #475569;\n  font-size: 0.8125rem;\n  padding: 0.35rem 0.85rem;\n  border-radius: 0.45rem;\n  cursor: pointer;\n  transition: all 0.15s ease;\n}\n\n.style-reset:hover {\n  background: #f8fafc;\n  color: #0f172a;\n  border-color: #cbd5e1;\n}\n\n.options-actions {\n  display: flex;\n  justify-content: flex-end;\n  gap: 0.75rem;\n  padding-top: 1rem;\n}\n\n.btn-primary-action {\n  background: #2563eb;\n  color: #ffffff;\n  border: 1px solid #2563eb;\n  padding: 0.5rem 1.5rem;\n  border-radius: 0.5rem;\n  font-size: 0.9375rem;\n  font-weight: 500;\n  cursor: pointer;\n  transition: background 0.15s ease;\n}\n\n.btn-primary-action:hover {\n  background: #1d4ed8;\n}\n\n.highlight {\n  font-weight: bold;\n  position: relative;\n  animation-name: highlight-pulse;\n  animation-duration: 0.4s;\n  animation-iteration-count: infinite;\n  animation-timing-function: ease-in-out;\n  animation-direction: alternate;\n}\n\n@keyframes highlight-pulse {\n  from { left: -1px; color: #991b1b; }\n  to { left: 1px; color: #dc2626; }\n}\n</style>","import script from \"./PlotSettingsBase.vue?vue&type=script&lang=js\"\nexport * from \"./PlotSettingsBase.vue?vue&type=script&lang=js\"\n\nconst __exports__ = script;\n\nexport default __exports__","<script>\nimport {defineComponent} from 'vue';\nimport MyBase from \"@/components/trends/MyBase.vue\";\nimport {MyPlotSettings} from \"@/components/trends/settings/MyPlotSettings\";\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'PlotSettingsBase',\n  components: {},\n  props: {\n  },\n  data: function (){\n    return {\n    }\n  },\n  methods: {\n    emitChange: function(data = undefined){\n      this.$emit('settingsChanged', data);\n    },\n    emitModify: function(data = undefined){\n      this.$emit('settingsModify', data);\n    },\n    /** map-only settings changed: re-render map layers without re-querying the server */\n    emitMapChange: function(){\n      this.$emit('mapSettingsChanged');\n    },\n    handleResponse: function (json){\n      this.settings.handleResponse(json);\n    },\n    buildOptions: function (){\n      return this.settings.buildOptions();\n    },\n    updateMapBounds: function(map){\n      if (this.settings.updateMapBounds(map))\n        this.emitChange();\n    },\n  },\n  computed: {\n    settings: function () {\n      const settings = this.store.plotSettings;\n      if (! settings){\n        this._getStore().plotSettings = new MyPlotSettings(this);\n      }\n      return this.store.plotSettings;\n    },\n    isAdmin: function () {\n      return this.store?.user?.isAdmin || false;\n    },\n  }\n});\n</script>\n","import { render } from \"./PlotSettings2.vue?vue&type=template&id=427ba1c1&scoped=true\"\nimport script from \"./PlotSettings2.vue?vue&type=script&lang=js\"\nexport * from \"./PlotSettings2.vue?vue&type=script&lang=js\"\n\nimport \"./PlotSettings2.vue?vue&type=style&index=0&id=427ba1c1&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-427ba1c1\"]])\n\nexport default __exports__","<template>\n  <div>\n    <picture>\n      <source :srcset=\"getSpeciesImage(img, 'avif')\" type=\"image/avif\">\n      <source :srcset=\"getSpeciesImage(img, 'webp')\" type=\"image/webp\">\n      <source :srcset=\"getSpeciesImage(img, 'jpg')\" type=\"image/jpeg\">\n      <img :src=\"getSpeciesImage(img, 'jpg')\" :class=\"cssClassesImage\">\n    </picture>\n    <div v-if=\"bottomBar === true\" class=\"image-caption\" :class=\"bottomBarClass\" v-html=\"bottomText\">\n    </div>\n  </div>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\n\nexport default defineComponent({\n  name: 'SpeciesImage',\n  components: {},\n  props: {\n    img: Object,\n    bottomBar: {type: Boolean, default: true},\n    bottomBarClass: {type: String, default: ''},\n    bottomBarText: {type: String, default: null},\n  },\n  data: function (){\n    return {\n    }\n  },\n  mounted: function() {\n    return;\n  },\n  methods: {\n    getSpeciesImage: function(imgData, extension){\n      if (! imgData){\n        return \"\";\n      }\n      return '/static/bats/species/' + imgData.p + '.' + extension;\n    },\n  },\n  computed: {\n    cssClassesImage: function(){\n      return {\n        'species-img': true,\n        'species-img-top': this.bottomBar,\n        'species-img-full': !this.bottomBar,\n      }\n    },\n    bottomText: function (){\n      if (this.bottomBarText) return this.bottomBarText;\n      else if (this.img.c) return '© ' + this.img.c;\n      else return 'Unknown photographer';\n    }\n  },\n});\n</script>\n\n<style scoped>\n.species-img {\n  display: block;\n  width: 100%;\n}\n\n.species-img-top {\n  border-radius: 0.625rem 0.625rem 0 0;\n}\n\n.species-img-full {\n  border-radius: 0.625rem;\n}\n\n.image-caption {\n  background: #1e293b;\n  color: #e2e8f0;\n  border-radius: 0 0 0.625rem 0.625rem;\n  text-align: center;\n  padding: 0.375rem 0.5rem;\n  font-size: 0.75rem;\n}\n</style>","import { render } from \"./SpeciesImage.vue?vue&type=template&id=0b21e81d&scoped=true\"\nimport script from \"./SpeciesImage.vue?vue&type=script&lang=js\"\nexport * from \"./SpeciesImage.vue?vue&type=script&lang=js\"\n\nimport \"./SpeciesImage.vue?vue&type=style&index=0&id=0b21e81d&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-0b21e81d\"]])\n\nexport default __exports__","<template>\n  <div :id=\"carouselId\" class=\"carousel slide\" data-bs-interval=\"false\">\n    <div v-if=\"indicators === true\" class=\"carousel-indicators\">\n      <button v-for=\"(img, idx) in images\" :class=\"{'active': idx == 0}\" :key=\"'b'+species.id+'-'+idx\"\n              type=\"button\" :data-bs-target=\"'#' + carouselId\" :data-bs-slide-to=\"idx\">\n      </button>\n    </div>\n    <div class=\"carousel-inner\">\n      <div v-for=\"(img, idx) in images\" class=\"carousel-item\" :class=\"{'active': idx == 0}\" :key=\"'i'+species.id+'-'+idx\" data-bs-interval=\"false\">\n        <SpeciesImage :img=\"img\" :bottom-bar=\"bottomBar\" bottomBarClass=\"pb-5\"></SpeciesImage>\n      </div>\n    </div>\n    <button v-if=\"images.length>1\" class=\"carousel-control-prev\" type=\"button\" :data-bs-target=\"'#' + carouselId\" data-bs-slide=\"prev\">\n      <span class=\"carousel-control-prev-icon\" aria-hidden=\"true\"></span>\n      <span class=\"visually-hidden\">Previous</span>\n    </button>\n    <button v-if=\"images.length>1\" class=\"carousel-control-next\" type=\"button\" :data-bs-target=\"'#' + carouselId\" data-bs-slide=\"next\">\n      <span class=\"carousel-control-next-icon\" aria-hidden=\"true\"></span>\n      <span class=\"visually-hidden\">Next</span>\n    </button>\n  </div>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport SpeciesImage from \"@/components/trends/cards/SpeciesImage.vue\";\n\nexport default defineComponent({\n  name: 'SpeciesImageCarousel',\n  components: {SpeciesImage},\n  props: {\n    species: Object,\n    images: Object,\n    bottomBar: {type: Boolean, default: true},\n    indicators: {type: Boolean, default: true},\n    mkey: {type: String, default: ''}\n  },\n  data: function (){\n    return {\n    }\n  },\n  mounted: function() {\n    return;\n  },\n  methods: {\n  },\n  computed: {\n    carouselId: function (){\n      return 'speciesCarousel' + this.mkey;\n    }\n  },\n});\n</script>\n\n<style scoped>\n.carousel-control-prev,\n.carousel-control-next {\n  opacity: 0.6;\n  transition: opacity 0.15s ease;\n}\n\n.carousel-control-prev:hover,\n.carousel-control-next:hover {\n  opacity: 1;\n}\n</style>\n","import { render } from \"./SpeciesImageCarousel.vue?vue&type=template&id=76ce92c3&scoped=true\"\nimport script from \"./SpeciesImageCarousel.vue?vue&type=script&lang=js\"\nexport * from \"./SpeciesImageCarousel.vue?vue&type=script&lang=js\"\n\nimport \"./SpeciesImageCarousel.vue?vue&type=style&index=0&id=76ce92c3&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-76ce92c3\"]])\n\nexport default __exports__","<template>\n  <div v-if=\"plotError\" class=\"error-banner\">\n    <div v-if=\"user && user.isAdmin\">\n      <h6 class=\"error-heading\">Error (for Admins only): <span class=\"badge-circle badge-admin\"></span></h6>\n      <span class=\"error-msg\">{{plotError.message}}</span>\n    </div>\n    <div v-else>\n      <h6 class=\"error-heading\">{{ $t('trends.plotError.generic_error') }}</h6>\n      <span class=\"error-msg\">{{ $t('trends.plotError.generic_error_text') }}</span>\n    </div>\n  </div>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport MyBase from \"@/components/trends/MyBase.vue\";\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'PlotErrorSmall',\n  components: {},\n  props: {\n    plotError: Object\n  },\n  // data: function (){\n  //   return {\n  //   }\n  // },\n  // mounted: function() {\n  //   return;\n  // },\n  // methods: {\n  //   hello: function () {\n  //     return;\n  //   },\n  // },\n});\n</script>\n\n<style scoped>\n.error-banner {\n  padding: 0.75rem 1rem;\n  background: rgba(220, 38, 38, 0.08);\n  border: 1px solid rgba(220, 38, 38, 0.2);\n  border-radius: 0.375rem;\n}\n\n.error-heading {\n  font-size: 0.8125rem;\n  font-weight: 600;\n  color: #991b1b;\n  margin: 0 0 0.25rem;\n}\n\n.error-msg {\n  font-size: 0.8125rem;\n  color: #1e293b;\n  line-height: 1.5;\n}\n</style>\n","import { render } from \"./PlotErrorSmall.vue?vue&type=template&id=a5c7c8a0&scoped=true\"\nimport script from \"./PlotErrorSmall.vue?vue&type=script&lang=js\"\nexport * from \"./PlotErrorSmall.vue?vue&type=script&lang=js\"\n\nimport \"./PlotErrorSmall.vue?vue&type=style&index=0&id=a5c7c8a0&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-a5c7c8a0\"]])\n\nexport default __exports__","<template>\n  <MyTrendCard :title=\"title\">\n    <template v-if=\"showPicker\" #actions>\n      <label class=\"src-picker\">\n        <span class=\"src-picker-label\">{{ $t('trends.sourcesObsType') }}</span>\n        <select class=\"form-select form-select-sm src-picker-select\" v-model=\"selectedObsId\">\n          <option v-for=\"obsId in obsPlotIds\" :key=\"obsId\" :value=\"obsId\">{{ obsLabel(obsId) }}</option>\n        </select>\n      </label>\n    </template>\n    <div id=\"box3\">\n      <div v-if=\"!store.plotSettings?.species\" class=\"contrib-empty\">\n        <div class=\"empty-inner\">\n          <svg width=\"128\" height=\"128\" class=\"empty-icon\"><use xlink:href=\"#person-heart\"/></svg>\n          <p class=\"empty-lead\">{{ $t('trends.intro.contributors1' )}}</p>\n          <p class=\"empty-lead\">{{ $t('trends.intro.contributors2' )}}</p>\n\n          <p class=\"empty-lead\"><a class=\"empty-link\" href=\"/accounts/signup\">{{ $t('trends.intro.contributorsAccLink') }}</a></p>\n\n          <p class=\"empty-lead\"><a class=\"empty-link\" href=\"mailto:info@batlas.info\">info@batlas.info</a></p>\n\n          <p class=\"empty-lead privacy-note\"><strong>{{ $t('trends.intro.privacy1' )}}</strong><br>\n            {{ $t('trends.intro.privacy1a' )}}\n            <a class=\"empty-link\" href=\"/static/bats/misc/BATLAS-Vereinbarung-Datentransfer-und-Datennutzung.docx\">{{ $t('trends.intro.privacy1b' )}}</a>\n            {{ $t('trends.intro.privacy1c' )}} {{ $t('trends.intro.privacy1d' )}}\n          </p>\n\n          <ul class=\"privacy-list\">\n            <li>{{ $t('trends.intro.privacy2a' )}}</li>\n            <li>{{ $t('trends.intro.privacy2b' )}}</li>\n          </ul>\n\n        </div>\n      </div>\n      <div v-else>\n        <div v-if=\"activeContributors\">\n          <ContributorsAccordion :contributors=\"activeContributors\"></ContributorsAccordion>\n        </div>\n\n        <div v-if=\"user && user.name && user.isAdmin\">\n          <div v-if=\"active.plot_error\" class=\"src-error\">\n            <span class=\"badge-circle badge-admin me-1\"></span>\n            [{{ active.plot_error.name }}]: {{ active.plot_error.message }}\n          </div>\n          <div v-if=\"active.timings\">\n            <TimingsInfo :timings=\"active.timings\"></TimingsInfo>\n          </div>\n          <div v-if=\"active.gof\">\n            <GofDiagnostics :gof-data=\"active.gof\" class=\"admin-section\"></GofDiagnostics>\n          </div>\n          <div v-if=\"active.overall\">\n            <h5 class=\"admin-sub-title\">TRIM <span class=\"badge-circle badge-admin\"></span></h5>\n            <TrimInfo :summary=\"active.summary\" :overall=\"active.overall\" @download=\"download\"></TrimInfo>\n          </div>\n          <DownloadData @download=\"download\" @select-sites=\"$emit('select-sites')\"></DownloadData>\n        </div>\n      </div>\n    </div>\n  </MyTrendCard>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport MyBase from \"@/components/trends/MyBase.vue\";\nimport MyTrendCard from \"@/components/trends/cards/MyTrendCard.vue\";\nimport ContributorsAccordion from \"@/components/trends/cards/ContributorsAccordion.vue\";\nimport TrimInfo from \"@/components/trends/cards/TrimInfo.vue\";\nimport TimingsInfo from \"@/components/trends/cards/TimingsInfo.vue\";\nimport DownloadData from \"@/components/trends/cards/DownloadData.vue\";\nimport GofDiagnostics from \"@/components/trends/GofDiagnostics.vue\";\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'TcMore',\n  components: {GofDiagnostics, DownloadData, TimingsInfo, TrimInfo, ContributorsAccordion, MyTrendCard},\n  props: {\n    overall: Object,\n    summary: Object,\n    timings: Object,\n    contributors: Object,\n    plotError: Object,\n    gof: Object,\n    obsPlots: Object,\n    obsPlotIds: {type: Array, default: () => []},\n  },\n  data: function (){\n    return {\n      /** which type's stats the card shows in a multi-type layout */\n      selectedObsId: null,\n    }\n  },\n  watch: {\n    // The payload changes on every refetch; a type can disappear from it (visibility,\n    // a failed build). Re-clamp so the card can never point at nothing.\n    obsPlotIds: {\n      immediate: true,\n      handler: function (ids){\n        if (!ids.length){\n          this.selectedObsId = null;\n          return;\n        }\n        if (!this.selectedObsId || !ids.includes(this.selectedObsId)){\n          const base = this.store?.plotSettings?.observationType?.id;\n          this.selectedObsId = ids.includes(base) ? base : ids[0];\n        }\n      },\n    },\n  },\n  mounted: function() {\n    return;\n  },\n  methods: {\n    supplierHasInfo: function (supplier){\n      return !!(supplier.url || supplier.desc || supplier.contributors);\n    },\n    download: function (data){\n      this.$emit('download', data);\n    },\n    obsLabel: function (obsId){\n      const key = 'trends.obsTabs.labels.' + obsId;\n      const short = this.$t(key);\n      return (short === key) ? obsId : short;\n    },\n  },\n  computed: {\n    showPicker: function (){\n      return this.store?.plotSettings?.obsLayout !== 'single'\n        && !!this.obsPlots && this.obsPlotIds.length > 1\n        && !!this.store.plotSettings?.species;\n    },\n    /**\n     * The stats this card is showing. In a multi-type layout that is the picked type's\n     * payload; otherwise it is the flat props, which already describe the base type.\n     */\n    active: function (){\n      if (this.showPicker && this.selectedObsId && this.obsPlots[this.selectedObsId]){\n        return this.obsPlots[this.selectedObsId];\n      }\n      return {\n        contributors: this.contributors,\n        overall: this.overall,\n        summary: this.summary,\n        timings: this.timings,\n        gof: this.gof,\n        plot_error: this.plotError,\n      };\n    },\n    activeContributors: function (){\n      return this.active.contributors;\n    },\n    title: function(){\n      if (this.activeContributors){\n        return this.$tc('trends.nbSources', {n: this.activeContributors.length})\n      }\n      return this.$t('trends.contribute');\n    }\n  }\n});\n</script>\n\n<style scoped>\n.contrib-empty {\n  max-width: 720px;\n  margin: 0 auto;\n}\n\n.empty-inner {\n  text-align: center;\n}\n\n.empty-icon {\n  color: #94a3b8;\n}\n\n.empty-lead {\n  font-size: 1.0625rem;\n  color: #64748b;\n  line-height: 1.6;\n  margin: 0.5rem 0;\n}\n\n.empty-lead:first-of-type {\n  margin-top: 1.5rem;\n}\n\n.empty-link {\n  color: #2563eb;\n  text-decoration: underline;\n  text-underline-offset: 2px;\n}\n\n.empty-link:hover {\n  color: #1d4ed8;\n}\n\n.privacy-note {\n  margin-top: 1.5rem;\n}\n\n.privacy-list {\n  text-align: left;\n  margin-top: 1.5rem;\n  font-size: 1.0625rem;\n  color: #64748b;\n  line-height: 1.6;\n  padding-left: 1.5rem;\n}\n\n.privacy-list li {\n  margin: 0.5rem 0;\n}\n\n.admin-section {\n  margin-top: 1.5rem;\n}\n\n.admin-sub-title {\n  font-size: 1rem;\n  font-weight: 600;\n  color: #1e293b;\n  margin: 1.5rem 0 0.75rem;\n}\n\n.src-picker {\n  display: inline-flex;\n  align-items: center;\n  gap: 0.4rem;\n  margin: 0;\n}\n\n.src-picker-label {\n  font-size: 0.8rem;\n  font-weight: 600;\n  color: #64748b;\n  white-space: nowrap;\n}\n\n.src-picker-select {\n  width: auto;\n  font-size: 0.8rem;\n}\n\n.src-error {\n  font-size: 0.8125rem;\n  color: #991b1b;\n  margin-top: 1rem;\n}\n</style>\n","<template>\n  <div v-if=\"contributors\" class=\"contrib-list\">\n    <div\n      class=\"file-card\"\n      v-for=\"(contributor, index) in contributors\"\n      :key=\"index\"\n    >\n      <!-- Card Header -->\n      <div\n        class=\"file-header\"\n        :class=\"{ 'clickable': supplierHasInfo(contributor) }\"\n        @click=\"supplierHasInfo(contributor) && toggleOpen(index)\"\n      >\n        <div class=\"file-header-left\">\n          <div class=\"contrib-icon-wrap\">\n            <img v-if=\"contributor.icon\" :src=\"'/dl/pic/'+contributor.icon\" class=\"contrib-icon-img\">\n            <svg v-else class=\"contrib-icon-svg\"><use xlink:href=\"#bat1\"/></svg>\n          </div>\n          <div class=\"file-header-info\">\n            <h6 class=\"file-name\">{{ contributor.name }}</h6>\n            <div class=\"file-meta\">\n              <span class=\"meta-tag\">{{ $tc('trends.contribCounts1', {n: contributor.cnt}) }}</span>\n              <span class=\"meta-tag\">{{ $tc('trends.contribCounts2', {n: contributor.locs}) }}</span>\n            </div>\n          </div>\n        </div>\n        <div class=\"file-header-right\" v-if=\"supplierHasInfo(contributor)\">\n          <span class=\"collapse-indicator\">{{ openItems[index] ? '&#9650;' : '&#9660;' }}</span>\n        </div>\n      </div>\n\n      <!-- Card Body -->\n      <div v-if=\"supplierHasInfo(contributor)\" v-show=\"openItems[index]\" class=\"file-body\">\n        <p v-if=\"contributor.description\" class=\"contrib-desc\">{{ contributor.description }}</p>\n        <p v-if=\"contributor.contributors\" class=\"contrib-people\">{{ contributor.contributors }}</p>\n        <p v-if=\"contributor.url\" class=\"contrib-url\"><a :href=\"contributor.url\">{{ contributor.url }}</a></p>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport MyBase from \"@/components/trends/MyBase.vue\";\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'ContributorsAccordion',\n  components: {},\n  props: {\n    contributors: Object,\n  },\n  data: function (){\n    return {\n      openItems: {},\n    }\n  },\n  mounted: function() {\n    return;\n  },\n  methods: {\n    supplierHasInfo: function (supplier){\n      if (supplier.url || supplier.desc || supplier.contributors) return true;\n      return false;\n    },\n    toggleOpen: function (index){\n      const updated = {...this.openItems};\n      updated[index] = !updated[index];\n      this.openItems = updated;\n    },\n  },\n});\n</script>\n\n<style scoped>\n.contrib-list {\n  display: flex;\n  flex-direction: column;\n  gap: 0.625rem;\n}\n\n.file-card {\n  --color-primary: #2563eb;\n  --color-primary-light: rgba(37, 99, 235, 0.08);\n  --color-primary-muted: rgba(37, 99, 235, 0.15);\n  --color-text: #1e293b;\n  --color-text-muted: #64748b;\n  --color-border: #e2e8f0;\n  --color-border-light: #f1f5f9;\n  --color-bg: #ffffff;\n  --color-bg-subtle: #f8fafc;\n  --radius-md: 0.625rem;\n  --radius-lg: 0.875rem;\n  --transition-fast: 0.15s ease;\n\n  background: var(--color-bg);\n  border: 1px solid var(--color-border);\n  border-radius: var(--radius-lg);\n  overflow: hidden;\n}\n\n/* Header */\n.file-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 0.875rem 1.25rem;\n  background: var(--color-bg-subtle);\n  border-bottom: 1px solid var(--color-border-light);\n  gap: 1rem;\n}\n\n.file-header.clickable {\n  cursor: pointer;\n  transition: background var(--transition-fast);\n}\n\n.file-header.clickable:hover {\n  background: #f1f5f9;\n}\n\n.file-header-left {\n  display: flex;\n  align-items: center;\n  gap: 0.75rem;\n  min-width: 0;\n}\n\n.contrib-icon-wrap {\n  width: 48px;\n  height: 48px;\n  flex-shrink: 0;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n\n.contrib-icon-img {\n  max-width: 48px;\n  max-height: 48px;\n  width: auto;\n  height: auto;\n  border-radius: var(--radius-md);\n}\n\n.contrib-icon-svg {\n  width: 32px;\n  height: 32px;\n  color: #94a3b8;\n}\n\n.file-header-info {\n  min-width: 0;\n}\n\n.file-name {\n  margin: 0;\n  font-size: 0.9375rem;\n  font-weight: 600;\n  color: var(--color-text);\n  line-height: 1.4;\n}\n\n.file-meta {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 0.5rem;\n  margin-top: 0.25rem;\n}\n\n.meta-tag {\n  font-size: 0.75rem;\n  color: var(--color-text-muted);\n}\n\n.file-header-right {\n  display: flex;\n  align-items: center;\n  gap: 0.75rem;\n  flex-shrink: 0;\n}\n\n.collapse-indicator {\n  font-size: 0.75rem;\n  color: var(--color-text-muted);\n}\n\n/* Body */\n.file-body {\n  padding: 1.25rem;\n}\n\n.contrib-desc {\n  font-size: 0.875rem;\n  color: var(--color-text-muted);\n  line-height: 1.6;\n  margin: 0 0 0.75rem;\n}\n\n.contrib-desc:last-child {\n  margin-bottom: 0;\n}\n\n.contrib-people {\n  font-size: 0.875rem;\n  color: var(--color-text);\n  line-height: 1.5;\n  margin: 0 0 0.75rem;\n}\n\n.contrib-people:last-child {\n  margin-bottom: 0;\n}\n\n.contrib-url {\n  margin: 0;\n}\n\n.contrib-url a {\n  color: var(--color-primary);\n  text-decoration: underline;\n  text-underline-offset: 2px;\n  font-size: 0.875rem;\n}\n\n.contrib-url a:hover {\n  color: #1d4ed8;\n}\n</style>\n","import { render } from \"./ContributorsAccordion.vue?vue&type=template&id=6d7e224a&scoped=true\"\nimport script from \"./ContributorsAccordion.vue?vue&type=script&lang=js\"\nexport * from \"./ContributorsAccordion.vue?vue&type=script&lang=js\"\n\nimport \"./ContributorsAccordion.vue?vue&type=style&index=0&id=6d7e224a&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-6d7e224a\"]])\n\nexport default __exports__","<template>\n  <div class=\"trim-info\">\n    <table class=\"data-table\">\n      <tbody>\n      <tr :class=\"{'row-danger': overall.slope.meaning === 'Uncertain'}\"><td class=\"cell-label\">Trend</td><td>{{overall.slope.meaning}}</td></tr>\n      <tr><td class=\"cell-label\">p</td><td>{{overall.slope.p}}</td></tr>\n      <tr><td class=\"cell-label\">add</td><td>{{overall.slope.add.toFixed(8)}} ({{overall.slope.se_add.toFixed(8)}})</td></tr>\n      <tr><td class=\"cell-label\">mul</td><td>{{overall.slope.mul.toFixed(8)}} ({{overall.slope.se_mul.toFixed(8)}})</td></tr>\n      <tr :class=\"{'row-danger': summary.convergence.startsWith('No convergence')}\"><td class=\"cell-label\">Convergence</td><td>{{summary.convergence}}</td></tr>\n      <tr v-if=\"summary.overdispersion\"><td class=\"cell-label\">overdispersion</td><td>{{summary.overdispersion.toFixed(8)}}</td></tr>\n      <tr v-if=\"summary.serialcorrelation\"><td class=\"cell-label\">serial correlation</td><td>{{summary.serialcorrelation.toFixed(8)}}</td></tr>\n      </tbody>\n    </table>\n\n    <h5 class=\"sub-title\">Timings</h5>\n    <table class=\"data-table\">\n      <tbody>\n      <tr v-for=\"(m,idx) in summary.timings\" :key=\"idx\"><td class=\"cell-label\">{{ m.m }}</td><td class=\"cell-mono\">{{m.t.toFixed(3)}} seconds</td></tr>\n      </tbody>\n    </table>\n\n    <h5 class=\"sub-title\">Goodness Of Fit</h5>\n    <table class=\"data-table\">\n      <tbody>\n      <tr><td class=\"cell-label\">Chi Square</td><td>{{summary.gof.chi2.chi2.toFixed(2)}}</td><td>{{summary.gof.chi2.df}}</td><td>{{summary.gof.chi2.p}}</td></tr>\n      <tr><td class=\"cell-label\">Likelihood Ratio</td><td>{{summary.gof.lr.LR.toFixed(2)}}</td><td>{{summary.gof.lr.df}}</td><td>{{summary.gof.lr.p}}</td></tr>\n      <tr><td class=\"cell-label\">AIC</td><td colspan=\"3\">{{summary.gof.aic.toFixed(2)}}</td></tr>\n      </tbody>\n    </table>\n  </div>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport MyBase from \"@/components/trends/MyBase.vue\";\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'TrimInfo',\n  components: {},\n  props: {\n    overall: Object,\n    summary: Object,\n  },\n  data: function (){\n    return {\n    }\n  },\n  mounted: function() {\n    return;\n  },\n  // methods: {\n  //   downloadCsv: function () {\n  //     this.$emit('download', {type: 'csv'});\n  //   },\n  //   downloadCsvDemo: function () {\n  //     this.$emit('download', {type: 'csv', demo: 1});\n  //   },\n  // },\n});\n</script>\n\n<style scoped>\n.data-table {\n  width: 100%;\n  border-collapse: collapse;\n  font-size: 0.8125rem;\n}\n\n.data-table td {\n  padding: 0.375rem 0.5rem;\n  border-bottom: 1px solid #f1f5f9;\n  color: #1e293b;\n}\n\n.data-table tr:hover {\n  background: #f8fafc;\n}\n\n.cell-label {\n  font-weight: 500;\n  color: #64748b;\n}\n\n.cell-mono {\n  font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n}\n\n.row-danger {\n  background: rgba(220, 38, 38, 0.08);\n}\n\n.row-danger td {\n  color: #991b1b;\n}\n\n.sub-title {\n  font-size: 1rem;\n  font-weight: 600;\n  color: #1e293b;\n  margin: 1.5rem 0 0.75rem;\n}\n</style>\n","import { render } from \"./TrimInfo.vue?vue&type=template&id=b7fbc67e&scoped=true\"\nimport script from \"./TrimInfo.vue?vue&type=script&lang=js\"\nexport * from \"./TrimInfo.vue?vue&type=script&lang=js\"\n\nimport \"./TrimInfo.vue?vue&type=style&index=0&id=b7fbc67e&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-b7fbc67e\"]])\n\nexport default __exports__","<template>\n  <div class=\"timings-info\">\n    <h5 class=\"timings-title\">Timings <span class=\"badge-circle badge-admin\"></span></h5>\n    <table class=\"data-table\">\n      <tbody>\n      <tr v-for=\"(m,idx) in timings\" :key=\"idx\"><td class=\"timing-label\">{{ m.m }}</td><td class=\"timing-value\">{{m.t.toFixed(3)}} seconds</td></tr>\n      </tbody>\n    </table>\n  </div>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport MyBase from \"@/components/trends/MyBase.vue\";\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'TimingsInfo',\n  components: {},\n  props: {\n    timings: Object\n  },\n  data: function (){\n    return {\n    }\n  },\n  mounted: function() {\n    return;\n  },\n});\n</script>\n\n<style scoped>\n.timings-title {\n  font-size: 1rem;\n  font-weight: 600;\n  color: #1e293b;\n  margin: 1.5rem 0 0.75rem;\n}\n\n.data-table {\n  width: 100%;\n  border-collapse: collapse;\n  font-size: 0.8125rem;\n}\n\n.data-table td {\n  padding: 0.375rem 0.5rem;\n  border-bottom: 1px solid #f1f5f9;\n  color: #1e293b;\n}\n\n.data-table tr:hover {\n  background: #f8fafc;\n}\n\n.timing-label {\n  font-weight: 500;\n}\n\n.timing-value {\n  color: #64748b;\n  font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n}\n</style>\n","import { render } from \"./TimingsInfo.vue?vue&type=template&id=e40671ec&scoped=true\"\nimport script from \"./TimingsInfo.vue?vue&type=script&lang=js\"\nexport * from \"./TimingsInfo.vue?vue&type=script&lang=js\"\n\nimport \"./TimingsInfo.vue?vue&type=style&index=0&id=e40671ec&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-e40671ec\"]])\n\nexport default __exports__","<template>\n  <div class=\"download-section\">\n    <h5 class=\"download-title\">Download Data <span class=\"badge-circle badge-admin\"></span></h5>\n    <div class=\"download-actions\">\n      <button class=\"btn-primary-action\" @click=\"downloadCsv\">CSV</button>\n      <button v-if=\"showSelectSites\" class=\"btn-outline-action\" @click=\"$emit('select-sites')\">\n        {{ $t('trends.selectSites') }}</button>\n    </div>\n  </div>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport MyBase from \"@/components/trends/MyBase.vue\";\nimport {canSeeSiteShortcuts} from \"@/lib/siteShortcuts\";\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'DownloadData',\n  components: {},\n  props: {\n  },\n  computed: {\n    showSelectSites() {\n      // shared shortcut gate + admins only on the public trends page\n      return canSeeSiteShortcuts(this.user) && !!this.user?.isAdmin;\n    },\n  },\n  data: function (){\n    return {\n    }\n  },\n  mounted: function() {\n    return;\n  },\n  methods: {\n    downloadCsv: function () {\n      this.$emit('download', {type: 'csv'});\n    },\n    downloadCsvDemo: function () {\n      this.$emit('download', {type: 'csv', demo: 1});\n    },\n  },\n});\n</script>\n\n<style scoped>\n.download-title {\n  font-size: 1rem;\n  font-weight: 600;\n  color: #1e293b;\n  margin: 1.5rem 0 0.75rem;\n}\n\n.btn-primary-action {\n  display: inline-flex;\n  align-items: center;\n  gap: 0.375rem;\n  padding: 0.5rem 1.25rem;\n  font-size: 0.875rem;\n  font-weight: 500;\n  color: white;\n  background: #2563eb;\n  border: none;\n  border-radius: 0.625rem;\n  cursor: pointer;\n  transition: all 0.15s ease;\n}\n\n.btn-primary-action:hover {\n  background: #1d4ed8;\n  transform: translateY(-1px);\n  box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);\n}\n\n.download-actions {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: 0.5rem;\n}\n\n.btn-outline-action {\n  display: inline-flex;\n  align-items: center;\n  gap: 0.375rem;\n  padding: 0.5rem 1.25rem;\n  font-size: 0.875rem;\n  font-weight: 500;\n  color: #2563eb;\n  background: transparent;\n  border: 1px solid rgba(37, 99, 235, 0.35);\n  border-radius: 0.625rem;\n  cursor: pointer;\n  transition: all 0.15s ease;\n}\n\n.btn-outline-action:hover {\n  background: rgba(37, 99, 235, 0.08);\n  border-color: #2563eb;\n  transform: translateY(-1px);\n  box-shadow: 0 4px 12px rgba(37, 99, 235, 0.15);\n}\n</style>\n","import { render } from \"./DownloadData.vue?vue&type=template&id=fa77bfa4&scoped=true\"\nimport script from \"./DownloadData.vue?vue&type=script&lang=js\"\nexport * from \"./DownloadData.vue?vue&type=script&lang=js\"\n\nimport \"./DownloadData.vue?vue&type=style&index=0&id=fa77bfa4&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-fa77bfa4\"]])\n\nexport default __exports__","<template>\n  <div class=\"gof-diagnostics\">\n    <div class=\"gof-header\">\n      <div class=\"gof-title-group\">\n        <svg width=\"20\" height=\"20\"><use xlink:href=\"#bar-chart\"/></svg>\n        <h5 class=\"gof-title\">{{ $t('trends.gof.title') }} <span class=\"badge-circle badge-admin\"></span></h5>\n      </div>\n      <button class=\"btn-ghost\" @click=\"toggleExpanded\">\n        {{ expanded ? $t('trends.gof.collapse') : $t('trends.gof.expand') }}\n      </button>\n    </div>\n\n    <div v-if=\"expanded && gofData\" class=\"gof-content\">\n      <div v-if=\"gofData.stats\" class=\"stats-summary\">\n        <div class=\"stats-row\">\n          <div class=\"stat-item\">\n            <span class=\"stat-key\">{{ $t('trends.gof.stats.deviance') }}</span>\n            <span class=\"stat-val\">{{ formatNumber(gofData.stats.deviance) }}</span>\n          </div>\n          <div class=\"stat-item\">\n            <span class=\"stat-key\">{{ $t('trends.gof.stats.aic') }}</span>\n            <span class=\"stat-val\">{{ formatNumber(gofData.stats.aic) }}</span>\n          </div>\n          <div class=\"stat-item\">\n            <span class=\"stat-key\">{{ $t('trends.gof.stats.gcv') }}</span>\n            <span class=\"stat-val\">{{ formatNumber(gofData.stats.gcv) }}</span>\n          </div>\n          <div class=\"stat-item\">\n            <span class=\"stat-key\">{{ $t('trends.gof.stats.n') }}</span>\n            <span class=\"stat-val\">{{ gofData.stats.n_sampled }} / {{ gofData.stats.n_points }}</span>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"plots-grid\">\n        <div class=\"plot-card\">\n          <div class=\"plot-card-header\">{{ $t('trends.gof.qq.title') }}</div>\n          <div class=\"plot-card-body\">\n            <div :id=\"plotIds.qq\" class=\"gof-plot\"></div>\n            <span class=\"plot-hint\">{{ $t('trends.gof.qq.hint') }}</span>\n          </div>\n        </div>\n\n        <div class=\"plot-card\">\n          <div class=\"plot-card-header\">{{ $t('trends.gof.residVsFit.title') }}</div>\n          <div class=\"plot-card-body\">\n            <div :id=\"plotIds.residVsFit\" class=\"gof-plot\"></div>\n            <span class=\"plot-hint\">{{ $t('trends.gof.residVsFit.hint') }}</span>\n          </div>\n        </div>\n\n        <div class=\"plot-card\">\n          <div class=\"plot-card-header\">{{ $t('trends.gof.histogram.title') }}</div>\n          <div class=\"plot-card-body\">\n            <div :id=\"plotIds.histogram\" class=\"gof-plot\"></div>\n            <span class=\"plot-hint\">{{ $t('trends.gof.histogram.hint') }}</span>\n          </div>\n        </div>\n\n        <div class=\"plot-card\">\n          <div class=\"plot-card-header\">{{ $t('trends.gof.obsVsFit.title') }}</div>\n          <div class=\"plot-card-body\">\n            <div :id=\"plotIds.obsVsFit\" class=\"gof-plot\"></div>\n            <span class=\"plot-hint\">{{ $t('trends.gof.obsVsFit.hint') }}</span>\n          </div>\n        </div>\n      </div>\n    </div>\n\n    <div v-else-if=\"expanded && !gofData\" class=\"info-banner\">\n      {{ $t('trends.gof.noData') }}\n    </div>\n  </div>\n</template>\n\n<script>\nimport { defineComponent } from 'vue';\nimport * as d3 from 'd3';\n\nexport default defineComponent({\n  name: 'GofDiagnostics',\n  props: {\n    gofData: {\n      type: Object,\n      default: null\n    },\n    plotIdPrefix: {\n      type: String,\n      default: 'gof'\n    }\n  },\n  data() {\n    return {\n      expanded: false\n    };\n  },\n  computed: {\n    plotIds() {\n      return {\n        qq: `${this.plotIdPrefix}-qq`,\n        residVsFit: `${this.plotIdPrefix}-residVsFit`,\n        histogram: `${this.plotIdPrefix}-histogram`,\n        obsVsFit: `${this.plotIdPrefix}-obsVsFit`\n      };\n    }\n  },\n  watch: {\n    expanded(val) {\n      if (val && this.gofData) {\n        this.$nextTick(() => this.renderPlots());\n      }\n    },\n    gofData() {\n      if (this.expanded && this.gofData) {\n        this.$nextTick(() => this.renderPlots());\n      }\n    }\n  },\n  methods: {\n    toggleExpanded() {\n      this.expanded = !this.expanded;\n    },\n    formatNumber(n) {\n      if (n === null || n === undefined) return 'N/A';\n      return typeof n === 'number' ? n.toFixed(2) : n;\n    },\n    renderPlots() {\n      if (!this.gofData) return;\n      \n      // Render each diagnostic plot\n      if (this.gofData.qq) this.renderQQPlot();\n      if (this.gofData.residVsFit) this.renderResidVsFitPlot();\n      if (this.gofData.histogram) this.renderHistogram();\n      if (this.gofData.obsVsFit) this.renderObsVsFitPlot();\n    },\n    \n    getPlotDimensions(elementId) {\n      const element = document.getElementById(elementId);\n      if (!element) return { width: 300, height: 200 };\n      const rect = element.getBoundingClientRect();\n      return { \n        width: rect.width || 300, \n        height: 200 \n      };\n    },\n    \n    renderQQPlot() {\n      const { qq } = this.gofData;\n      const elementId = this.plotIds.qq;\n      const { width, height } = this.getPlotDimensions(elementId);\n      const margin = { top: 10, right: 20, bottom: 30, left: 40 };\n      \n      // Clear previous plot\n      d3.select(`#${elementId}`).selectAll('*').remove();\n      \n      const svg = d3.select(`#${elementId}`)\n        .append('svg')\n        .attr('width', width)\n        .attr('height', height);\n      \n      const g = svg.append('g')\n        .attr('transform', `translate(${margin.left},${margin.top})`);\n      \n      const innerWidth = width - margin.left - margin.right;\n      const innerHeight = height - margin.top - margin.bottom;\n      \n      const xExtent = d3.extent(qq.theoretical);\n      const yExtent = d3.extent(qq.residuals);\n      \n      const x = d3.scaleLinear()\n        .domain(xExtent)\n        .range([0, innerWidth]);\n      \n      const y = d3.scaleLinear()\n        .domain(yExtent)\n        .range([innerHeight, 0]);\n      \n      // Reference line (y = x)\n      const lineExtent = [Math.max(xExtent[0], yExtent[0]), Math.min(xExtent[1], yExtent[1])];\n      g.append('line')\n        .attr('x1', x(lineExtent[0]))\n        .attr('y1', y(lineExtent[0]))\n        .attr('x2', x(lineExtent[1]))\n        .attr('y2', y(lineExtent[1]))\n        .attr('stroke', '#dc3545')\n        .attr('stroke-width', 1.5)\n        .attr('stroke-dasharray', '5,5');\n      \n      // Points\n      const points = qq.theoretical.map((t, i) => ({ x: t, y: qq.residuals[i] }));\n      g.selectAll('circle')\n        .data(points)\n        .enter()\n        .append('circle')\n        .attr('cx', d => x(d.x))\n        .attr('cy', d => y(d.y))\n        .attr('r', 2)\n        .attr('fill', 'steelblue')\n        .attr('opacity', 0.5);\n      \n      // Axes\n      g.append('g')\n        .attr('transform', `translate(0,${innerHeight})`)\n        .call(d3.axisBottom(x).ticks(5));\n      \n      g.append('g')\n        .call(d3.axisLeft(y).ticks(5));\n    },\n    \n    renderResidVsFitPlot() {\n      const { residVsFit } = this.gofData;\n      const elementId = this.plotIds.residVsFit;\n      const { width, height } = this.getPlotDimensions(elementId);\n      const margin = { top: 10, right: 20, bottom: 30, left: 40 };\n\n      d3.select(`#${elementId}`).selectAll('*').remove();\n\n      const svg = d3.select(`#${elementId}`)\n        .append('svg')\n        .attr('width', width)\n        .attr('height', height);\n\n      const g = svg.append('g')\n        .attr('transform', `translate(${margin.left},${margin.top})`);\n\n      const innerWidth = width - margin.left - margin.right;\n      const innerHeight = height - margin.top - margin.bottom;\n\n      // Use eta (linear predictor) if available, fall back to fitted for backwards compatibility\n      const xData = residVsFit.eta || residVsFit.fitted;\n\n      const x = d3.scaleLinear()\n        .domain(d3.extent(xData))\n        .range([0, innerWidth]);\n\n      const y = d3.scaleLinear()\n        .domain(d3.extent(residVsFit.residuals))\n        .range([innerHeight, 0]);\n\n      // Horizontal reference line at y = 0\n      g.append('line')\n        .attr('x1', 0)\n        .attr('y1', y(0))\n        .attr('x2', innerWidth)\n        .attr('y2', y(0))\n        .attr('stroke', '#dc3545')\n        .attr('stroke-width', 1.5)\n        .attr('stroke-dasharray', '5,5');\n\n      // Points\n      const points = xData.map((val, i) => ({ x: val, y: residVsFit.residuals[i] }));\n      g.selectAll('circle')\n        .data(points)\n        .enter()\n        .append('circle')\n        .attr('cx', d => x(d.x))\n        .attr('cy', d => y(d.y))\n        .attr('r', 2)\n        .attr('fill', 'steelblue')\n        .attr('opacity', 0.5);\n\n      // Axes\n      g.append('g')\n        .attr('transform', `translate(0,${innerHeight})`)\n        .call(d3.axisBottom(x).ticks(5));\n\n      g.append('g')\n        .call(d3.axisLeft(y).ticks(5));\n    },\n    \n    renderHistogram() {\n      const { histogram } = this.gofData;\n      const elementId = this.plotIds.histogram;\n      const { width, height } = this.getPlotDimensions(elementId);\n      const margin = { top: 10, right: 20, bottom: 30, left: 40 };\n\n      d3.select(`#${elementId}`).selectAll('*').remove();\n\n      const svg = d3.select(`#${elementId}`)\n        .append('svg')\n        .attr('width', width)\n        .attr('height', height);\n\n      const g = svg.append('g')\n        .attr('transform', `translate(${margin.left},${margin.top})`);\n\n      const innerWidth = width - margin.left - margin.right;\n      const innerHeight = height - margin.top - margin.bottom;\n\n      // Support both old format (breaks/counts) and new format (xmin/xmax/count)\n      let bins, xDomain, counts;\n      if (histogram.xmin && histogram.xmax) {\n        // New format from gratia-style extraction\n        bins = histogram.xmin.map((xmin, i) => ({\n          x0: xmin,\n          x1: histogram.xmax[i],\n          count: histogram.count[i]\n        }));\n        xDomain = [histogram.xmin[0], histogram.xmax[histogram.xmax.length - 1]];\n        counts = histogram.count;\n      } else {\n        // Old format with breaks/counts\n        bins = histogram.breaks.slice(0, -1).map((b, i) => ({\n          x0: b,\n          x1: histogram.breaks[i + 1],\n          count: histogram.counts[i]\n        }));\n        xDomain = [histogram.breaks[0], histogram.breaks[histogram.breaks.length - 1]];\n        counts = histogram.counts;\n      }\n\n      const x = d3.scaleLinear()\n        .domain(xDomain)\n        .range([0, innerWidth]);\n\n      const y = d3.scaleLinear()\n        .domain([0, d3.max(counts)])\n        .range([innerHeight, 0]);\n\n      // Bars\n      g.selectAll('rect')\n        .data(bins)\n        .enter()\n        .append('rect')\n        .attr('x', d => x(d.x0) + 1)\n        .attr('width', d => Math.max(0, x(d.x1) - x(d.x0) - 1))\n        .attr('y', d => y(d.count))\n        .attr('height', d => innerHeight - y(d.count))\n        .attr('fill', 'steelblue')\n        .attr('opacity', 0.7);\n\n      // Axes\n      g.append('g')\n        .attr('transform', `translate(0,${innerHeight})`)\n        .call(d3.axisBottom(x).ticks(5));\n\n      g.append('g')\n        .call(d3.axisLeft(y).ticks(5));\n    },\n    \n    renderObsVsFitPlot() {\n      const { obsVsFit } = this.gofData;\n      const elementId = this.plotIds.obsVsFit;\n      const { width, height } = this.getPlotDimensions(elementId);\n      const margin = { top: 10, right: 20, bottom: 30, left: 40 };\n      \n      d3.select(`#${elementId}`).selectAll('*').remove();\n      \n      const svg = d3.select(`#${elementId}`)\n        .append('svg')\n        .attr('width', width)\n        .attr('height', height);\n      \n      const g = svg.append('g').attr('transform', `translate(${margin.left},${margin.top})`);\n      \n      const innerWidth = width - margin.left - margin.right;\n      const innerHeight = height - margin.top - margin.bottom;\n      \n      const allVals = [...obsVsFit.fitted, ...obsVsFit.observed];\n      const extent = d3.extent(allVals);\n      \n      const x = d3.scaleLinear()\n        .domain(extent)\n        .range([0, innerWidth]);\n      \n      const y = d3.scaleLinear()\n        .domain(extent)\n        .range([innerHeight, 0]);\n      \n      // Reference line (y = x)\n      g.append('line')\n        .attr('x1', x(extent[0]))\n        .attr('y1', y(extent[0]))\n        .attr('x2', x(extent[1]))\n        .attr('y2', y(extent[1]))\n        .attr('stroke', '#dc3545')\n        .attr('stroke-width', 1.5)\n        .attr('stroke-dasharray', '5,5');\n      \n      // Points\n      const points = obsVsFit.fitted.map((f, i) => ({ x: f, y: obsVsFit.observed[i] }));\n      g.selectAll('circle')\n        .data(points)\n        .enter()\n        .append('circle')\n        .attr('cx', d => x(d.x))\n        .attr('cy', d => y(d.y))\n        .attr('r', 2)\n        .attr('fill', 'steelblue')\n        .attr('opacity', 0.5);\n      \n      // Axes\n      g.append('g')\n        .attr('transform', `translate(0,${innerHeight})`)\n        .call(d3.axisBottom(x).ticks(5));\n      \n      g.append('g')\n        .call(d3.axisLeft(y).ticks(5));\n    }\n  }\n});\n</script>\n\n<style scoped>\n.gof-diagnostics {\n  --color-primary: #2563eb;\n  --color-text: #1e293b;\n  --color-text-muted: #64748b;\n  --color-border: #e2e8f0;\n  --color-border-light: #f1f5f9;\n  --color-bg: #ffffff;\n  --color-bg-subtle: #f8fafc;\n  --radius-sm: 0.375rem;\n  --radius-md: 0.625rem;\n  --radius-lg: 0.875rem;\n  --transition-fast: 0.15s ease;\n\n  margin-top: 1.5rem;\n  background: var(--color-bg-subtle);\n  border: 1px solid var(--color-border);\n  border-radius: var(--radius-lg);\n  overflow: hidden;\n}\n\n.gof-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 0.75rem 1rem;\n  border-bottom: 1px solid var(--color-border-light);\n}\n\n.gof-title-group {\n  display: flex;\n  align-items: center;\n  gap: 0.5rem;\n  color: var(--color-text-muted);\n}\n\n.gof-title {\n  margin: 0;\n  font-size: 0.9375rem;\n  font-weight: 600;\n  color: var(--color-text);\n}\n\n.btn-ghost {\n  padding: 0.25rem 0.75rem;\n  font-size: 0.8125rem;\n  font-weight: 500;\n  color: var(--color-text-muted);\n  background: transparent;\n  border: 1px solid var(--color-border);\n  border-radius: var(--radius-sm);\n  cursor: pointer;\n  transition: all var(--transition-fast);\n}\n\n.btn-ghost:hover {\n  color: var(--color-text);\n  background: var(--color-bg);\n  border-color: var(--color-text-muted);\n}\n\n.gof-content {\n  padding: 1rem;\n  background: var(--color-bg);\n}\n\n/* Stats Summary */\n.stats-summary {\n  padding: 0.75rem;\n  background: var(--color-bg);\n  border: 1px solid var(--color-border-light);\n  border-radius: var(--radius-md);\n  margin-bottom: 1rem;\n}\n\n.stats-row {\n  display: grid;\n  grid-template-columns: repeat(4, 1fr);\n  gap: 0.5rem;\n  text-align: center;\n}\n\n@media (max-width: 575px) {\n  .stats-row {\n    grid-template-columns: repeat(2, 1fr);\n  }\n}\n\n.stat-key {\n  display: block;\n  font-size: 0.6875rem;\n  font-weight: 600;\n  text-transform: uppercase;\n  letter-spacing: 0.03em;\n  color: var(--color-text-muted);\n  margin-bottom: 0.125rem;\n}\n\n.stat-val {\n  font-size: 0.8125rem;\n  font-weight: 500;\n  color: var(--color-text);\n}\n\n/* Plots Grid */\n.plots-grid {\n  display: grid;\n  grid-template-columns: repeat(2, 1fr);\n  gap: 0.75rem;\n}\n\n@media (max-width: 767px) {\n  .plots-grid {\n    grid-template-columns: 1fr;\n  }\n}\n\n.plot-card {\n  background: var(--color-bg);\n  border: 1px solid var(--color-border);\n  border-radius: var(--radius-md);\n  overflow: hidden;\n}\n\n.plot-card-header {\n  padding: 0.5rem 0.75rem;\n  font-size: 0.75rem;\n  font-weight: 600;\n  color: var(--color-text-muted);\n  background: var(--color-bg-subtle);\n  border-bottom: 1px solid var(--color-border-light);\n}\n\n.plot-card-body {\n  padding: 0.75rem;\n}\n\n.gof-plot {\n  width: 100%;\n  height: 200px;\n  background: var(--color-bg);\n}\n\n.plot-hint {\n  display: block;\n  font-size: 0.6875rem;\n  color: var(--color-text-muted);\n  margin-top: 0.375rem;\n  line-height: 1.4;\n}\n\n/* Info Banner */\n.info-banner {\n  padding: 0.75rem 1rem;\n  margin: 1rem;\n  font-size: 0.875rem;\n  color: #0c4a6e;\n  background: rgba(8, 145, 178, 0.08);\n  border: 1px solid rgba(8, 145, 178, 0.2);\n  border-radius: var(--radius-sm);\n}\n</style>\n","import { render } from \"./GofDiagnostics.vue?vue&type=template&id=48a0842a&scoped=true\"\nimport script from \"./GofDiagnostics.vue?vue&type=script&lang=js\"\nexport * from \"./GofDiagnostics.vue?vue&type=script&lang=js\"\n\nimport \"./GofDiagnostics.vue?vue&type=style&index=0&id=48a0842a&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-48a0842a\"]])\n\nexport default __exports__","import { render } from \"./TcMore.vue?vue&type=template&id=127eb84e&scoped=true\"\nimport script from \"./TcMore.vue?vue&type=script&lang=js\"\nexport * from \"./TcMore.vue?vue&type=script&lang=js\"\n\nimport \"./TcMore.vue?vue&type=style&index=0&id=127eb84e&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-127eb84e\"]])\n\nexport default __exports__","<template>\n  <div class=\"inla-components\">\n    <h3 class=\"ic-title\">{{ $t('trends.inla.componentsTitle') }}</h3>\n    <p class=\"ic-intro\">{{ $t('trends.inla.componentsIntro') }}</p>\n    <div class=\"ic-cols\">\n      <div class=\"ic-col\" v-for=\"col in columns\" :key=\"col.part\">\n        <div class=\"ic-col-head\">\n          <span class=\"ic-num\">{{ col.part }}</span>\n          <span class=\"ic-name\">{{ col.name }}</span>\n          <span class=\"ic-sub\">{{ col.sub }}</span>\n        </div>\n        <div v-if=\"showPartSites\" class=\"ic-sites\">\n          {{ $tc('trends.inla.partSites', {n: siteStats[col.statKey]}) }}\n        </div>\n        <div class=\"ic-trend\" :id=\"col.trendId\"></div>\n        <InlaSpatialMap :spatial=\"plot.spatial\" :fixed-part=\"col.part\" :labels=\"mapLabels\" />\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport { defineComponent } from 'vue';\nimport { MyD3 } from '@/lib/myd3/MyD3';\nimport { inlaTrendToTraces, RAW_SCALE_PANEL_OPTIONS } from '@/lib/inla/inlaTrendToTraces';\nimport InlaSpatialMap from '@/components/account/admin/InlaSpatialMap.vue';\n\nexport default defineComponent({\n  name: 'InlaComponentCard',\n  components: { InlaSpatialMap },\n  props: {\n    plot: { type: Object, required: true },\n    siteStats: { type: Object, default: null },\n  },\n  computed: {\n    // p0/p1/p2 are the component panels; part 1/2/3 aligns them with the spatial map parts.\n    columns() {\n      return [\n        { part: 1, key: 'p0', trendId: 'divInlaTrend1', statKey: 'nb_sites',\n          name: this.$t('trends.inla.part1Name'), sub: this.$t('trends.inla.part1Sub') },\n        { part: 2, key: 'p1', trendId: 'divInlaTrend2', statKey: 'nb_sites_positive',\n          name: this.$t('trends.inla.part2Name'), sub: this.$t('trends.inla.part2Sub') },\n        { part: 3, key: 'p2', trendId: 'divInlaTrend3', statKey: 'nb_sites_multi',\n          name: this.$t('trends.inla.part3Name'), sub: this.$t('trends.inla.part3Sub') },\n      ];\n    },\n    // Only shown for data from an import that records complete surveys; for an\n    // ordinary dataset all three numbers would just repeat the summary sentence.\n    showPartSites() {\n      return !!(this.siteStats && this.siteStats.has_complete_survey);\n    },\n    mapLabels() {\n      return {\n        partLabel: this.$t('trends.inla.map.partLabel'),\n        note: this.$t('trends.inla.map.note'),\n        tkPrefix: this.$t('trends.inla.map.tkPrefix'),\n        noPosterior: this.$t('trends.inla.map.noPosterior'),\n        crInterval: this.$t('trends.inla.map.crInterval'),\n        rawEta: this.$t('trends.inla.map.rawEta'),\n        parts: [\n          { name: this.$t('trends.inla.part1Name'), sub: this.$t('trends.inla.part1Sub') },\n          { name: this.$t('trends.inla.part2Name'), sub: this.$t('trends.inla.part2Sub') },\n          { name: this.$t('trends.inla.part3Name'), sub: this.$t('trends.inla.part3Sub') },\n        ],\n      };\n    },\n  },\n  watch: {\n    plot() { this.$nextTick(this.renderTrends); },\n  },\n  mounted() {\n    this.$nextTick(this.renderTrends);\n  },\n  methods: {\n    renderTrends() {\n      const panels = this.plot && this.plot.trend && this.plot.trend.panels;\n      if (!panels) { return; }\n      for (const col of this.columns) {\n        const panel = panels[col.key];\n        if (!panel) { continue; }\n        const pd = inlaTrendToTraces(panel);\n        new MyD3(col.trendId, pd, { ...RAW_SCALE_PANEL_OPTIONS, ttShowSignificance: true, showGridlines: true }, this.$tc).draw();\n      }\n    },\n  },\n});\n</script>\n\n<style scoped>\n.inla-components {\n  margin-top: 0.5rem;\n  padding: 1.1rem 1.2rem 1.35rem;\n  border: 1px solid #e2e8f0;\n  border-radius: 0.85rem;\n  background: #fff;\n}\n.ic-title {\n  margin: 0 0 0.15rem;\n  font-size: 1.02rem;\n  font-weight: 700;\n  color: #1e293b;\n}\n.ic-intro {\n  margin: 0 0 1.1rem;\n  font-size: 0.82rem;\n  line-height: 1.4;\n  color: #64748b;\n  max-width: 60ch;\n}\n.ic-cols {\n  display: grid;\n  grid-template-columns: repeat(3, 1fr);\n  gap: 1.4rem;\n}\n@media (max-width: 991.98px) {\n  .ic-cols { grid-template-columns: 1fr; }\n}\n.ic-col-head {\n  display: flex;\n  align-items: baseline;\n  gap: 0.4rem;\n  margin-bottom: 0.45rem;\n  padding-bottom: 0.45rem;\n  border-bottom: 1px solid #eef2f7;\n}\n.ic-num {\n  align-self: center;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 1.15rem;\n  height: 1.15rem;\n  border-radius: 999px;\n  background: rgba(37, 99, 235, 0.12);\n  color: #2563eb;\n  font-size: 0.7rem;\n  font-weight: 700;\n}\n.ic-name { font-size: 0.9rem; font-weight: 600; color: #1e293b; }\n.ic-sub { font-size: 0.75rem; color: #64748b; }\n.ic-sites { margin: -0.2rem 0 0.5rem; font-size: 0.78rem; font-weight: 600; color: #475569; }\n.ic-trend { width: 100%; min-height: 220px; margin-bottom: 0.6rem; position: relative; }\n</style>\n","<template>\n  <div class=\"inla-map-wrap\">\n    <div class=\"inla-map-controls\">\n      <label class=\"inla-map-label\" v-if=\"!fixedPart\">{{ txt.partLabel }}</label>\n      <div class=\"inla-seg\" v-if=\"!fixedPart\">\n        <button\n          v-for=\"p in partMeta\" :key=\"p.num\" type=\"button\"\n          class=\"inla-seg-btn\" :class=\"{ active: part === p.num }\"\n          @click=\"part = p.num\">\n          <span class=\"inla-seg-num\">{{ p.num }}</span>{{ p.name }}\n        </button>\n      </div>\n      <span class=\"inla-map-note\">{{ txt.note }}</span>\n    </div>\n\n    <div class=\"inla-map-frame\">\n      <div ref=\"map\" class=\"inla-map\"></div>\n      <div class=\"inla-map-legend\" v-if=\"legend.length\">\n        <span class=\"legend-title\">{{ activePart.name }} · {{ activePart.sub }}</span>\n        <div class=\"legend-scale\">\n          <span v-for=\"(c, i) in legend\" :key=\"i\" class=\"legend-swatch\" :style=\"{ background: c }\"></span>\n        </div>\n        <div class=\"legend-ends\"><span>{{ fmt(domainMin) }}</span><span>{{ fmt(domainMax) }}</span></div>\n      </div>\n    </div>\n\n    <Teleport to=\"body\">\n      <div ref=\"tip\" class=\"inla-map-tip\" style=\"display:none\"></div>\n    </Teleport>\n  </div>\n</template>\n\n<script>\nimport { defineComponent } from 'vue';\nimport * as d3 from 'd3';\nimport L from 'leaflet';\nimport 'leaflet/dist/leaflet.css';\nimport MyBase from '@/components/account/MyBase.vue';\nimport { ApiCommunication, ApiRequestBuilder } from '@/lib/ApiCom';\nimport { inverseLinkForPart } from '@/lib/inla/inverseLink';\nimport { placeTip } from '@/components/account/dashboard/tooltip';\n\nconst PART_META = [\n  { num: 1, name: 'Occupancy', sub: 'P(present)' },\n  { num: 2, name: 'Conditional', sub: 'P(>1 | present)' },\n  { num: 3, name: 'Group size', sub: 'count | >1' },\n];\n\n// Public plotter endpoint. tk25_geo is served here (bats/plotter/api.py) without an\n// is_staff gate, so this works on the anonymous /trends page as well as in admin.\nconst GeoCom = new ApiCommunication('/api_plot');\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'InlaSpatialMap',\n  props: {\n    spatial: { type: Object, required: true },   // plot.spatial: {part1,part2,part3,car_index_to_tk25}\n    fixedPart: { type: Number, default: null },  // 1|2|3 pins one part (public); null = 3-way selector (admin)\n    labels: { type: Object, default: null },     // i18n strings (public); null = English literals (admin)\n  },\n  data() {\n    return { map: null, geoLayer: null, features: [], resizeObserver: null,\n             part: this.fixedPart || 1, legend: [], domainMin: 0, domainMax: 1 };\n  },\n  computed: {\n    // Merge optional i18n labels over the English defaults so admin (labels=null) is unchanged.\n    partMeta() {\n      const L = this.labels;\n      if (!L || !L.parts) { return PART_META; }\n      return PART_META.map((p, i) => ({\n        num: p.num,\n        name: (L.parts[i] && L.parts[i].name) || p.name,\n        sub: (L.parts[i] && L.parts[i].sub) || p.sub,\n      }));\n    },\n    txt() {\n      const L = this.labels || {};\n      return {\n        partLabel: L.partLabel || 'Hurdle part',\n        note: L.note || 'colour = posterior mean, response scale',\n        tkPrefix: L.tkPrefix || 'TK25',\n        noPosterior: L.noPosterior || 'no posterior for this sheet',\n        crInterval: L.crInterval || '95% CrI',\n        rawEta: L.rawEta || 'raw η',\n      };\n    },\n    activePart() { return this.partMeta[this.part - 1]; },\n    // sheet number -> { value (response scale), row (raw), ciLow, ciHigh } for the selected part.\n    dataBySheet() {\n      const rows = this.spatial['part' + this.part] || [];\n      const link = inverseLinkForPart(this.part);\n      const c2t = this.spatial.car_index_to_tk25 || {};\n      const out = {};\n      for (const r of rows) {\n        const sheet = c2t[String(r.ID)];\n        if (sheet === undefined || !Number.isFinite(r.mean)) continue;\n        out[sheet] = {\n          value: link(r.mean),\n          ciLow: Number.isFinite(r.QL) ? link(r.QL) : undefined,\n          ciHigh: Number.isFinite(r.QH) ? link(r.QH) : undefined,\n          row: r,\n        };\n      }\n      return out;\n    },\n  },\n  watch: {\n    part() { this.renderLayer(); },\n    spatial() { this.fetchGeometry(); },\n    fixedPart(v) { if (v) { this.part = v; } },\n  },\n  mounted() {\n    this.map = L.map(this.$refs.map, {\n      zoomControl: false, attributionControl: false,\n      scrollWheelZoom: false, dragging: false, doubleClickZoom: false,\n      keyboard: false, touchZoom: false, boxZoom: false,\n      zoomAnimation: false, fadeAnimation: false, markerZoomAnimation: false,\n    }).setView([49.0, 11.5], 6);\n    // The container can still be unsized here (hidden parent, stylesheet in flight):\n    // Leaflet caches a 0x0 size, fitBounds then computes a NaN zoom and every\n    // projection after it yields \"Invalid LatLng object: (NaN, NaN)\". Re-measure and\n    // re-fit on the first resize that gives the container real dimensions.\n    if (typeof ResizeObserver !== 'undefined') {\n      this.resizeObserver = new ResizeObserver(() => this.refitMap());\n      this.resizeObserver.observe(this.$refs.map);\n    }\n    this.fetchGeometry();\n  },\n  beforeUnmount() {\n    if (this.resizeObserver) { this.resizeObserver.disconnect(); this.resizeObserver = null; }\n    if (this.map) this.map.remove();\n  },\n  methods: {\n    fmt(v) { return (v === undefined || v === null || !Number.isFinite(v)) ? 'n/a' : v.toFixed(3); },\n    fetchGeometry() {\n      const sheets = Object.values(this.spatial.car_index_to_tk25 || {});\n      const rb = new ApiRequestBuilder();\n      rb.addAction('tk25_geo', { sheets });\n      // Post to the public plotter endpoint; pass `this` only for ApiCom's spinner bookkeeping.\n      GeoCom.post(this, rb.build(),\n        (json) => {\n          this.features = json.geo || [];\n          this.renderLayer();\n        },\n        () => { this.features = []; this.renderLayer(); });\n    },\n    colorScale() {\n      const vals = Object.values(this.dataBySheet).map(d => d.value);\n      this.domainMin = d3.min(vals);\n      this.domainMax = d3.max(vals);\n      if (this.domainMin === undefined) { this.domainMin = 0; this.domainMax = 1; }\n      return d3.scaleSequential(d3.interpolateViridis).domain([this.domainMin, this.domainMax]);\n    },\n    styleFor(sheet, scale) {\n      const d = this.dataBySheet[sheet];\n      return {\n        fillColor: d === undefined ? '#eef2f7' : scale(d.value),\n        fillOpacity: 0.85, weight: 0.5, color: '#94a3b8',\n      };\n    },\n    renderLayer() {\n      if (!this.map) return;\n      if (this.geoLayer) { this.geoLayer.remove(); this.geoLayer = null; }\n      if (!this.features.length) { this.legend = []; return; }\n      const scale = this.colorScale();\n      const fc = {\n        type: 'FeatureCollection',\n        features: this.features.map(f => ({\n          type: 'Feature', properties: { id: f.id, name: f.name }, geometry: f.geometry,\n        })),\n      };\n      this.geoLayer = L.geoJSON(fc, {\n        style: (feat) => this.styleFor(feat.properties.id, scale),\n        onEachFeature: (feat, layer) => {\n          layer.on('mouseover', (e) => { layer.setStyle({ weight: 2, color: '#1e293b' }); this.showTip(feat, e.originalEvent); });\n          layer.on('mousemove', (e) => this.showTip(feat, e.originalEvent));\n          layer.on('mouseout', () => { if (this.geoLayer) this.geoLayer.resetStyle(layer); this.hideTip(); });\n        },\n      }).addTo(this.map);\n      this.refitMap();\n      this.legend = d3.range(0, 1.0001, 0.2).map(t => scale(this.domainMin + t * (this.domainMax - this.domainMin)));\n    },\n    /**\n     * Re-measure the container and re-frame the layer. Recovers a map that was built\n     * at zero size — invalidateSize() replaces Leaflet's cached size and the refit\n     * then computes a real zoom over the NaN one fitBounds produced.\n     */\n    refitMap() {\n      if (!this.map || !this.geoLayer) return;\n      const el = this.$refs.map;\n      if (!el || !el.clientWidth || !el.clientHeight) return;\n      this.map.invalidateSize();\n      try { this.map.fitBounds(this.geoLayer.getBounds(), { padding: [8, 8] }); } catch (e) { /* empty */ }\n    },\n    showTip(feat, event) {\n      const tip = this.$refs.tip; if (!tip || !event) return;\n      const sheet = feat.properties.id;\n      const d = this.dataBySheet[sheet];\n      const p = this.activePart;\n      const head = `<div class=\"mt-name\">${this.txt.tkPrefix} ${sheet}</div>` +\n        `<div class=\"mt-sub\"><span class=\"mt-num\">${p.num}</span>${p.name} · ${p.sub}</div>`;\n      let body;\n      if (d === undefined) {\n        body = `<div class=\"mt-empty\">${this.txt.noPosterior}</div>`;\n      } else {\n        const ci = (d.ciLow !== undefined && d.ciHigh !== undefined)\n          ? `<div class=\"mt-row\"><span>${this.txt.crInterval}</span><b>${this.fmt(d.ciLow)} – ${this.fmt(d.ciHigh)}</b></div>` : '';\n        const sd = Number.isFinite(d.row.sd)\n          ? `<div class=\"mt-row\"><span>${this.txt.rawEta}</span><b>${d.row.mean.toFixed(2)} ± ${d.row.sd.toFixed(2)}</b></div>` : '';\n        body = `<div class=\"mt-val\">${this.fmt(d.value)}</div>` +\n          `<div class=\"mt-rows\">${ci}${sd}</div>`;\n      }\n      tip.innerHTML = head + body;\n      tip.style.display = 'block';\n      placeTip(tip, event);\n    },\n    hideTip() { if (this.$refs.tip) this.$refs.tip.style.display = 'none'; },\n  },\n});\n</script>\n\n<style scoped>\n.inla-map-wrap {\n  --color-primary: #2563eb;\n  --color-text: #1e293b;\n  --color-text-muted: #64748b;\n  --color-border: #e2e8f0;\n  position: relative;\n  width: 100%;\n}\n\n/* ---------- Controls ---------- */\n.inla-map-controls {\n  display: flex;\n  align-items: center;\n  flex-wrap: wrap;\n  gap: 0.6rem;\n  margin-bottom: 0.7rem;\n}\n.inla-map-label {\n  font-size: 0.6875rem;\n  font-weight: 700;\n  text-transform: uppercase;\n  letter-spacing: 0.08em;\n  color: var(--color-text-muted);\n}\n.inla-seg {\n  display: inline-flex;\n  border: 1px solid var(--color-border);\n  border-radius: 0.5rem;\n  overflow: hidden;\n  background: #fff;\n}\n.inla-seg-btn {\n  display: inline-flex;\n  align-items: center;\n  gap: 0.35rem;\n  border: none;\n  background: transparent;\n  padding: 0.3rem 0.6rem;\n  font-size: 0.78rem;\n  color: var(--color-text-muted);\n  cursor: pointer;\n  transition: background 0.15s ease, color 0.15s ease;\n}\n.inla-seg-btn + .inla-seg-btn { border-left: 1px solid var(--color-border); }\n.inla-seg-btn:hover { background: #f1f5f9; color: var(--color-text); }\n.inla-seg-btn.active { background: var(--color-primary); color: #fff; }\n.inla-seg-num {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 1.05rem;\n  height: 1.05rem;\n  border-radius: 999px;\n  background: rgba(37, 99, 235, 0.12);\n  color: var(--color-primary);\n  font-size: 0.68rem;\n  font-weight: 700;\n}\n.inla-seg-btn.active .inla-seg-num { background: rgba(255, 255, 255, 0.25); color: #fff; }\n.inla-map-note { color: var(--color-text-muted); font-size: 0.72rem; margin-left: auto; }\n\n/* ---------- Map ---------- */\n.inla-map-frame { position: relative; }\n.inla-map {\n  width: 100%;\n  height: 460px;\n  border-radius: 0.75rem;\n  background: #f8fafc;\n  border: 1px solid var(--color-border);\n}\n.inla-map-legend {\n  position: absolute; bottom: 12px; right: 12px; z-index: 500;\n  background: rgba(255, 255, 255, 0.94); padding: 0.45rem 0.6rem;\n  border: 1px solid var(--color-border); border-radius: 0.5rem;\n  box-shadow: 0 2px 10px rgba(15, 23, 42, 0.12);\n  font-size: 0.68rem; color: var(--color-text-muted);\n}\n.legend-title { display: block; margin-bottom: 0.28rem; font-weight: 600; color: var(--color-text); }\n.legend-scale { display: flex; border-radius: 3px; overflow: hidden; }\n.legend-swatch { width: 24px; height: 9px; }\n.legend-ends { display: flex; justify-content: space-between; margin-top: 0.18rem; font-variant-numeric: tabular-nums; }\n\n/* ---------- Tooltip (dark card, matches the dashboard maps) ---------- */\n.inla-map-tip {\n  position: fixed; pointer-events: none; z-index: 1000;\n  background: rgba(15, 23, 42, 0.95); color: #fff; border-radius: 0.6rem;\n  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.32); padding: 0.55rem 0.7rem;\n  font-size: 0.76rem; min-width: 140px;\n}\n.inla-map-tip :deep(.mt-name) { font-weight: 700; font-size: 0.85rem; }\n.inla-map-tip :deep(.mt-sub) {\n  display: flex; align-items: center; gap: 0.3rem;\n  opacity: 0.72; font-size: 0.68rem; margin-bottom: 0.35rem;\n}\n.inla-map-tip :deep(.mt-num),\n.inla-map-tip :deep(.mt-val) { font-variant-numeric: tabular-nums; }\n.inla-map-tip :deep(.mt-num) {\n  display: inline-flex; align-items: center; justify-content: center;\n  width: 1rem; height: 1rem; border-radius: 999px;\n  background: rgba(255, 255, 255, 0.16); font-size: 0.62rem; font-weight: 700;\n}\n.inla-map-tip :deep(.mt-val) { font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; }\n.inla-map-tip :deep(.mt-rows) {\n  margin-top: 0.35rem; padding-top: 0.3rem;\n  border-top: 1px solid rgba(255, 255, 255, 0.15); display: grid; gap: 0.15rem;\n}\n.inla-map-tip :deep(.mt-row) {\n  display: flex; justify-content: space-between; gap: 1.2rem; font-variant-numeric: tabular-nums;\n}\n.inla-map-tip :deep(.mt-row span) { opacity: 0.72; }\n.inla-map-tip :deep(.mt-empty) { opacity: 0.72; font-style: italic; }\n</style>\n","import script from \"./MyBase.vue?vue&type=script&lang=js\"\nexport * from \"./MyBase.vue?vue&type=script&lang=js\"\n\nconst __exports__ = script;\n\nexport default __exports__","<script>\nimport {defineComponent} from 'vue';\nimport {useAccountStore} from \"@/store/account\";\n\nexport default defineComponent({\n  data: function (){\n    return {\n      mStore: null,\n    }\n  },\n  // mounted: function() {\n  //   return;\n  // },\n  methods: {\n    _getStore() {\n      if (!this.mStore){\n        this.mStore = useAccountStore();\n      }\n      return this.mStore;\n    },\n  },\n  computed: {\n    store: function () {\n      return this._getStore();\n    },\n    accountComponent: function () {\n      return this.store.accountComponent;\n    },\n    user: function () {\n      return this.store.user;\n    },\n  }\n});\n</script>\n","// Inverse links applied client-side to the raw linear predictor emitted per spatial part.\nexport function plogis(x: number): number {\n    return 1 / (1 + Math.exp(-x));\n}\nexport function expLink(x: number): number {\n    return Math.exp(x);\n}\nexport function inverseLinkForPart(part: 1 | 2 | 3): (x: number) => number {\n    return part === 3 ? expLink : plogis;\n}\n","// Shared positioning for the dashboard chart tooltips (.chart-tip).\n//\n// The tooltips live inside .section-card, which uses `overflow: hidden`, so an\n// absolutely-positioned tip gets clipped the moment it reaches a card edge.\n// These tips are therefore `position: fixed` (escaping the card clip) and placed\n// against the viewport here, flipping to the other side of the cursor and\n// clamping to the screen so the tip is always fully visible — even near an edge\n// or when it is large.\n//\n// The tip element must already be visible with its content set before calling\n// (so offsetWidth / offsetHeight reflect the rendered size).\nexport function placeTip(tip, event, gap = 14) {\n  if (!tip) return;\n  const tw = tip.offsetWidth;\n  const th = tip.offsetHeight;\n  const vw = window.innerWidth;\n  const vh = window.innerHeight;\n  const pad = 8; // keep this far from the viewport edge\n\n  // Prefer below-right of the cursor; flip to the other side if it would overflow.\n  let left = event.clientX + gap;\n  if (left + tw + pad > vw) left = event.clientX - gap - tw;\n  left = Math.min(Math.max(left, pad), Math.max(pad, vw - tw - pad));\n\n  let top = event.clientY + gap;\n  if (top + th + pad > vh) top = event.clientY - gap - th;\n  top = Math.min(Math.max(top, pad), Math.max(pad, vh - th - pad));\n\n  tip.style.left = left + 'px';\n  tip.style.top = top + 'px';\n}\n","import { render } from \"./InlaSpatialMap.vue?vue&type=template&id=d32d9b0a&scoped=true\"\nimport script from \"./InlaSpatialMap.vue?vue&type=script&lang=js\"\nexport * from \"./InlaSpatialMap.vue?vue&type=script&lang=js\"\n\nimport \"./InlaSpatialMap.vue?vue&type=style&index=0&id=d32d9b0a&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-d32d9b0a\"]])\n\nexport default __exports__","import { render } from \"./InlaComponentCard.vue?vue&type=template&id=60138bb2&scoped=true\"\nimport script from \"./InlaComponentCard.vue?vue&type=script&lang=js\"\nexport * from \"./InlaComponentCard.vue?vue&type=script&lang=js\"\n\nimport \"./InlaComponentCard.vue?vue&type=style&index=0&id=60138bb2&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-60138bb2\"]])\n\nexport default __exports__","<template>\n  <div id=\"carouselSP\" class=\"carousel carousel-dark slide\" data-bs-ride=\"carousel\">\n    <div class=\"carousel-inner\">\n      <div class=\"carousel-item\" v-for=\"(page, key) in pages\" :key=\"key\" :class=\"{'active': key==0}\" data-bs-interval=\"false\">\n        <div class=\"preview-row\">\n          <div v-for=\"(spec, key) in page.imgs\" :key=\"key\" class=\"preview-item\" @click=\"clickSpecies(spec)\">\n            <SpeciesImage :img=\"spec.images[Math.floor(Math.random() * spec.images.length)]\" class=\"preview-image\" style=\"max-width: 224px;\" :bottom-bar-text=\"previewSpeciesHtml(spec)\" bottom-bar-class=\"preview-caption\"></SpeciesImage>\n          </div>\n        </div>\n      </div>\n    </div>\n\n    <div class=\"carousel-indicators\">\n<!--      <button class=\"\" type=\"button\" data-bs-target=\"#carouselSP\" data-bs-slide=\"prev\"></button>-->\n      <button type=\"button\" data-bs-target=\"#carouselSP\" data-bs-slide-to=\"0\" class=\"active\" aria-current=\"true\" aria-label=\"Slide 1\"></button>\n      <button v-for=\"(page, index) in pages.slice(1)\" :key=\"index\" type=\"button\" data-bs-target=\"#carouselSP\" :data-bs-slide-to=\"index + 1\" :aria-label=\"'Slide ' + (index+2)\"></button>\n<!--      <button class=\"\" type=\"button\" data-bs-target=\"#carouselSP\" data-bs-slide=\"prev\"></button>-->\n    </div>\n  </div>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport MyBase from \"@/components/trends/MyBase.vue\";\nimport SpeciesImage from \"@/components/trends/cards/SpeciesImage.vue\";\n\nexport default defineComponent({\n  extends: MyBase,\n  name: 'SpeciesPreviewCarousel',\n  components: {SpeciesImage},\n  props: {\n    countTypes: Array\n  },\n  data: function (){\n    return {\n      pages: [],\n      width: 0\n    }\n  },\n  mounted: function() {\n    const pages = [];\n    const elm = document.getElementById('mainContainer');\n    // const countTypes = this.store.plotSettings.availableCountTypes;\n    const countTypes = this.countTypes;\n    if (elm) {\n      const computedStyles = window.getComputedStyle(elm);\n      const width = parseFloat(computedStyles.width);\n      this.width = width;\n      let nbPerRow = Math.floor(width / 224);\n      if (countTypes.length == 16 && nbPerRow > 4){\n        nbPerRow = 4;\n      }\n      const nbRows = Math.ceil(countTypes.length / nbPerRow);\n      console.log(\"mounted\", width, nbPerRow, nbRows, countTypes.length);\n      for (let i = 0; i < nbRows; i++) {\n      // console.log(i, nbRows);\n        const imgs = countTypes.slice(i * nbPerRow, (i + 1) * nbPerRow);\n        pages.push({\n          imgs\n        });\n      }\n    }\n    this.pages = pages;\n  },\n  methods: {\n    previewSpeciesHtml: function (spec){\n      // return `<em>${spec.latin}</em><div class=\"fs-6\">${this.capitalizeAll(spec.name)}</div>`;\n      return `<em>${spec.latin}</em>`;\n      // return <em>' + spec.latin + '</em><span' + capitalizeAll(spec.name)\n    },\n    clickSpecies: function (spec){\n      this.$emit('selectSpecies', spec);\n    },\n  },\n});\n</script>\n\n<style scoped>\n.preview-row {\n  display: flex;\n  flex-direction: row;\n  justify-content: space-evenly;\n}\n\n.preview-item {\n  margin: 0.5rem;\n  cursor: pointer;\n  transition: transform 0.15s ease, box-shadow 0.15s ease;\n  border-radius: 0.625rem;\n}\n\n.preview-item:hover {\n  transform: translateY(-2px);\n  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n}\n\n.preview-image {\n  margin-bottom: 0.75rem;\n}\n\ndiv.carousel-indicators {\n  position: relative;\n}\n\ndiv.carousel-indicators button {\n  width: 20px;\n  height: 20px;\n  border-radius: 50%;\n  background-color: #94a3b8;\n  border: none;\n  padding: 0;\n  cursor: pointer;\n  transition: background-color 0.15s ease;\n}\n\ndiv.carousel-indicators button.active {\n  background-color: #2563eb;\n}\n</style>\n","import { render } from \"./SpeciesPreviewCarousel.vue?vue&type=template&id=7aaed9e4&scoped=true\"\nimport script from \"./SpeciesPreviewCarousel.vue?vue&type=script&lang=js\"\nexport * from \"./SpeciesPreviewCarousel.vue?vue&type=script&lang=js\"\n\nimport \"./SpeciesPreviewCarousel.vue?vue&type=style&index=0&id=7aaed9e4&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-7aaed9e4\"]])\n\nexport default __exports__","<template>\n  <div class=\"trend-gam\">\n    <div v-if=\"! hasEnoughData\" :class=\"cssTrend(undefined)\" class=\"trend-row\">\n      <svg class=\"trend-icon\" :width=\"iconSizeLarge\" :height=\"iconSizeLarge\"><use xlink:href=\"#question-circle\"/></svg>\n      <div>{{ $t('trends.slope.Uncertain') }}<br>{{ $t('trends.plotError.generic_error') }}</div>\n    </div>\n    <div v-else>\n      <div v-for=\"(seg, key) in significantSegments\" :key=\"key\" class=\"trend-row\" :class=\"cssTrend(seg)\">\n        <svg class=\"trend-icon\" :width=\"iconSize\" :height=\"iconSize\"><use :xlink:href=\"svgTrend(seg)\"/></svg>\n        <div>{{ timespanText(seg) }}</div>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nimport {defineComponent} from 'vue';\nimport {MyD3} from \"@/lib/myd3/MyD3\";\n\nclass SignificantSegment {\n  yearStart = 0;\n  yearEnd = 0;\n  significance = 0;\n  constructor(trace, segment){\n    this.yearStart = Math.round(trace.items[segment.x0]?.data?.year);\n    this.yearEnd = Math.round(trace.items[segment.x1]?.data?.year || trace.items[trace.items.length - 1]?.data?.year);\n    this.significance = segment.significance;\n  }\n}\nexport default defineComponent({\n  name: 'TrendComponentGAM',\n  components: {},\n  props: {\n    plot: null,\n    hasEnoughData: {type: Boolean, default: true},\n    iconSizeLarge: {type: Number, default: 64},\n    iconSize: {type: Number, default: 16}\n  },\n  data: function (){\n    return {\n      pp: null,\n      significantSegments: [],\n      displayInsignificants: true,\n    }\n  },\n  mounted: function() {\n    if (this.plot){\n      this.updateFromPlot();\n    }\n\n  },\n  watch: {\n    plot: function(){\n      this.updateFromPlot();\n    }\n  },\n  methods: {\n    updateFromPlot: function(){\n      if (!this.plot){\n        this.pp = null;\n        this.significantSegments = [];\n        return;\n      }\n      this.pp = MyD3.getPreparedPlot(this.plot);\n      //  find the trace with a significance\n      let significantTrace = undefined;\n      for (const trace of this.pp.traces){\n        for (const itm of trace.items){\n          if (itm.data?.significance !== undefined){\n            significantTrace = trace;\n            break;\n          }\n        }\n        if (significantTrace) break;\n      }\n\n      const sigsegs = [];\n      if (significantTrace){\n        const segmentsRaw = MyD3.createSegmentsBySignificance(significantTrace);\n        const segments = MyD3.stripShortSignificantSegments(segmentsRaw, significantTrace);\n        // now find all the significant segments\n        for (const seg of segments){\n          if (this.displayInsignificants || seg.significance > 0){\n            sigsegs.push(new SignificantSegment(significantTrace, seg));\n          }\n        }\n      }\n      this.significantSegments = sigsegs;\n    },\n    cssTrend: function(seg){\n      const css = {};\n      if (! this.hasEnoughData){\n        css['trend-color-danger'] = true;\n      }\n      else{\n        const color = this.colorBySeg(seg);\n        css['trend-color-' + color] = true;\n      }\n      return css;\n    },\n\n    colorBySeg(seg){\n      if (! this.hasEnoughData || !seg){\n        return \"muted\";\n      }\n      if (seg.significance === 1){\n        return \"success\";\n      }\n      else if (seg.significance === 2){\n        return \"danger\";\n      }\n      else{\n        return \"muted\";\n      }\n    },\n\n    svgTrend: function(seg){\n      if (! this.hasEnoughData){\n        return \"#question-circle\";\n      }\n      if (seg.significance === 1){\n        return \"#arrow-up-right-circle\";\n      }\n      else if (seg.significance === 2){\n        return \"#arrow-down-right-circle\";\n      }\n      else{\n        return \"#arrow-right-circle\";\n      }\n    },\n\n    timespanText: function (seg){\n      if (seg.yearStart === seg.yearEnd) return `${seg.yearStart}`;\n      return `${seg.yearStart} - ${seg.yearEnd}`;\n    }\n  },\n});\n</script>\n\n<style scoped>\n.trend-row {\n  display: flex;\n  align-items: center;\n  gap: 0.5rem;\n  font-size: 0.875rem;\n  font-weight: 500;\n  line-height: 1.4;\n  padding: 0.125rem 0;\n}\n\n.trend-icon {\n  flex-shrink: 0;\n}\n\n.trend-color-success { color: #059669; }\n.trend-color-danger { color: #dc2626; }\n.trend-color-muted { color: #64748b; }\n</style>\n","import { render } from \"./TrendComponentGAM.vue?vue&type=template&id=1361b420&scoped=true\"\nimport script from \"./TrendComponentGAM.vue?vue&type=script&lang=js\"\nexport * from \"./TrendComponentGAM.vue?vue&type=script&lang=js\"\n\nimport \"./TrendComponentGAM.vue?vue&type=style&index=0&id=1361b420&scoped=true&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-1361b420\"]])\n\nexport default __exports__","import { render } from \"./Plots3.vue?vue&type=template&id=96e7337c&scoped=true\"\nimport script from \"./Plots3.vue?vue&type=script&lang=js\"\nexport * from \"./Plots3.vue?vue&type=script&lang=js\"\n\nimport \"./Plots3.vue?vue&type=style&index=0&id=96e7337c&scoped=true&lang=css\"\nimport \"./Plots3.vue?vue&type=style&index=1&id=96e7337c&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-96e7337c\"]])\n\nexport default __exports__","\nimport {defineComponent} from 'vue';\nimport PlotsThree from \"@/components/trends/Plots3.vue\";\n\nexport default defineComponent({\n  name: 'App',\n  components: {\n    PlotsThree,\n  },\n  data: function () {\n    return {\n      myView: \"\",\n    }\n  },\n  created() {\n    this.myView = document.getElementById(\"app\")?.getAttribute(\"my_view\") || \"plot\";\n  }\n});\n","import { render } from \"./App.vue?vue&type=template&id=1fb8d404&ts=true\"\nimport script from \"./App.vue?vue&type=script&lang=ts\"\nexport * from \"./App.vue?vue&type=script&lang=ts\"\n\nimport \"./App.vue?vue&type=style&index=0&id=1fb8d404&lang=css\"\n\nimport exportComponent from \"/home/s/PycharmProjects/batdemo/myvue/node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import {createApp} from 'vue'\nimport App from './App.vue'\nimport '@/assets/css/access-badges.css'\nimport {createPinia} from \"pinia\";\nimport {setupI18n} from \"@/account/i18n\";\n\ndeclare const vueI18n:any;\n// alert(vueI18n);\n\nconst pinia = createPinia()\nconst i18n = setupI18n(vueI18n)\nconst app = createApp(App)\napp.use(pinia)\napp.use(i18n)\n\napp.mount('#app')","import {nextTick} from 'vue'\nimport {createI18n, I18n} from 'vue-i18n'\n\n// export const SUPPORT_LOCALES = ['en', 'ja']\n\nexport function setupI18n(d: any) {\n    const html = document.querySelector('html');\n    let lang = 'en';\n    if (html){\n        lang = html.getAttribute('lang') || 'en';\n    }\n\n    if (d){\n        const messages: Record<string, any> = {};\n        messages[lang] = d;\n        const options = {\n            locale: lang,\n            messages\n        };\n        return createI18n(options);\n    }\n\n    const options = {\n        locale: lang\n    };\n    const i18n = createI18n(options);\n    setI18nLanguage(i18n, options.locale);\n    return i18n;\n}\n\nexport function setI18nLanguage(i18n: I18n, locale: string) {\n    if (i18n.mode === 'legacy') {\n        i18n.global.locale = locale;\n    } else {\n        // i18n.global.locale.value = locale\n    }\n    // /**\n    //  * NOTE:\n    //  * If you need to specify the language setting for headers, such as the `fetch` API, set it here.\n    //  * The following is an example for axios.\n    //  *\n    //  * axios.defaults.headers.common['Accept-Language'] = locale\n    //  */\n    // const html = document.querySelector('html');\n    // if (html)\n    //     html.setAttribute('lang', locale)\n    //\n    // {\n    //     // loadLocaleMessages(i18n, locale);\n    // }\n    loadLocaleMessages(i18n, locale);\n}\n\nexport async function loadLocaleMessages(i18n: any, locale: string) {\n    // load locale messages with dynamic import\n    const messages = await import(\n        /* webpackChunkName: \"locale-[request]\" */ `../locales/${locale}.json`\n        )\n\n    // set locale and locale message\n    i18n.global.setLocaleMessage(locale, messages.default)\n\n    return nextTick()\n}","var map = {\n\t\"./de.json\": [\n\t\t5894,\n\t\t706\n\t],\n\t\"./en.json\": [\n\t\t4174,\n\t\t990\n\t]\n};\nfunction webpackAsyncContext(req) {\n\tif(!__webpack_require__.o(map, req)) {\n\t\treturn Promise.resolve().then(function() {\n\t\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\t\te.code = 'MODULE_NOT_FOUND';\n\t\t\tthrow e;\n\t\t});\n\t}\n\n\tvar ids = map[req], id = ids[0];\n\treturn __webpack_require__.e(ids[1]).then(function() {\n\t\treturn __webpack_require__.t(id, 3 | 16);\n\t});\n}\nwebpackAsyncContext.keys = function() { return Object.keys(map); };\nwebpackAsyncContext.id = 9842;\nmodule.exports = webpackAsyncContext;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = function(chunkId) {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce(function(promises, key) {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks\n__webpack_require__.u = function(chunkId) {\n\t// return url for filenames based on template\n\treturn \"js/\" + {\"706\":\"locale-de-json\",\"990\":\"locale-en-json\"}[chunkId] + \".js\";\n};","// This function allow to reference async chunks\n__webpack_require__.miniCssF = function(chunkId) {\n\t// return url for filenames based on template\n\treturn undefined;\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.j = 667;","__webpack_require__.p = \"/static/src/vue/dist/\";","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t667: 0\n};\n\n__webpack_require__.f.j = function(chunkId, promises) {\n\t\t// JSONP chunk loading for javascript\n\t\tvar installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\n\t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n\t\t\t// a Promise means \"currently loading\".\n\t\t\tif(installedChunkData) {\n\t\t\t\tpromises.push(installedChunkData[2]);\n\t\t\t} else {\n\t\t\t\tif(true) { // all chunks have JS\n\t\t\t\t\t// setup Promise in chunk cache\n\t\t\t\t\tvar promise = new Promise(function(resolve, reject) { installedChunkData = installedChunks[chunkId] = [resolve, reject]; });\n\t\t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n\t\t\t\t\t// start chunk loading\n\t\t\t\t\tvar url = __webpack_require__.p + __webpack_require__.u(chunkId);\n\t\t\t\t\t// create error before stack unwound to get useful stacktrace later\n\t\t\t\t\tvar error = new Error();\n\t\t\t\t\tvar loadingEnded = function(event) {\n\t\t\t\t\t\tif(__webpack_require__.o(installedChunks, chunkId)) {\n\t\t\t\t\t\t\tinstalledChunkData = installedChunks[chunkId];\n\t\t\t\t\t\t\tif(installedChunkData !== 0) installedChunks[chunkId] = undefined;\n\t\t\t\t\t\t\tif(installedChunkData) {\n\t\t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n\t\t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n\t\t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n\t\t\t\t\t\t\t\terror.type = errorType;\n\t\t\t\t\t\t\t\terror.request = realSrc;\n\t\t\t\t\t\t\t\tinstalledChunkData[1](error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t__webpack_require__.l(url, loadingEnded, \"chunk-\" + chunkId, chunkId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n};\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkmyvue\"] = self[\"webpackChunkmyvue\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [504,996], function() { return __webpack_require__(3501); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","leafPrototypes","getProto","inProgress","dataWebpackPrefix","_hoisted_1","xmlns","style","_hoisted_11","_createStaticVNode","class","id","_createElementVNode","width","height","ApiCommunication","constructor","url","_defineProperty","WeakMap","Map","this","axios","xsrfCookieName","xsrfHeaderName","_startRequest","app","infoText","count","_requestCounts","get","set","reqId","_nextReqId","_requestInfoTexts","text","working","_updateInfoTexts","_endRequest","Math","max","delete","_syncWorkingState","fatalError","confirm","texts","forEach","entry","push","loadingInfoTexts","getActiveRequestCount","_handleFatalError","response","data","raiseFatalError","message","_handleResponse","responseHandler","errorHandler","headers","e","makeRequest","method","post","config","postFile","file","postFormData","formData","postDownload","filename","undefined","responseType","then","blobUrl","window","URL","createObjectURL","Blob","link","document","createElement","href","setAttribute","body","appendChild","click","def","download","catch","error","requestData","FormData","append","ApiRequestBuilder","actionId","properties","actions","addAction","action","build","ApiUtil","map","l","item","idx","DomElement","element","el","attr","key","value","Array","isArray","classList","Object","keys","filter","cls","Boolean","join","styleString","entries","prop","val","String","attrs","attributes","content","textContent","ElementBuilder","create","tag","domElement","parent","Tooltip","svg","container","show","htmlContent","x","y","html","position","hide","bounds","node","getBoundingClientRect","left","top","maxLeft","maxTop","min","MyPlotVisuals","Plot","prepare","plot","handlers","traces","prepared","jsonTrace","handler","find","canHandle","trace","read","traceIndex","length","prepareBounds","myD3","renderables","traceHandler","yieldRenderables","sort","a","b","renderable","configureAxes","updateBounds","xMin","xMax","yMin","yMax","resolveYBounds","Trace","traceJson","settings","title","keyX","keyY","applyStyle","hsva","dashArray","applyHsva","color","applyColorHex","hex","m","exec","trim","r","parseInt","g","mix","t","round","shade","rgba","colorFull","colorFullAlpha10","colorFullAlpha25","colorDesaturated","colorDark","colorLight","colorBarFill","colorBarStroke","colorText","colorTextMuted","hue","saturation","brightness","alpha","fn","h","s","TraceData","TraceRenderable","_plot","findMinMax","items","currentMin","currentMax","Number","isFinite","Infinity","findMinMax2","keysMin","keysMax","LEGACY_INCREASE","Set","LEGACY_DECREASE","modernizeColor","modern","legacy","has","toLowerCase","getStrokeColor","significance","colors","type","increase","decrease","getStrokeWidth","dlStrokeWidth","dlStrokeWidthMul","createSegmentsBySignificance","segments","segment","stroke","strokeWidth","x0","x1","resolveCurve","curve","d3","LineRenderable","super","render","axisX","axisY","slice","lineGen","d","path","datum","AreaRenderable","keyY0","keyY1","visuals","showErrorArea","y0","y1","fillAreaGradientSeq","FillAreaRenderable","gradientId","gradient","baseline","preparedPlot","areaGen","FocusMarkerRenderable","focusMarker","isConnected","colorFill","marker","ErrorBarsRenderable","keyLow","keyHigh","mode","renderLines","renderBars","barWidth","selectAll","enter","clsPoints","clsLines","keyValue","MarkersRenderable","RectangleRenderable","baseY","topY","ESCAPE_MAP","ScatterLinesInteraction","register","includes","sync","tooltip","ensureTooltip","xRange","range","yRange","onHover","active","event","mouse","mx","my","activeTrace","getTrace","nearest","bestDx","dx","abs","year","setDimmed","setHighlighted","nearby","i","dist","buildRow","n","bold","countText","toLocaleString","replace","c","reset","interactions","ScatterLinesRenderable","NaN","live","baseStrokeWidth","defined","name","linePath","markers","interaction","getInteraction","hitPath","hitCls","hitCircles","onMove","onLeave","on","opacity","ChartRenderable","prepareData","getBarFillColor","getBarStrokeColor","getSeriesColor","getTextColor","fg","calculateTotal","reduce","sum","createTooltipContent","total","label","formattedValue","percentage","toFixed","_isGroupedItem","_groupedChildren","createGroupedTooltipContent","valueLabel","hidePercent","childrenCount","canvasWidth","dlWidth","canvasHeight","dlHeight","maxTooltipWidth","maxTooltipHeight","maxVisibleItems","floor","childrenHtml","visibleCount","child","childFormattedValue","truncateLabel","remainingCount","maxWidth","maxChars","substring","showTooltip","hideTooltip","PieRenderable","PI","groupSmallItems","customOptions","getPieSettings","showLabels","labelType","minLabelAngle","MIN_LABEL_ANGLE","labelPosition","innerRadiusRatio","keepOrder","hoverGrow","onSliceClick","centerText","formatLabel","percent","getLabelColor","pieSettings","radius","innerRadius","group","pieGen","restRadius","arcGen","outerRadius","arcGrown","arcs","paths","currentTarget","transition","duration","_event","renderCenterText","renderLabels","valueSize","sub","subLines","baseDy","line","labelArcGen","centroid","LABEL_FONT_SIZE","endAngle","startAngle","each","arcLength","originalText","BarsRenderable","labels","isHorizontalOrientation","axisYType","categoricalYLabels","axisXType","categoricalXLabels","isHorizontal","values","minValue","maxValue","dimensions","getChartDimensions","renderHorizontalBars","renderVerticalBars","orientation","barSpacing","BAR_SPACE_RATIO","bars","createVerticalBarRects","shouldRenderBarLabels","parseFloat","FONT_SIZE","createVerticalBarLabels","attachTooltips","index","bandwidth","domain","_","toString","padding","bandScale","STROKE_WIDTH","fontSize","plotBounds","right","bottom","alignment","getBarLabelAlignment","barHeight","barTop","barBottom","barCenterX","barBounds","center","textBounds","calculateBarLabelPosition","textAnchor","dominantBaseline","maxTextWidth","truncateTextWithEllipsis","applyBarLabelStyling","createHorizontalBarRects","createHorizontalBarLabels","barLeft","selection","StackedBarsRenderable","getStackSettings","labelMinHeight","stacks","categories","series","maxStackHeight","category","stackTotal","stackSettings","catStr","cumulativeValue","segmentBottom","segmentTop","segmentHeight","rect","attachSegmentTooltip","calculateStackTotal","dot","emph","buildTooltipHtml","HeatmapRenderable","getGrid","grid","xLabels","yLabels","bandX","bandY","row","v","sqrt","rx","attachCellTooltip","rowLabel","colLabel","unit","RadialBarsRenderable","labelSpace","inner","angle","align","radial","_d","padAngle","padRadius","cos","sin","TraceHandler","readItemsTabular","table","header","rows","doRead","defaultHandlers","hideGraph","fillArea","showLine","hideFocus","showMarkers","showErrorBars","keyRteLow","keyRteHigh","getTraceHandlers","ICONS","LABEL_FALLBACKS","ZoomController","fullExtent","opts","requestRedraw","translate","full","panEnabled","resolveOptions","backend","custom","enabled","wheel","drag","pan","clampWindow","win","minSpan","fullSpan","span","zoomAt","cx","factor","cur","view","setView","zoomTo","panTo","startView","domainDx","updateControls","applyCursor","panDragActive","scheduleRedraw","rafPending","requestAnimationFrame","attach","ctx","svgNode","svgRoot","addEventListener","onWheel","passive","dragEnabled","onMouseDown","canPan","activeMode","dragging","cursor","pointerX","gNode","preventDefault","px","pow","deltaY","xScale","invert","button","startSelection","startPan","startPx","lastPx","band","overlay","ev","onUp","removeEventListener","remove","anchorDomain","domainUnderCursorNow","fallback","ensureControls","toolbar","controlsBuilt","mkButton","icon","labelKey","onClick","btn","innerHTML","onclick","panBtn","zoomBtn","resetBtn","insertBefore","firstChild","setActive","className","disabled","display","pendingResizeRedraws","cancelResizeRedraw","elm","observer","disconnect","MyD3","getPreparedPlot","buildSignificanceSegments","stripShortSignificantSegments","result","threshold","seg","year0","year1","prev","next","last","collapseShortSegments","plotIdOrElement","customOptionsOrTranslate","vueTranslation","_plotElementId","_plotElement","zoomOptions","zoom","plotElement","getElementById","Error","buildDefaultTooltip","context","fmt","maximumFractionDigits","minimumFractionDigits","selX","traceData","selectedData","selY","hasData","ci","ciLow","ciHigh","nbSites","ttShowSitesAtBottom","dataType","sigHtml","ttShowSignificance","primary","sig","footer","headerLabel","isInteger","axisTickFontSize","baseFontSize","axisType","explicit","axisFontSize","dlFontSizeMul","resolveCategoricalXLayout","availableSpace","rotation","step","avgCharWidth","maxLabelWidth","spacePerLabel","labelsRotationAngle","perLabel","ceil","applyLabelRotation","textSelection","axis","calcTextSize","preparedData","shouldHideYAxisLabels","yValues","maxHeight","hiddenSVG","measure","str","size","bbox","getBBox","DOMRect","dataMin","dataMax","include","yIncludeValues","pad","yPadTopRatio","computeViewYBounds","lo","hi","xv","yv","calcRotatedXLabelMargin","shouldHideXAxisLabels","maxLabelSpaceRatio","rotationAngle","radians","additionalHeight","clampedHeight","calcMaxYLabelMargin","totalWidth","shouldRenderLabels","hideAxisLabels","shouldHideXAxis","shouldHideYAxis","hideAxes","isZoomEligible","redrawWhenSized","options","ResizeObserver","clientWidth","clientHeight","draw","observe","drawToAlt","margin","cw","ch","plotElm","fsAxisX","fsAxisY","cs","baseTextSize","maxYLabelWidth","maxXLabelHeight","leftMargin","additionalBottomMargin","minLeftMargin","fsTitle","dlTitle","dlSubtitle","zoomView","zoomController","some","layout","tickValues","xAxisLabels","call","tickFormat","originalLabel","tickSize","xCategorical","ticks","bandHeight","yStep","yCategorical","yLo","yHi","fitted","showGridlines","dataLayer","clipId","clipSeq","classicPostRendering","addUI","toolbarContainer","renderContext","yd0","yd1","unityVisible","hideUnityLine","myLine","myLine2","myLine2Text","allFocusMarkers","myTooltip","cy","rw","rh","myRect","crosshairParts","yearMarkers","rteItems","hideAndShow","setCrosshairVisible","crosshairEnabled","bestX","minDiff","bisect","xVal","diff","emphasizeYearMarkers","emphasizeRteItems","tooltipTraces","markerX","markerY","isFirstTraceWithData","potentialItem","pixelX","pixelY","isFirst","tooltipContext","tooltipBuilder","validTrace","py","visible","part","base","isNaN","rootContainer","getComputedStyle","crosshairButton","imageButton","buildDownloadPopup","popupContainer","$t","MIN_W","MIN_H","MAX_W","MAX_H","uid","dlSeq","formatButtons","modal","tabindex","role","backdrop","sectionTitle","field","for","clampInput","input","parsed","closeButton","fitSize","w","grow","shrink","colSize","sizeRow","startW","startH","inputW","inputH","presetRow","presets","screen","plotSize","resCheck","errorText","colLabels","inputTitle","inputSubtitle","subtitle","inputStrokeWidth","inputStrokeWidthMul","inputFontSizeMul","expertMode","expert","expertHead","expertRow","expertCol","formatsRow","format","isValidResolution","downloadName","valid","close","closeDownloadPopup","target","popupKeyHandler","popupWatchTimer","setInterval","add","popupBackdrop","focus","select","clearInterval","querySelector","toSvg","toImage","svgInit","svgString","XMLSerializer","serializeToString","blob","webkitURL","createSvgImage","img","Image","src","downloadClick","downloadLink","revokeObjectURL","svgSize","dl","onload","canvas","getContext","drawImage","imgURI","toDataURL","ellipsisWidth","availableWidthForText","bandSize","minReadable","barLabels","isVertical","clampTextPosition","textLength","minBound","maxBound","halfLength","getValue","getLabel","setLabel","setValue","groupOptions","maxItems","minPercentage","sortedData","groupLabel","totalValue","itemsToKeep","itemsToGroup","keepItems","groupItems","groupedValue","groupedItem","RAW_SCALE_PANEL_OPTIONS","SIG_TO_INT","rowPerYear","panel","best","inlaTrendToTraces","lineR","ymin","ymax","lineTrace","hasSites","sitesPerYear","yearH","yearR","OBS_TYPE_STYLE","W","dash","S","SBB","SEC","DEFAULT_STYLE","tracesFor","payload","inlaToTraces","trend","panels","p123","sites_per_year","JSON","parse","stringify","useTrendsStore","defineStore","state","com","user","plotSettings","speciesDict","defineComponent","mStore","methods","_getStore","computed","store","accountComponent","resolvePlotModel","observationType","adminOverride","default_plot_model","MyPlotSettings","component","fill","fillTo","border","borderTo","weight","graduated","gradientMode","gradientInvert","noDetectionFill","allRegions","mapRegion","resetMapStyle","MAP_STYLE_DEFAULTS","mapStyleSite","mapStyleDistribution","mapStyleRegionDim","emitChange","handleResponse","json","species","observationTypes","bioGeoRegions","biogeo","geoAdministrativeRegions","geoadm","geoRegions1","geo1","geoRegions2","geo2","geoRegions3","geo3","gridSizes","availableGridSizes","tk25Available","defaultObservationType","defaultObservationTypeId","possible_choices","availableCountTypes","filterAvailable","count_types","availableObservationTypes","obs_types","availableBiogeo","biogeo_ids","availableGeo1","geo1_ids","avalaibleGeoAdm","geoadm_ids","year_min","yearMin","year_max","yearMax","selectedRegion","plot_options","po","yearStart","yearEnd","showLocations","showSquares","squareSize","mapAggregation","showDistribution","filterDate","filterDateMonthStart","filterDateMonthEnd","filterDateIncludeNulls","trimModel","trimSerialCorrelation","trimOverdispersion","trimTotals","trimCovariateGeo","trimChangepointsAll","trimStepwise","minCountsPerSite","fillYearGaps","buildOptions","plotModel","geoBounds","mapBounds","canUseMoreOptions","filterDateStart","filterDateEnd","obsLayout","updateMapBounds","oldBounds","available","list","localeCompare","isAdmin","effectiveYearMax","currentYear","Date","getFullYear","yearsMin","cap","years","yearsMax","effectiveMax","addByModZero","maxV","COUNT_BIN_LABELS","hexToRgb","lerp","lerpHue","toLin","toSrgb","rgbToXyz","R","G","B","xyzToRgb","z","_f","cbrt","_fi","t3","xyzToLab","fx","fy","labToXyz","L","fz","labToLch","C","hypot","H","atan2","lchToLab","rgbToOklab","rgbToHsl","interpolate","hexA","hexB","ca","cb","hx","padStart","rgbToHex","A","q","p","hk","hslToRgb","oklabToRgb","gradientColorAt","low","high","gradientSteps","Geo","deg2rad","deg","haversine","lat1","lon1","lat2","lon2","RADIUS_EARTH_KM","rlat1","rlat2","difflat","difflon","asin","SquaresHelper","squareSizeInKm","centerLat","CENTER_LAT_GERMANY","dstY","squareSizeLat","dstX","squareSizeLon","nbLon","nbLat","offsetX","offsetY","coordsByIndex","indexLat","indexLon","MyMap","idMap","tmpLayer","mapLayer","squaresHelper","setSquareSize","sizeInKm","Leaflet","zoomSnap","createTileLayer","createInfoControl","createLegend","createControls","hasCompleteSurvey","siteStats","has_complete_survey","styleForCell","nbLoc","nbLocPos","fillColor","fillOpacity","nb","styleForDistribution","styleForRegionMask","updateRegionStyle","regionLayer","setStyle","scale","imperial","addTo","makeButton","iconHref","ctl","onAdd","div","stopPropagation","centerMap","toggleFullscreen","exportPng","fullscreenElement","elmMap","plotId","getPlotId","elmPlot","resizedListener","getContainer","exitFullscreen","requestFullscreen","corner1","corner2","fitBounds","$refs","layer","cfg","BASEMAPS","OSM","attribution","maxZoom","crossOrigin","subdomains","removeLayer","bringToBack","_addedToMap","infoDiv","onRemove","infoControl","showInfo","HTMLElement","hideInfo","legendHtml","squares","nbCells","nbLocations","obsLabel","ms","steps","borderSteps","lbl","nbNoDetection","sq","nb_loc_pos","$tc","legendDiv","legend","cRect","dpr","devicePixelRatio","fillStyle","fillRect","querySelectorAll","complete","naturalWidth","drawEl","finish","drawExportLegend","toBlob","removeChild","svgRect","clone","cloneNode","transform","xml","onerror","encodeURIComponent","lines","sw","boxH","strokeStyle","lineWidth","strokeRect","textBaseline","font","ln","fillText","tw","measureText","createDistributionLayerFull","geojsonData","distributionLayer","createLocationsLayer","locationsLayer","markerOptions","squareCenter","nb_loc","bindPopup","polygon","latSum","lonSum","end","i2","createHolesFromGeometry","innerBounds","extractCoordinates","geometry","coords","coordinates","coord","hole","features","feature","createRegionLayer","setTimeout","outerBounds","points","ring","isValid","regionBounds","invalidateSize","err","createSitesLayer","squaresLayer","allSquares","baseStyle","poly","polygonFromSquare","bringToFront","bindTooltip","cellTooltipHtml","sticky","direction","cellPopupHtml","contributorNames","contributors","names","cIdx","cmp","tk25","Carto","ArcGIS","Topo","Satellite","ApiCom","extends","MyBase","prefix","speciesTitles","locations","nbCounts","plotError","overall","summary","timings","gof","isInla","obsPlots","created","unmounted","mounted","createMap","trendData","resizeTimeoutId","clearTimeout","resizedFn","elmMap2","basis","updatePlot","handleError","settingsComponent","User","speciesDesc","titles","images","speciesImages","speciesId","counts","sImages","subImages","subDescId","descId","desc","nb_rows","site_stats","plot_error","distfull","region","square_size","updateMapSquare","obsPlotIds","$nextTick","drawObsGrid","drawCombined","getCustomOptions","plotData","trendPlotData","dataMinYear","dataMaxYear","meaning","slope","hasEnoughData","startsWith","baseObsId","merged","order","byId","obsId","own","solidId","isSolid","mergeObsPlots","obsTypeLabels","contributing","status","settingsChanged","updateBrowserUrl","settingsModify","requestRawData","openSitesShortcut","plotOptions","location","lang","urlFor","sitesShortcutUrlForPlotOptions","$i18n","locale","callbackSelectRectangle","moveMap","mapSettingsChanged","latin","first","pathname","split","langPrefix","parts","obs","slug","history","replaceState","all","short","components","props","default","_createElementBlock","_ctx","_hoisted_9","_hoisted_10","_hoisted_12","_hoisted_13","_hoisted_14","severity","_hoisted_15","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","cardStyle","_Fragment","_hoisted_2","_renderSlot","ref","viewBox","emits","open","menuStyle","tabs","currentLabel","opt","layoutOptions","o","currentIsAdminOnly","isAdminOnly","beforeUnmount","teardown","isActive","isAvailable","public","isSelectable","$emit","kind","obsType","selectLayout","toggle","openMenu","positionMenu","onDocPointerDown","focusActiveOption","trigger","innerWidth","minWidth","root","menu","contains","optionButtons","from","buttons","onMenuKeydown","indexOf","activeElement","_createBlock","_Teleport","to","onKeydown","_hoisted_16","_hoisted_17","MyTrendCard","PlotContent","ObsTypeSelect","isGrid","isCombined","hasCombinedContent","effectivePlot","effectivePlotError","_component_MyTrendCard","_createVNode","_component_ObsTypeSelect","onSelect","$event","_component_PlotContent","hello","emitModify","emitMapChange","PlotSettingsBase","basemaps","gradientModes","selectSpecies","selectBioGeo","bg","selectGeo1","selectGeoAdm","geoAdm","selectObservationType","selectObsLayout","selectMapLayer","setStyleColor","styleKey","selectWeight","resetStyling","selectMapAggregation","selectYearStart","selectYearEnd","capitalizeAll","toUpperCase","substr","cellGradientCss","rgb","hsl","lab","lch","oklch","spec","geo","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_29","_hoisted_30","_hoisted_32","_hoisted_33","_hoisted_34","_hoisted_35","_hoisted_37","_hoisted_39","_hoisted_40","_hoisted_41","_hoisted_43","_hoisted_47","_hoisted_48","_hoisted_49","_hoisted_50","_hoisted_51","onChange","_hoisted_53","_hoisted_54","_hoisted_55","_hoisted_56","_hoisted_57","_hoisted_58","_hoisted_59","_hoisted_60","_hoisted_61","_hoisted_62","_hoisted_63","_hoisted_64","_hoisted_65","_hoisted_67","_hoisted_68","_hoisted_69","_hoisted_70","_hoisted_71","_hoisted_72","_hoisted_73","_hoisted_74","_hoisted_75","_hoisted_76","bm","_hoisted_78","_hoisted_79","_hoisted_80","_hoisted_81","_hoisted_82","_hoisted_83","_hoisted_84","_hoisted_85","_hoisted_86","_hoisted_87","background","onInput","_hoisted_89","_hoisted_90","_hoisted_91","_hoisted_93","_hoisted_94","_hoisted_95","_hoisted_96","_hoisted_98","_hoisted_99","_hoisted_100","_hoisted_101","_hoisted_103","_hoisted_104","_hoisted_105","_hoisted_107","_hoisted_108","_hoisted_110","_hoisted_111","_hoisted_113","_hoisted_114","_hoisted_115","_hoisted_116","_hoisted_117","_hoisted_118","_hoisted_119","_hoisted_120","_hoisted_121","_hoisted_123","_hoisted_124","_hoisted_125","_hoisted_126","_hoisted_127","_hoisted_128","_hoisted_129","_hoisted_130","_hoisted_131","_hoisted_132","bottomBar","bottomBarClass","bottomBarText","getSpeciesImage","imgData","extension","cssClassesImage","bottomText","srcset","SpeciesImage","indicators","mkey","carouselId","_component_SpeciesImage","openItems","supplierHasInfo","supplier","toggleOpen","updated","contributor","cnt","locs","description","_hoisted_18","_hoisted_19","colspan","se_add","mul","se_mul","convergence","overdispersion","serialcorrelation","chi2","df","lr","LR","_hoisted_20","_hoisted_21","aic","showSelectSites","isStaff","downloadCsv","downloadCsvDemo","demo","gofData","plotIdPrefix","expanded","plotIds","qq","residVsFit","histogram","obsVsFit","watch","renderPlots","toggleExpanded","formatNumber","renderQQPlot","renderResidVsFitPlot","renderHistogram","renderObsVsFitPlot","getPlotDimensions","elementId","innerHeight","xExtent","theoretical","yExtent","residuals","lineExtent","xData","eta","bins","xDomain","xmin","xmax","breaks","allVals","observed","extent","f","stats","deviance","gcv","n_sampled","n_points","_hoisted_22","_hoisted_23","_hoisted_27","_hoisted_28","_hoisted_38","_hoisted_42","GofDiagnostics","DownloadData","TimingsInfo","TrimInfo","ContributorsAccordion","selectedObsId","immediate","ids","showPicker","activeContributors","_component_ContributorsAccordion","_component_TimingsInfo","_component_GofDiagnostics","_component_TrimInfo","onDownload","_component_DownloadData","onSelectSites","useAccountStore","plogis","exp","expLink","PART_META","num","GeoCom","spatial","required","fixedPart","geoLayer","resizeObserver","domainMin","domainMax","partMeta","txt","partLabel","note","tkPrefix","noPosterior","crInterval","rawEta","activePart","dataBySheet","c2t","car_index_to_tk25","out","sheet","ID","mean","QL","QH","renderLayer","fetchGeometry","zoomControl","attributionControl","scrollWheelZoom","doubleClickZoom","keyboard","touchZoom","boxZoom","zoomAnimation","fadeAnimation","markerZoomAnimation","refitMap","sheets","rb","colorScale","vals","styleFor","fc","feat","onEachFeature","showTip","originalEvent","resetStyle","hideTip","getBounds","tip","head","sd","gap","offsetWidth","th","offsetHeight","vw","vh","clientX","clientY","placeTip","InlaSpatialMap","columns","trendId","statKey","showPartSites","mapLabels","renderTrends","col","pd","_component_InlaSpatialMap","countTypes","pages","computedStyles","nbPerRow","nbRows","imgs","previewSpeciesHtml","clickSpecies","page","random","SignificantSegment","iconSizeLarge","iconSize","pp","significantSegments","displayInsignificants","updateFromPlot","significantTrace","itm","sigsegs","segmentsRaw","cssTrend","css","colorBySeg","svgTrend","timespanText","PlotsBase","TrendComponentGAM","SpeciesPreviewCarousel","TcMore","InlaComponentCard","PlotErrorSmall","SpeciesImageCarousel","PlotSettings2","TcMap","PlotCard","MySpinner","isMoreInfoOpen","highlight","evt","elements","toggleMoreInfo","openSpeciesDropdown","bootstrap","Dropdown","removeAttribute","selectObsType","subSpecies","isAdminOnlyView","isGridLayout","_component_MySpinner","_component_PlotSettings2","onSettingsChanged","onSettingsModify","onMapSettingsChanged","_component_SpeciesImageCarousel","$options","_component_PlotErrorSmall","_component_TrendComponentGAM","nb_rows_positive","nb_sites_positive","subKey","_hoisted_31","onMouseenter","onMouseleave","_hoisted_36","_component_SpeciesPreviewCarousel","onSelectSpecies","_component_PlotCard","onSelectObsType","_component_TcMap","_component_InlaComponentCard","_component_TcMore","PlotsThree","myView","getAttribute","_cache","$props","$setup","$data","_component_PlotsThree","_resolveComponent","_openBlock","pinia","createPinia","i18n","messages","createI18n","global","async","setLocaleMessage","nextTick","loadLocaleMessages","setI18nLanguage","setupI18n","vueI18n","createApp","App","use","mount","webpackAsyncContext","req","__webpack_require__","Promise","resolve","code","module","exports","__webpack_module_cache__","moduleId","cachedModule","__webpack_modules__","O","chunkIds","priority","notFulfilled","fulfilled","j","every","splice","getter","__esModule","getPrototypeOf","obj","__proto__","ns","current","getOwnPropertyNames","definition","defineProperty","enumerable","chunkId","promises","u","miniCssF","globalThis","Function","prototype","hasOwnProperty","done","script","needAttach","scripts","getElementsByTagName","charset","timeout","nc","onScriptComplete","doneFns","parentNode","bind","Symbol","toStringTag","installedChunks","installedChunkData","promise","reject","errorType","realSrc","request","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","chunkLoadingGlobal","self","__webpack_exports__"],"sourceRoot":""}