β Back to parkrun Userscripts
Adds an annual participation summary (totals, averages, min/max) to parkrun event history pages
What is a userscript?
A userscript is a small piece of JavaScript that runs in your browser and enhances specific websites. These scripts work with parkrun event pages, parkrunner profile pages, and results pages, and can be used with any userscript manager including Userscripts, Tampermonkey, Violentmonkey, or any compatible browser extension.
Installation
-
Install a userscript manager for your browser:
- Desktop: Userscripts (Safari), Tampermonkey (Chrome, Firefox, Edge, Opera), or Violentmonkey (Orion)
- iOS: Userscripts (Safari) or Violentmonkey (Orion)
- Android: Install Kiwi Browser, then install Tampermonkey or Violentmonkey from the Chrome Web Store.
- Click the install link below for this script.
- Click βInstallβ when prompted by your userscript manager.
Install parkrun Annual Summary
Bookmarklet version
You can also use this script as a bookmarklet (a bookmark whose URL is JavaScript), which can be useful on browsers that support bookmarks but not userscript managers.
Desktop bookmarklet
Drag this link to your bookmarks bar:
parkrun Annual Summary bookmarklet
Mobile bookmarklet
On mobile browsers that let you edit bookmark URLs:
- Copy the JavaScript code below to your clipboard.
- Create a new bookmark for any page.
- Edit the bookmark and replace its URL with the code you copied.
- Navigate to the relevant parkrun page.
- Select the bookmark to run the script.
javascript:function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _toConsumableArray(e){return _arrayWithoutHoles(e)||_iterableToArray(e)||_unsupportedIterableToArray(e)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArray(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}function _regenerator(){var m,e="function"==typeof Symbol?Symbol:{},t=e.iterator||"@@iterator",r=e.toStringTag||"@@toStringTag";function n(e,t,r,n){var o,a,l,i,s,c,u,d,p,t=t&&t.prototype instanceof f?t:f,t=Object.create(t.prototype);return _regeneratorDefine2(t,"_invoke",(o=e,a=r,u=n||[],d=!1,p={p:c=0,n:0,v:m,a:y,f:y.bind(m,4),d:function(e,t){return l=e,i=0,s=m,p.n=t,h}},function(e,t,r){if(1<c)throw TypeError("Generator is already running");for(d&&1===t&&y(t,r),i=t,s=r;(g=i<2?m:s)||!d;){l||(i?i<3?(1<i&&(p.n=-1),y(i,s)):p.n=s:p.v=s);try{if(c=2,l){if(g=l[e=i?e:"next"]){if(!(g=g.call(l,s)))throw TypeError("iterator result is not an object");if(!g.done)return g;s=g.value,i<2&&(i=0)}else 1===i&&(g=l.return)&&g.call(l),i<2&&(s=TypeError("The iterator does not provide a '"+e+"' method"),i=1);l=m}else if((g=(d=p.n<0)?s:o.call(a,p))!==h)break}catch(e){l=m,i=1,s=e}finally{c=1}}return{value:g,done:d}}),!0),t;function y(e,t){for(i=e,s=t,g=0;!d&&c&&!r&&g<u.length;g++){var r,n=u[g],o=p.p,a=n[2];3<e?(r=a===t)&&(s=n[(i=n[4])?5:i=3],n[4]=n[5]=m):n[0]<=o&&((r=e<2&&o<n[1])?(i=0,p.v=t,p.n=n[1]):o<a&&(r=e<3||n[0]>t||a<t)&&(n[4]=e,n[5]=t,p.n=a,i=0))}if(r||1<e)return h;throw d=!0,t}}var h={};function f(){}function o(){}function a(){}var g=Object.getPrototypeOf,e=[][t]?g(g([][t]())):(_regeneratorDefine2(g={},t,function(){return this}),g),l=a.prototype=f.prototype=Object.create(e);function i(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,a):(e.__proto__=a,_regeneratorDefine2(e,r,"GeneratorFunction")),e.prototype=Object.create(l),e}return _regeneratorDefine2(l,"constructor",o.prototype=a),_regeneratorDefine2(a,"constructor",o),_regeneratorDefine2(a,r,o.displayName="GeneratorFunction"),_regeneratorDefine2(l),_regeneratorDefine2(l,r,"Generator"),_regeneratorDefine2(l,t,function(){return this}),_regeneratorDefine2(l,"toString",function(){return"[object Generator]"}),(_regenerator=function(){return{w:n,m:i}})()}function _regeneratorDefine2(e,t,r,n){var a=Object.defineProperty;try{a({},"",{})}catch(e){a=0}(_regeneratorDefine2=function(e,t,r,n){function o(t,r){_regeneratorDefine2(e,t,function(e){return this._invoke(t,r,e)})}t?a?a(e,t,{value:r,enumerable:!n,configurable:!n,writable:!n}):e[t]=r:(o("next",0),o("throw",1),o("return",2))})(e,t,r,n)}function ownKeys(t,e){var r,n=Object.keys(t);return Object.getOwnPropertySymbols&&(r=Object.getOwnPropertySymbols(t),e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),n.push.apply(n,r)),n}function _objectSpread(t){for(var e=1;e<arguments.length;e++){var r=null!=arguments[e]?arguments[e]:{};e%2?ownKeys(Object(r),!0).forEach(function(e){_defineProperty(t,e,r[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):ownKeys(Object(r)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))})}return t}function _defineProperty(e,t,r){return(t=_toPropertyKey(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function _toPropertyKey(e){e=_toPrimitive(e,"string");return"symbol"==_typeof(e)?e:e+""}function _toPrimitive(e,t){if("object"!=_typeof(e)||!e)return e;var r=e[Symbol.toPrimitive];if(void 0===r)return("string"===t?String:Number)(e);r=r.call(e,t||"default");if("object"!=_typeof(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}function _slicedToArray(e,t){return _arrayWithHoles(e)||_iterableToArrayLimit(e,t)||_unsupportedIterableToArray(e,t)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){var r;if(e)return"string"==typeof e?_arrayLikeToArray(e,t):"Map"===(r="Object"===(r={}.toString.call(e).slice(8,-1))&&e.constructor?e.constructor.name:r)||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(e,t):void 0}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function _iterableToArrayLimit(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,a,l,i=[],s=!0,c=!1;try{if(a=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;s=!1}else for(;!(s=(n=a.call(r)).done)&&(i.push(n.value),i.length!==t);s=!0);}catch(e){c=!0,o=e}finally{try{if(!s&&null!=r.return&&(l=r.return(),Object(l)!==l))return}finally{if(c)throw o}}return i}}function _arrayWithHoles(e){if(Array.isArray(e))return e}function asyncGeneratorStep(e,t,r,n,o,a,l){try{var i=e[a](l),s=i.value}catch(e){return void r(e)}i.done?t(s):Promise.resolve(s).then(n,o)}function _asyncToGenerator(i){return function(){var e=this,l=arguments;return new Promise(function(t,r){var n=i.apply(e,l);function o(e){asyncGeneratorStep(n,t,r,o,a,"next",e)}function a(e){asyncGeneratorStep(n,t,r,o,a,"throw",e)}o(void 0)})}}(()=>{var w={backgroundColor:"#1c1b2a",barColor:"#f59e0b",lineColor:"#22d3ee",textColor:"#f3f4f6",subtleTextColor:"#d1d5db",gridColor:"rgba(243, 244, 246, 0.18)"},E=["#f59e0b","#22d3ee","#f97316","#10b981","#a855f7","#ef4444","#3b82f6","#84cc16"],S={currentEvent:null,comparisonEvents:[],allParkruns:null};function n(){return(n=_asyncToGenerator(_regenerator().m(function e(){var t,r,n,o,a,l;return _regenerator().w(function(e){for(;;)switch(e.p=e.n){case 0:if(t="parkrun_events_cache",e.p=1,a=localStorage.getItem(t)){if(e.p=2,a=JSON.parse(a),n=a.data,a=a.timestamp,(a=Date.now()-a)<864e5)return console.log("Using cached parkrun events (".concat(Math.round(a/1e3/60)," minutes old)")),e.a(2,n);e.n=3}else e.n=5;break;case 3:e.n=5;break;case 4:e.p=4,a=e.v,console.log("Cache parse error, fetching fresh data",a);case 5:return console.log("Fetching parkrun events from https://images.parkrun.com/events.json"),e.n=6,fetch("https://images.parkrun.com/events.json");case 6:if(r=e.v,console.log("Fetch response status:",r.status,r.statusText),r.ok){e.n=7;break}return console.error("Fetch failed with status:",r.status),e.a(2,[]);case 7:return e.n=8,r.json();case 8:if(n=e.v,o=(null==(o=n.events)?void 0:o.features)||n.features||[],console.log("Features array length:",o.length),o&&0!==o.length){e.n=9;break}return console.error("No features found in response data"),e.a(2,[]);case 9:try{localStorage.setItem(t,JSON.stringify({data:o,timestamp:Date.now()})),console.log("Cached",o.length,"parkrun events for 24 hours")}catch(e){console.warn("Failed to cache parkrun events:",e)}return console.log("Successfully loaded",o.length,"parkrun events"),e.a(2,o);case 10:return e.p=10,l=e.v,console.error("Failed to fetch parkruns:",l),console.error("Error details:",l.message,l.stack),e.a(2,[])}},e,null,[[2,4],[1,10]])}))).apply(this,arguments)}function _(){return{eventName:window.location.pathname.split("/")[1],domain:window.location.hostname,url:window.location.origin}}function A(e,t,r,n){var o=(r-e)*Math.PI/180,n=(n-t)*Math.PI/180,t=Math.sin(o/2)*Math.sin(o/2)+Math.cos(e*Math.PI/180)*Math.cos(r*Math.PI/180)*Math.sin(n/2)*Math.sin(n/2);return 6371*(2*Math.atan2(Math.sqrt(t),Math.sqrt(1-t)))}function a(){return(a=_asyncToGenerator(_regenerator().m(function e(t,r){var n,o,a,l;return _regenerator().w(function(e){for(;;)if(0===e.n)return n=t.cloneNode(!0),a=t.querySelectorAll("canvas"),o=n.querySelectorAll("canvas"),a.forEach(function(e,t){try{var r=e.toDataURL("image/png"),n=document.createElement("img");n.src=r,n.alt="Chart snapshot",n.style.maxWidth="100%",n.style.display="block",n.style.backgroundColor="#2b223d",o[t]&&o[t].replaceWith(n)}catch(e){console.error("Failed to serialize chart canvas:",e)}}),a="\n :root { color-scheme: dark; }\n body { margin: 0; padding: 20px; background: ".concat(w.backgroundColor,"; color: ").concat(w.textColor,'; font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif; line-height: 1.5; }\n a { color: ').concat(w.lineColor,"; }\n h1, h2, h3, h4 { color: ").concat(w.barColor,"; margin: 0 0 10px 0; }\n table { width: 100%; border-collapse: collapse; }\n th, td { border: 1px solid ").concat(w.gridColor,"; padding: 10px; text-align: left; }\n th { background: #2b223d; color: ").concat(w.barColor,"; }\n tr:nth-child(even) td { background: #241c35; }\n tr:nth-child(odd) td { background: #1f182e; }\n .parkrun-annual-summary { background: ").concat(w.backgroundColor,"; padding: 16px; border-radius: 6px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25); }\n .chart-img { max-width: 100%; display: block; }\n .meta { margin-bottom: 16px; color: ").concat(w.subtleTextColor,"; font-size: 13px; }\n .meta strong { color: ").concat(w.textColor,"; }\n "),l='\n <header>\n <h1>parkrun Annual Summary</h1>\n <div class="meta">\n <div><strong>Event:</strong> '.concat(r.eventShortName,"</div>\n <div><strong>Generated:</strong> ").concat(r.generatedAt,"</div>\n </div>\n </header>\n "),e.a(2,'<!DOCTYPE html><html><head><meta charset="UTF-8"><title>parkrun Annual Summary - '.concat(r.eventShortName,"</title><style>").concat(a,"</style></head><body>").concat(l).concat(n.outerHTML,"</body></html>"))},e)}))).apply(this,arguments)}function T(){return e.apply(this,arguments)}function e(){return(e=_asyncToGenerator(_regenerator().m(function e(t,r){var n,o;return _regenerator().w(function(e){for(;;)switch(e.n){case 0:return e.n=1,function(){return a.apply(this,arguments)}(t,r);case 1:return n=e.v,o="parkrun-annual-summary-".concat(r.eventShortName,"-").concat(r.generatedAtISO,".html"),e.a(2,{blob:new Blob([n],{type:"text/html"}),filename:o})}},e)}))).apply(this,arguments)}function i(){return(i=_asyncToGenerator(_regenerator().m(function e(t,r){var n,o,a,l,i,s,c;return _regenerator().w(function(e){for(;;)switch(e.p=e.n){case 0:return e.p=0,n="".concat(r,"/").concat(t,"/results/eventhistory/"),e.n=1,fetch(n);case 1:return n=e.v,e.n=2,n.text();case 2:return o=e.v,c=new DOMParser,c=c.parseFromString(o,"text/html"),o=null!=(o=null==(o=c.querySelector("h1"))?void 0:o.textContent.trim())?o:"".concat(t," Event History"),a=[],l=[],i=[],s=[],c=c.querySelectorAll("tr.Results-table-row"),Array.from(c).reverse().forEach(function(e){var t=e.getAttribute("data-parkrun"),t=(t&&a.push(t),e.getAttribute("data-date")),t=(t&&(t=new Date(t).toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"}),l.push(t)),e.getAttribute("data-finishers")),t=(t&&i.push(parseInt(t,10)),e.getAttribute("data-volunteers"));t&&s.push(parseInt(t,10))}),e.a(2,{eventName:t,title:o,eventNumbers:a,dates:l,finishers:i,volunteers:s});case 3:return e.p=3,c=e.v,console.error("Failed to fetch event history for ".concat(t,":"),c),e.a(2,null)}},e,null,[[0,3]])}))).apply(this,arguments)}function F(a){var l={};return a.dates.forEach(function(e,t){var e=new Date(e).getFullYear(),r=null!=(r=a.finishers[t])?r:0,n=null!=(n=a.volunteers[t])?n:0,o=a.eventNumbers[t],e=(l[e]||(l[e]={year:e,eventCount:0,totalFinishers:0,totalVolunteers:0,minFinishers:null,maxFinishers:null,minVolunteers:null,maxVolunteers:null}),l[e]);e.eventCount++,e.totalFinishers+=r,e.totalVolunteers+=n,(null===e.minFinishers||r<e.minFinishers.value)&&(e.minFinishers={value:r,date:a.dates[t],eventNumber:o}),(null===e.maxFinishers||r>e.maxFinishers.value)&&(e.maxFinishers={value:r,date:a.dates[t],eventNumber:o}),(null===e.minVolunteers||n<e.minVolunteers.value)&&(e.minVolunteers={value:n,date:a.dates[t],eventNumber:o}),(null===e.maxVolunteers||n>e.maxVolunteers.value)&&(e.maxVolunteers={value:n,date:a.dates[t],eventNumber:o})}),Object.keys(l).map(Number).sort(function(e,t){return e-t}).map(function(e){var t=l[e];return{year:e,eventCount:t.eventCount,totalFinishers:t.totalFinishers,totalVolunteers:t.totalVolunteers,avgFinishers:Math.round(t.totalFinishers/t.eventCount),avgVolunteers:Math.round(t.totalVolunteers/t.eventCount),minFinishers:t.minFinishers,maxFinishers:t.maxFinishers,minVolunteers:t.minVolunteers,maxVolunteers:t.maxVolunteers,finishersGrowth:null,volunteersGrowth:null}}).map(function(e,t,r){return 0===t?e:(t=(r=r[t-1]).avgFinishers?(e.avgFinishers-r.avgFinishers)/r.avgFinishers*100:null,r=r.avgVolunteers?(e.avgVolunteers-r.avgVolunteers)/r.avgVolunteers*100:null,_objectSpread(_objectSpread({},e),{},{finishersGrowth:t,volunteersGrowth:r}))})}function p(e){return e?e.value.toLocaleString():"-"}function y(e){var t,r;return null===e||Number.isNaN(e)?"-":(t=0<e?"+":"",r=0<e?"#53BA9D":e<0?"#ff6b6b":w.subtleTextColor,'<span style="color: '.concat(r,';">').concat(t).concat(e.toFixed(1),"%</span>"))}function N(o){var e=document.createElement("div"),t=(e.style.marginBottom="15px",e.style.padding="10px",e.style.backgroundColor=w.backgroundColor,e.style.borderRadius="6px",e.style.display="flex",e.style.alignItems="center",e.style.gap="10px",e.style.flexWrap="wrap",document.createElement("span")),a=(t.textContent="Compare with:",t.style.color=w.textColor,t.style.fontWeight="bold",e.appendChild(t),document.createElement("select")),t=(a.style.padding="6px 12px",a.style.backgroundColor="#3a3250",a.style.color=w.textColor,a.style.border="1px solid ".concat(w.gridColor),a.style.borderRadius="4px",a.style.cursor="pointer",document.createElement("option")),l=(t.value="",t.textContent="-- Select parkrun --",a.appendChild(t),o.forEach(function(e){var t=document.createElement("option");t.value=e.properties.eventname,t.textContent="".concat(e.properties.EventShortName," (").concat(e.distance.toFixed(1),"km)"),a.appendChild(t)}),document.createElement("button"));return l.textContent="+ Add",l.style.padding="6px 12px",l.style.backgroundColor=w.lineColor,l.style.color="#2b223d",l.style.border="none",l.style.borderRadius="4px",l.style.cursor="pointer",l.style.fontWeight="bold",l.addEventListener("click",_asyncToGenerator(_regenerator().m(function e(){var t,r,n;return _regenerator().w(function(e){for(;;)switch(e.n){case 0:if(t=a.value){e.n=1;break}return e.a(2);case 1:if(S.comparisonEvents.some(function(e){return e.eventName===t}))return alert("This parkrun is already selected for comparison"),e.a(2);e.n=2;break;case 2:return l.disabled=!0,l.textContent="Loading...",r=_(),e.n=3,function(){return i.apply(this,arguments)}(t,r.url);case 3:(r=e.v)?(n=o.find(function(e){return e.properties.eventname===t}),S.comparisonEvents.push(_objectSpread(_objectSpread({},r),{},{distance:null==n?void 0:n.distance})),G()):alert("Failed to fetch event history"),l.disabled=!1,l.textContent="+ Add",a.value="";case 4:return e.a(2)}},e)}))),e.appendChild(a),e.appendChild(l),e}function j(e,t){var r=F(e);if(0===r.length)return null;var e=document.createElement("div"),n=(e.className="tab-content",e.style.display=0===t?"block":"none",e.style.backgroundColor=w.backgroundColor,e.style.padding="15px",e.style.borderRadius="6px",document.createElement("div")),o=(n.style.overflowX="auto",document.createElement("table")),a=(o.className="annualSummaryTable",o.style.width="100%",o.style.borderCollapse="collapse",o.style.fontSize="14px",o.style.color=w.textColor,o.style.backgroundColor=w.backgroundColor,{key:"year",dir:"asc"}),l=[{key:"year",label:"Year",align:"left"},{key:"eventCount",label:"Events",align:"center"},{key:"totalFinishers",label:"Finishers Total",align:"right",color:w.barColor},{key:"minFinishers",label:"Finishers Min",align:"right",color:w.barColor},{key:"maxFinishers",label:"Finishers Max",align:"right",color:w.barColor},{key:"avgFinishers",label:"Finishers Avg",align:"right",color:w.barColor},{key:"finishersGrowth",label:"Finishers YoY",align:"right"},{key:"totalVolunteers",label:"Volunteers Total",align:"right",color:w.lineColor},{key:"minVolunteers",label:"Volunteers Min",align:"right",color:w.lineColor},{key:"maxVolunteers",label:"Volunteers Max",align:"right",color:w.lineColor},{key:"avgVolunteers",label:"Volunteers Avg",align:"right",color:w.lineColor},{key:"volunteersGrowth",label:"Volunteers YoY",align:"right"}],i=document.createElement("thead"),s=document.createElement("tr"),c=(s.style.borderBottom="2px solid ".concat(w.gridColor),l.forEach(function(e){var t=document.createElement("th");t.textContent=e.label,t.style.padding="10px",t.style.textAlign=e.align,t.style.cursor="pointer",e.color&&(t.style.color=e.color),t.addEventListener("click",function(){a.key===e.key?a.dir="asc"===a.dir?"desc":"asc":(a.key=e.key,a.dir="desc"),u()}),s.appendChild(t)}),i.appendChild(s),o.appendChild(i),document.createElement("tbody"));function u(){c.innerHTML="",_toConsumableArray(r).sort(function(e,t){function r(e){return null==(e=e[n])?-1/0:"object"===_typeof(e)&&void 0!==e.value?e.value:e}var n=a.key,o="asc"===a.dir?1:-1,e=r(e),t=r(t);return e===t?0:t<e?o:-o}).forEach(function(e){var t=document.createElement("tr");t.style.borderBottom="1px solid ".concat(w.gridColor),t.innerHTML='\n <td style="padding: 10px; text-align: left; font-weight: bold;">'.concat(e.year,'</td>\n <td style="padding: 10px; text-align: center;">').concat(e.eventCount,'</td>\n <td style="padding: 10px; text-align: right; color: ').concat(w.barColor,';">').concat(e.totalFinishers.toLocaleString(),'</td>\n <td style="padding: 10px; text-align: right; color: ').concat(w.barColor,';">').concat(p(e.minFinishers),'</td>\n <td style="padding: 10px; text-align: right; color: ').concat(w.barColor,';">').concat(p(e.maxFinishers),'</td>\n <td style="padding: 10px; text-align: right; color: ').concat(w.barColor,';">').concat(e.avgFinishers,'</td>\n <td style="padding: 10px; text-align: right;">').concat(y(e.finishersGrowth),'</td>\n <td style="padding: 10px; text-align: right; color: ').concat(w.lineColor,';">').concat(e.totalVolunteers.toLocaleString(),'</td>\n <td style="padding: 10px; text-align: right; color: ').concat(w.lineColor,';">').concat(p(e.minVolunteers),'</td>\n <td style="padding: 10px; text-align: right; color: ').concat(w.lineColor,';">').concat(p(e.maxVolunteers),'</td>\n <td style="padding: 10px; text-align: right; color: ').concat(w.lineColor,';">').concat(e.avgVolunteers,'</td>\n <td style="padding: 10px; text-align: right;">').concat(y(e.volunteersGrowth),"</td>\n "),c.appendChild(t)})}o.appendChild(c),n.appendChild(o),e.appendChild(n),u();var l=document.createElement("div"),i=(l.style.display="grid",l.style.gridTemplateColumns="1fr 1fr",l.style.gap="20px",l.style.marginTop="20px",document.createElement("div")),o=(i.style.minWidth="0",document.createElement("canvas")),n=(o.className="annualTotalsChart-".concat(t),i.appendChild(o),document.createElement("div")),d=(n.style.minWidth="0",document.createElement("canvas"));return d.className="annualGrowthChart-".concat(t),n.appendChild(d),l.appendChild(i),l.appendChild(n),e.appendChild(l),"undefined"!=typeof Chart&&(t=o.getContext("2d"),i=d.getContext("2d"),n=r.map(function(e){return e.year.toString()}),new Chart(t,{type:"bar",data:{labels:n,datasets:[{label:"Total Finishers",data:r.map(function(e){return e.totalFinishers}),backgroundColor:w.barColor,borderColor:w.barColor,borderWidth:1},{label:"Total Volunteers",data:r.map(function(e){return e.totalVolunteers}),backgroundColor:w.lineColor,borderColor:w.lineColor,borderWidth:1}]},options:{animation:!1,responsive:!0,maintainAspectRatio:!0,aspectRatio:1.3,plugins:{legend:{labels:{color:w.textColor}},title:{display:!0,text:"Annual Totals",color:w.textColor}},scales:{x:{title:{display:!0,text:"Year",color:w.textColor},ticks:{color:w.subtleTextColor},grid:{color:w.gridColor}},y:{beginAtZero:!0,title:{display:!0,text:"Participants",color:w.textColor},ticks:{precision:0,color:w.subtleTextColor},grid:{color:w.gridColor}}}}}),l=r.filter(function(e){return null!==e.finishersGrowth}),new Chart(i,{type:"line",data:{labels:l.map(function(e){return e.year.toString()}),datasets:[{label:"Finishers Growth",data:l.map(function(e){return e.finishersGrowth}),borderColor:w.barColor,backgroundColor:w.barColor,borderWidth:2,pointRadius:4,pointBackgroundColor:w.barColor,fill:!1,tension:.2},{label:"Volunteers Growth",data:l.map(function(e){return e.volunteersGrowth}),borderColor:w.lineColor,backgroundColor:w.lineColor,borderWidth:2,pointRadius:4,pointBackgroundColor:w.lineColor,fill:!1,tension:.2}]},options:{animation:!1,responsive:!0,maintainAspectRatio:!0,aspectRatio:1.3,plugins:{legend:{labels:{color:w.textColor}},title:{display:!0,text:"Year-over-Year Growth (%)",color:w.textColor}},scales:{x:{title:{display:!0,text:"Year",color:w.textColor},ticks:{color:w.subtleTextColor},grid:{color:w.gridColor}},y:{title:{display:!0,text:"Growth (%)",color:w.textColor},ticks:{color:w.subtleTextColor,callback:function(e){return e+"%"}},grid:{color:w.gridColor}}}}})),e}function O(e){var t=document.createElement("div");return t.style.minWidth="0",t.appendChild(e),t}function V(e,t,o,r,a,n,l){l=6<arguments.length&&void 0!==l&&l,r=r.map(function(e,t){var r=e.event,n=e.yearly,e=E[t%E.length],t=o.map(function(t){var e=n.find(function(e){return e.year===t});return e&&null!=(e=a(e))?e:null});return{label:r.title||r.eventName,data:t,borderColor:e,backgroundColor:e,borderWidth:2,pointRadius:4,pointBackgroundColor:e,fill:!1,tension:.2,spanGaps:!0}}),e=e.getContext("2d");new Chart(e,{type:"line",data:{labels:o.map(function(e){return e.toString()}),datasets:r},options:{animation:!1,responsive:!0,maintainAspectRatio:!0,aspectRatio:1.3,plugins:{legend:{labels:{color:w.textColor}},title:{display:!0,text:t,color:w.textColor}},scales:{x:{title:{display:!0,text:"Year",color:w.textColor},ticks:{color:w.subtleTextColor},grid:{color:w.gridColor}},y:{beginAtZero:!l,title:{display:!0,text:n,color:w.textColor},ticks:{precision:0,color:w.subtleTextColor,callback:l?function(e){return e+"%"}:void 0},grid:{color:w.gridColor}}}}})}function G(){var r,n,o,a,l,i,e,s,c,t,u,d,p,y,m,h,f,g,b,v,x=document.querySelector(".parkrun-annual-summary"),C=(x&&x.remove(),x=null!=(x=null==(x=document.querySelector("h1"))?void 0:x.textContent.trim())?x:"Event History",r=[],n=[],o=[],a=[],C=document.querySelectorAll("tr.Results-table-row"),Array.from(C).reverse().forEach(function(e){var t=e.getAttribute("data-parkrun"),t=(t&&r.push(t),e.getAttribute("data-date")),t=(t&&(t=new Date(t).toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"}),n.push(t)),e.getAttribute("data-finishers")),t=(t&&o.push(parseInt(t,10)),e.getAttribute("data-volunteers"));t&&a.push(parseInt(t,10))}),{title:x,eventNumbers:r,dates:n,finishers:o,volunteers:a});function k(){l.innerHTML="",[S.currentEvent].concat(_toConsumableArray(S.comparisonEvents)).forEach(function(e,t){var r=document.createElement("div"),n=(r.style.display="inline-flex",r.style.alignItems="center",r.style.gap="6px",r.style.padding="4px 10px",r.style.backgroundColor=E[t%E.length],r.style.color="#2b223d",r.style.borderRadius="12px",r.style.fontSize="12px",r.style.fontWeight="bold",document.createElement("span"));n.textContent=e.title||e.eventName,r.appendChild(n),0<t&&((e=document.createElement("span")).textContent="Γ",e.style.cursor="pointer",e.style.marginLeft="4px",e.style.fontSize="16px",e.addEventListener("click",function(){S.comparisonEvents.splice(t-1,1),G()}),r.appendChild(e)),l.appendChild(r)})}0===C.eventNumbers.length?console.log("No event history data found"):(S.currentEvent=_objectSpread(_objectSpread({},C),{},{eventName:_().eventName}),x=[S.currentEvent].concat(_toConsumableArray(S.comparisonEvents)),(C=document.createElement("div")).className="parkrun-annual-summary",C.style.width="100%",C.style.maxWidth="1200px",C.style.margin="20px auto",C.style.padding="15px",C.style.backgroundColor=w.backgroundColor,C.style.borderRadius="8px",C.style.boxShadow="0 2px 4px rgba(0,0,0,0.1)",(t=document.createElement("h3")).textContent="Annual Participation Summary",t.style.textAlign="center",t.style.marginBottom="15px",t.style.color=w.barColor,C.appendChild(t),null===S.allParkruns?((t=document.createElement("div")).style.padding="10px",t.style.color=w.subtleTextColor,t.style.textAlign="center",t.style.fontSize="13px",t.textContent="Loading parkrun events for comparison...",C.appendChild(t)):0===S.allParkruns.length?((t=document.createElement("div")).style.padding="10px",t.style.color="#ff6b6b",t.style.textAlign="center",t.style.fontSize="13px",t.textContent="Failed to load parkrun events data. Check console for details.",C.appendChild(t),console.error("No parkrun events loaded. Expected data from https://images.parkrun.com/events.json")):0<(t=function(o,e,t){var r,a,l,i,s,c=2<arguments.length&&void 0!==t?t:50,t=e.find(function(e){return e.properties.eventname===o.eventName});return t?(r=_slicedToArray(t.geometry.coordinates,2),a=r[0],l=r[1],i=t.properties.countrycode,s=t.properties.seriesid,e.filter(function(e){var t,r,n;return e.properties.eventname!==o.eventName&&e.properties.countrycode===i&&e.properties.seriesid===s&&(t=(e=_slicedToArray(e.geometry.coordinates,2))[0],e=e[1],r=Math.abs(e-l),n=Math.abs(t-a),!(.5<r||.5<n))&&A(l,a,e,t)<=c}).map(function(e){var t=_slicedToArray(e.geometry.coordinates,2),r=t[0],t=A(l,a,t[1],r);return _objectSpread(_objectSpread({},e),{},{distance:t})}).sort(function(e,t){return e.distance-t.distance})):[]}(_(),S.allParkruns)).length?((t=N(t)).className="parkrun-comparison-selector-controls",C.appendChild(t)):((t=document.createElement("div")).style.padding="10px",t.style.color=w.subtleTextColor,t.style.textAlign="center",t.style.fontSize="13px",e=_(),t.textContent="No nearby parkruns found for comparison (within 50km of ".concat(e.eventName,")"),C.appendChild(t),console.log("Current event:",e.eventName,"Total parkruns loaded:",S.allParkruns.length)),0<S.comparisonEvents.length&&((l=document.createElement("div")).id="selectedEventsDisplay",l.style.display="flex",l.style.gap="8px",l.style.flexWrap="wrap",l.style.marginTop="10px",k(),t={container:l,updateDisplay:k},C.appendChild(t.container)),e=x,(t=document.createElement("div")).id="eventTabs",t.style.marginTop="15px",(s=document.createElement("div")).style.display="flex",s.style.gap="5px",s.style.borderBottom="2px solid ".concat(w.gridColor),s.style.marginBottom="15px",(c=document.createElement("div")).id="tabContents",e.forEach(function(e,r){var t=document.createElement("button");t.textContent=e.title||e.eventName,t.style.padding="10px 20px",t.style.backgroundColor=0===r?E[r%E.length]:"#3a3250",t.style.color=0===r?"#2b223d":w.textColor,t.style.border="none",t.style.borderRadius="6px 6px 0 0",t.style.cursor="pointer",t.style.fontWeight="bold",t.dataset.index=r,t.addEventListener("click",function(){s.querySelectorAll("button").forEach(function(e,t){e.style.backgroundColor=t===r?E[t%E.length]:"#3a3250",e.style.color=t===r?"#2b223d":w.textColor}),c.querySelectorAll(".tab-content").forEach(function(e,t){e.style.display=t===r?"block":"none"})}),s.appendChild(t)}),t.appendChild(s),t.appendChild(c),i=(t={tabsContainer:t,tabContents:c}).tabContents,C.appendChild(t.tabsContainer),x.forEach(function(e,t){e=j(e,t);e&&i.appendChild(e)}),1<x.length&&(y=(t=x).length<2?null:((x=document.createElement("div")).id="comparisonSection",x.style.marginTop="30px",x.style.padding="15px",x.style.backgroundColor=w.backgroundColor,x.style.borderRadius="8px",(u=document.createElement("h3")).textContent="Comparison Charts",u.style.textAlign="center",u.style.color=w.barColor,u.style.marginBottom="20px",x.appendChild(u),u=t.map(function(e){return{event:e,yearly:F(e)}}),d=new Set,u.forEach(function(e){e.yearly.forEach(function(e){return d.add(e.year)})}),t=Array.from(d).sort(function(e,t){return e-t}),(y=document.createElement("div")).style.display="grid",y.style.gridTemplateColumns="1fr 1fr",y.style.gap="20px",g=document.createElement("canvas"),y.appendChild(O(g)),b=document.createElement("canvas"),y.appendChild(O(b)),v=document.createElement("canvas"),y.appendChild(O(v)),p=document.createElement("canvas"),y.appendChild(O(p)),x.appendChild(y),(y=document.createElement("div")).style.display="flex",y.style.justifyContent="center",y.style.marginTop="20px",y.style.gap="10px",y.style.flexWrap="wrap",(m=document.createElement("button")).textContent="π Export HTML",m.style.padding="8px 16px",m.style.backgroundColor=w.barColor,m.style.color="#1c1b2a",m.style.border="none",m.style.borderRadius="4px",m.style.cursor="pointer",m.style.fontWeight="bold",m.style.fontSize="14px",(h=document.createElement("button")).textContent="π€ Share Report",h.style.padding="8px 16px",h.style.backgroundColor=w.lineColor,h.style.color="#2b223d",h.style.border="none",h.style.borderRadius="4px",h.style.cursor="pointer",h.style.fontWeight="bold",h.style.fontSize="14px",f=function(){var t=_(),e=null==(e=S.allParkruns)?void 0:e.find(function(e){return e.properties.eventname===t.eventName}),e=(null==e||null==(e=e.properties)?void 0:e.EventShortName)||t.eventName,r=new Date,n=r.toISOString().split("T")[0];return{eventShortName:e,generatedAt:r.toLocaleString(),generatedAtISO:n}},m.addEventListener("click",_asyncToGenerator(_regenerator().m(function e(){var t,r,n,o,a,l,i;return _regenerator().w(function(e){for(;;)switch(e.p=e.n){case 0:if(t=m.textContent,r=m.style.display,m.textContent="Exporting...",m.disabled=!0,m.style.display="none",e.p=1,n=document.querySelector(".parkrun-annual-summary")){e.n=2;break}throw new Error("Report container not found");case 2:return o=f(),e.n=3,T(n,o);case 3:o=e.v,l=o.blob,i=o.filename,a=URL.createObjectURL(l),(l=document.createElement("a")).href=a,l.download=i,l.click(),setTimeout(function(){return URL.revokeObjectURL(a)},1e3),console.log("Annual summary HTML export complete"),e.n=5;break;case 4:e.p=4,i=e.v,console.error("Annual summary export failed:",i),alert("Error exporting HTML: "+i.message);case 5:return e.p=5,m.disabled=!1,m.textContent=t,m.style.display=r,e.f(5);case 6:return e.a(2)}},e,null,[[1,4,5,6]])}))),h.addEventListener("click",_asyncToGenerator(_regenerator().m(function e(){var t,r,n,o,a,l,i,s,c;return _regenerator().w(function(e){for(;;)switch(e.p=e.n){case 0:if(t=h.textContent,r=h.style.display,h.textContent="Sharing...",h.disabled=!0,h.style.display="none",e.p=1,n=document.querySelector(".parkrun-annual-summary")){e.n=2;break}throw new Error("Report container not found");case 2:return o=f(),e.n=3,T(n,o);case 3:if(l=e.v,a=l.blob,l=l.filename,s=new File([a],l,{type:"text/html"}),navigator.canShare&&navigator.canShare({files:[s]}))return e.n=4,navigator.share({title:"parkrun Annual Summary - ".concat(o.eventShortName),text:"Annual participation summary report",files:[s]});e.n=5;break;case 4:console.log("Annual summary shared via Web Share API"),e.n=6;break;case 5:i=URL.createObjectURL(a),(s=document.createElement("a")).href=i,s.download=l,s.click(),setTimeout(function(){return URL.revokeObjectURL(i)},1e3),alert("Sharing is not supported in this browser, so the HTML report was downloaded instead.");case 6:e.n=8;break;case 7:e.p=7,c=e.v,console.error("Annual summary share failed:",c),alert("Error sharing report: "+c.message);case 8:return e.p=8,h.disabled=!1,h.textContent=t,h.style.display=r,e.f(8);case 9:return e.a(2)}},e,null,[[1,7,8,9]])}))),y.appendChild(m),y.appendChild(h),x.appendChild(y),"undefined"!=typeof Chart&&(V(g,"Annual Totals - Finishers",t,u,function(e){return e.totalFinishers},"Finishers"),V(b,"Annual Totals - Volunteers",t,u,function(e){return e.totalVolunteers},"Volunteers"),V(v,"YoY Growth - Finishers (%)",t,u,function(e){return e.finishersGrowth},"Growth (%)",!0),V(p,"YoY Growth - Volunteers (%)",t,u,function(e){return e.volunteersGrowth},"Growth (%)",!0)),x))&&C.appendChild(y),(g=document.getElementById("eventHistoryChart"))&&g.parentElement?g.parentElement.parentNode.insertBefore(C,g.parentElement.nextSibling):(b="h1",v=C,(b=document.querySelector(b))&&b.parentNode&&(b.nextSibling?b.parentNode.insertBefore(v,b.nextSibling):b.parentNode.appendChild(v))))}function t(){return(t=_asyncToGenerator(_regenerator().m(function e(){var t,r;return _regenerator().w(function(e){for(;;)switch(e.n){case 0:if(t=document.querySelector(".Results-table"),r=window.location.href,r=r.includes("/eventhistory/"),t&&r){e.n=1;break}return e.a(2);case 1:return e.n=2,function(){return n.apply(this,arguments)}();case 2:S.allParkruns=e.v,document.getElementById("annualSummaryTable")||document.getElementById("eventTabs")?console.log("Annual summary already exists, skipping render"):G();case 3:return e.a(2)}},e)}))).apply(this,arguments)}!function(){t.apply(this,arguments)}()})();